BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

env.class.php 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * ENV
  5. *
  6. * The PHP singleton is considered bad design for nebulous reasons,
  7. * but for securely loading a site config it does exactly what we need:
  8. *
  9. * - Ensure that only one instance of itself can ever exist
  10. * - Load the instance everywhere we need to do $ENV->VALUE
  11. * - No memory penalty because of multiple $ENV instances
  12. * - Static values in classes/config.php are immutable
  13. * - Site configs don't exist in the constants table
  14. * - Separate public and private config values
  15. *
  16. * @see https://stackoverflow.com/a/3724689
  17. * @see https://phpenthusiast.com/blog/the-singleton-design-pattern-in-php
  18. */
  19. class ENV
  20. {
  21. # Disinstantiates itself
  22. private static $ENV = null;
  23. # Config options receptacles
  24. private static $Priv = []; # Passwords, app keys, database, etc.
  25. private static $Pub = []; # Site meta, options, resources, etc.
  26. /**
  27. * __functions()
  28. */
  29. # Prevents outside construction
  30. private function __construct()
  31. {
  32. # Would be expensive, e.g.,
  33. # $ENV = new ENV();
  34. return;
  35. }
  36. # Prevents multiple instances
  37. public function __clone()
  38. {
  39. return trigger_error(
  40. 'clone() not allowed',
  41. E_USER_ERROR
  42. );
  43. }
  44. # $this->key returns public->key
  45. public function __get($key)
  46. {
  47. return isset(self::$Pub[$key])
  48. ? self::$Pub[$key]
  49. : false;
  50. }
  51. # isset()
  52. public function __isset($key)
  53. {
  54. return isset(self::$Pub[$key]);
  55. }
  56. /**
  57. * Gets n' Sets
  58. */
  59. # Calls its self's creation or returns itself
  60. public static function go()
  61. {
  62. return (self::$ENV === null)
  63. ? self::$ENV = new ENV()
  64. : self::$ENV;
  65. }
  66. # get
  67. public static function getPriv($key)
  68. {
  69. return isset(self::$Priv[$key])
  70. ? self::$Priv[$key]
  71. : false;
  72. }
  73. public static function getPub($key)
  74. {
  75. return isset(self::$Pub[$key])
  76. ? self::$Pub[$key]
  77. : false;
  78. }
  79. # set
  80. public static function setPriv($key, $value)
  81. {
  82. return self::$Priv[$key] = $value;
  83. }
  84. public static function setPub($key, $value)
  85. {
  86. return self::$Pub[$key] = $value;
  87. }
  88. /**
  89. * toArray
  90. * @see https://ben.lobaugh.net/blog/567/php-recursively-convert-an-object-to-an-array
  91. */
  92. public function toArray($obj)
  93. {
  94. if (is_object($obj)) {
  95. $obj = (array) $obj;
  96. }
  97. if (is_array($obj)) {
  98. $new = array();
  99. foreach ($obj as $key => $value) {
  100. $new[$key] = $this->toArray($value);
  101. }
  102. } else {
  103. $new = $obj;
  104. }
  105. return $new;
  106. }
  107. /**
  108. * fromJson
  109. *
  110. * @param string $JSON Valid JavaScript object string
  111. * @return RecursiveArrayObject Not stdClass as in json_decode()
  112. */
  113. public function fromJson($str)
  114. {
  115. if (!is_string($str) || is_empty($str)) {
  116. error('$ENV->fromJson() expects a string.');
  117. }
  118. # Decode to array and construct RAO
  119. return $RAO = new RecursiveArrayObject(
  120. json_decode($str, true)
  121. );
  122. }
  123. /**
  124. * dedupe
  125. *
  126. * Takes a collection (usually an array) of various jumbled $ENV slices.
  127. * Returns a once-deduplicated RecursiveArrayObject with original nesting intact.
  128. * Simple and handy if you need to populate a form with arbitrary collections of metadata.
  129. */
  130. public function dedupe($obj)
  131. {
  132. if (is_object($obj)) {
  133. $obj = (array) $obj;
  134. }
  135. return $RAO = new RecursiveArrayObject(
  136. array_unique($this->toArray($obj))
  137. );
  138. }
  139. /**
  140. * map
  141. *
  142. * Simple array_map() object wrapper.
  143. * Maps a callback (or default) to an object.
  144. *
  145. * Example output:
  146. * $Hashes = $ENV->map('md5', $ENV->CATS->SEQ);
  147. *
  148. * var_dump($Hashes);
  149. * object(RecursiveArrayObject)#324 (1) {
  150. * ["storage":"ArrayObject":private]=>
  151. * array(6) {
  152. * ["ID"]=>
  153. * string(32) "28c8edde3d61a0411511d3b1866f0636"
  154. * ["Name"]=>
  155. * string(32) "fe83ccb5dc96dbc0658b3c4672c7d5fe"
  156. * ["Icon"]=>
  157. * string(32) "52963afccc006d2bce3c890ad9e8f73a"
  158. * ["Platforms"]=>
  159. * string(32) "d41d8cd98f00b204e9800998ecf8427e"
  160. * ["Formats"]=>
  161. * string(32) "d41d8cd98f00b204e9800998ecf8427e"
  162. * ["Description"]=>
  163. * string(32) "ca6628e8c13411c800d1d9d0eaccd849"
  164. * }
  165. * }
  166. *
  167. * var_dump($Hashes->Icon);
  168. * string(32) "52963afccc006d2bce3c890ad9e8f73a"
  169. *
  170. * @param string $fn Callback function
  171. * @param object $obj Object to operate on
  172. * @return object $RAO Mapped RecursiveArrayObject
  173. */
  174. public function map($fn = '', $obj = null)
  175. {
  176. # Set a default function if desired
  177. if (empty($fn) && !is_object($fn)) {
  178. $fn = 'array_filter';
  179. }
  180. # Quick sanity check
  181. if ($fn === 'array_map') {
  182. error("map() can't invoke the function it wraps.");
  183. }
  184. /**
  185. * $fn not a closure
  186. *
  187. * var_dump(
  188. * gettype(
  189. * (function() { return; })
  190. * ));
  191. * string(6) "object"
  192. */
  193. if (is_string($fn) && !is_object($fn)) {
  194. $fn = trim(strtok($fn, ' '));
  195. }
  196. # Map the sanitized function name
  197. # to a mapped array conversion
  198. return $RAO = new RecursiveArrayObject(
  199. array_map(
  200. $fn,
  201. array_map(
  202. $fn,
  203. $this->toArray($obj)
  204. )
  205. )
  206. );
  207. }
  208. }
  209. /**
  210. * @author: etconsilium@github
  211. * @license: BSDLv2
  212. * @see https://github.com/etconsilium/php-recursive-array-object
  213. */
  214. class RecursiveArrayObject extends \ArrayObject
  215. {
  216. /**
  217. * __construct
  218. */
  219. public function __construct($input = null, $flags = self::ARRAY_AS_PROPS, $iterator_class = "ArrayIterator")
  220. {
  221. foreach ($input as $key => $value) {
  222. $this->__set($key, $value);
  223. }
  224. return $this;
  225. }
  226. /**
  227. * __set
  228. */
  229. public function __set($name, $value)
  230. {
  231. if (is_array($value) || is_object($value)) {
  232. $this->offsetSet($name, (new self($value)));
  233. } else {
  234. $this->offsetSet($name, $value);
  235. }
  236. }
  237. /**
  238. * __get
  239. */
  240. public function __get($name)
  241. {
  242. if ($this->offsetExists($name)) {
  243. return $this->offsetGet($name);
  244. } elseif (array_key_exists($name, $this)) {
  245. return $this[$name];
  246. } else {
  247. throw new \InvalidArgumentException(sprintf('$this have not prop `%s`', $name));
  248. }
  249. }
  250. /**
  251. * __isset
  252. */
  253. public function __isset($name)
  254. {
  255. return array_key_exists($name, $this);
  256. }
  257. /**
  258. * __unset
  259. */
  260. public function __unset($name)
  261. {
  262. unset($this[$name]);
  263. }
  264. }