PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/engine/lib/private_settings.php

https://github.com/fragilbert/Elgg
PHP | 414 lines | 208 code | 63 blank | 143 comment | 40 complexity | ce2493145b95329b13a0aa8678d115ef MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, LGPL-2.1, GPL-2.0
  1. <?php
  2. /**
  3. * Private settings for entities
  4. * Private settings provide metadata like storage of settings for plugins
  5. * and users.
  6. *
  7. * @package Elgg.Core
  8. * @subpackage PrivateSettings
  9. */
  10. /**
  11. * Returns entities based upon private settings. Also accepts all
  12. * options available to elgg_get_entities(). Supports
  13. * the singular option shortcut.
  14. *
  15. * @see elgg_get_entities
  16. *
  17. * @param array $options Array in format:
  18. *
  19. * private_setting_names => NULL|ARR private setting names
  20. *
  21. * private_setting_values => NULL|ARR metadata values
  22. *
  23. * private_setting_name_value_pairs => NULL|ARR (
  24. * name => 'name',
  25. * value => 'value',
  26. * 'operand' => '=',
  27. * )
  28. * Currently if multiple values are sent via
  29. * an array (value => array('value1', 'value2')
  30. * the pair's operand will be forced to "IN".
  31. *
  32. * private_setting_name_value_pairs_operator => NULL|STR The operator to use for combining
  33. * (name = value) OPERATOR (name = value); default AND
  34. *
  35. * private_setting_name_prefix => STR A prefix to apply to all private settings. Used to
  36. * namespace plugin user settings or by plugins to namespace
  37. * their own settings.
  38. *
  39. *
  40. * @return mixed int If count, int. If not count, array. false on errors.
  41. * @since 1.8.0
  42. */
  43. function elgg_get_entities_from_private_settings(array $options = array()) {
  44. $defaults = array(
  45. 'private_setting_names' => ELGG_ENTITIES_ANY_VALUE,
  46. 'private_setting_values' => ELGG_ENTITIES_ANY_VALUE,
  47. 'private_setting_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE,
  48. 'private_setting_name_value_pairs_operator' => 'AND',
  49. 'private_setting_name_prefix' => '',
  50. );
  51. $options = array_merge($defaults, $options);
  52. $singulars = array('private_setting_name', 'private_setting_value',
  53. 'private_setting_name_value_pair');
  54. $options = elgg_normalise_plural_options_array($options, $singulars);
  55. $clauses = elgg_get_entity_private_settings_where_sql('e', $options['private_setting_names'],
  56. $options['private_setting_values'], $options['private_setting_name_value_pairs'],
  57. $options['private_setting_name_value_pairs_operator'], $options['private_setting_name_prefix']);
  58. if ($clauses) {
  59. // merge wheres to pass to get_entities()
  60. if (isset($options['wheres']) && !is_array($options['wheres'])) {
  61. $options['wheres'] = array($options['wheres']);
  62. } elseif (!isset($options['wheres'])) {
  63. $options['wheres'] = array();
  64. }
  65. $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
  66. // merge joins to pass to get_entities()
  67. if (isset($options['joins']) && !is_array($options['joins'])) {
  68. $options['joins'] = array($options['joins']);
  69. } elseif (!isset($options['joins'])) {
  70. $options['joins'] = array();
  71. }
  72. $options['joins'] = array_merge($options['joins'], $clauses['joins']);
  73. }
  74. return elgg_get_entities($options);
  75. }
  76. /**
  77. * Returns private setting name and value SQL where/join clauses for entities.
  78. *
  79. * @param string $table Entities table name
  80. * @param array|null $names Array of names
  81. * @param array|null $values Array of values
  82. * @param array|null $pairs Array of names / values / operands
  83. * @param string $pair_operator Operator for joining pairs where clauses
  84. * @param string $name_prefix A string to prefix all names with
  85. * @return array
  86. * @since 1.8.0
  87. * @access private
  88. */
  89. function elgg_get_entity_private_settings_where_sql($table, $names = NULL, $values = NULL,
  90. $pairs = NULL, $pair_operator = 'AND', $name_prefix = '') {
  91. global $CONFIG;
  92. // @todo short circuit test
  93. $return = array (
  94. 'joins' => array (),
  95. 'wheres' => array(),
  96. );
  97. $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps on
  98. {$table}.guid = ps.entity_guid";
  99. $wheres = array();
  100. // get names wheres
  101. $names_where = '';
  102. if ($names !== NULL) {
  103. if (!is_array($names)) {
  104. $names = array($names);
  105. }
  106. $sanitised_names = array();
  107. foreach ($names as $name) {
  108. $name = $name_prefix . $name;
  109. $sanitised_names[] = '\'' . sanitise_string($name) . '\'';
  110. }
  111. $names_str = implode(',', $sanitised_names);
  112. if ($names_str) {
  113. $names_where = "(ps.name IN ($names_str))";
  114. }
  115. }
  116. // get values wheres
  117. $values_where = '';
  118. if ($values !== NULL) {
  119. if (!is_array($values)) {
  120. $values = array($values);
  121. }
  122. $sanitised_values = array();
  123. foreach ($values as $value) {
  124. // normalize to 0
  125. if (!$value) {
  126. $value = 0;
  127. }
  128. $sanitised_values[] = '\'' . sanitise_string($value) . '\'';
  129. }
  130. $values_str = implode(',', $sanitised_values);
  131. if ($values_str) {
  132. $values_where = "(ps.value IN ($values_str))";
  133. }
  134. }
  135. if ($names_where && $values_where) {
  136. $wheres[] = "($names_where AND $values_where)";
  137. } elseif ($names_where) {
  138. $wheres[] = "($names_where)";
  139. } elseif ($values_where) {
  140. $wheres[] = "($values_where)";
  141. }
  142. // add pairs which must be in arrays.
  143. if (is_array($pairs)) {
  144. // join counter for incremental joins in pairs
  145. $i = 1;
  146. // check if this is an array of pairs or just a single pair.
  147. if (isset($pairs['name']) || isset($pairs['value'])) {
  148. $pairs = array($pairs);
  149. }
  150. $pair_wheres = array();
  151. foreach ($pairs as $index => $pair) {
  152. // @todo move this elsewhere?
  153. // support shortcut 'n' => 'v' method.
  154. if (!is_array($pair)) {
  155. $pair = array(
  156. 'name' => $index,
  157. 'value' => $pair
  158. );
  159. }
  160. // must have at least a name and value
  161. if (!isset($pair['name']) || !isset($pair['value'])) {
  162. // @todo should probably return false.
  163. continue;
  164. }
  165. if (isset($pair['operand'])) {
  166. $operand = sanitise_string($pair['operand']);
  167. } else {
  168. $operand = ' = ';
  169. }
  170. // for comparing
  171. $trimmed_operand = trim(strtolower($operand));
  172. // if the value is an int, don't quote it because str '15' < str '5'
  173. // if the operand is IN don't quote it because quoting should be done already.
  174. if (is_numeric($pair['value'])) {
  175. $value = sanitise_string($pair['value']);
  176. } else if (is_array($pair['value'])) {
  177. $values_array = array();
  178. foreach ($pair['value'] as $pair_value) {
  179. if (is_numeric($pair_value)) {
  180. $values_array[] = sanitise_string($pair_value);
  181. } else {
  182. $values_array[] = "'" . sanitise_string($pair_value) . "'";
  183. }
  184. }
  185. if ($values_array) {
  186. $value = '(' . implode(', ', $values_array) . ')';
  187. }
  188. // @todo allow support for non IN operands with array of values.
  189. // will have to do more silly joins.
  190. $operand = 'IN';
  191. } else if ($trimmed_operand == 'in') {
  192. $value = "({$pair['value']})";
  193. } else {
  194. $value = "'" . sanitise_string($pair['value']) . "'";
  195. }
  196. $name = sanitise_string($name_prefix . $pair['name']);
  197. // @todo The multiple joins are only needed when the operator is AND
  198. $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps{$i}
  199. on {$table}.guid = ps{$i}.entity_guid";
  200. $pair_wheres[] = "(ps{$i}.name = '$name' AND ps{$i}.value
  201. $operand $value)";
  202. $i++;
  203. }
  204. $where = implode(" $pair_operator ", $pair_wheres);
  205. if ($where) {
  206. $wheres[] = "($where)";
  207. }
  208. }
  209. $where = implode(' AND ', $wheres);
  210. if ($where) {
  211. $return['wheres'][] = "($where)";
  212. }
  213. return $return;
  214. }
  215. /**
  216. * Gets a private setting for an entity.
  217. *
  218. * Plugin authors can set private data on entities. By default
  219. * private data will not be searched or exported.
  220. *
  221. * @internal Private data is used to store settings for plugins
  222. * and user settings.
  223. *
  224. * @param int $entity_guid The entity GUID
  225. * @param string $name The name of the setting
  226. *
  227. * @return mixed The setting value, or false on failure
  228. * @see set_private_setting()
  229. * @see get_all_private_settings()
  230. * @see remove_private_setting()
  231. * @see remove_all_private_settings()
  232. * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
  233. */
  234. function get_private_setting($entity_guid, $name) {
  235. global $CONFIG;
  236. $entity_guid = (int) $entity_guid;
  237. $name = sanitise_string($name);
  238. $entity = get_entity($entity_guid);
  239. if (!$entity instanceof ElggEntity) {
  240. return false;
  241. }
  242. $query = "SELECT value from {$CONFIG->dbprefix}private_settings
  243. where name = '{$name}' and entity_guid = {$entity_guid}";
  244. $setting = get_data_row($query);
  245. if ($setting) {
  246. return $setting->value;
  247. }
  248. return false;
  249. }
  250. /**
  251. * Return an array of all private settings.
  252. *
  253. * @param int $entity_guid The entity GUID
  254. *
  255. * @return array|false
  256. * @see set_private_setting()
  257. * @see get_private_settings()
  258. * @see remove_private_setting()
  259. * @see remove_all_private_settings()
  260. * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
  261. */
  262. function get_all_private_settings($entity_guid) {
  263. global $CONFIG;
  264. $entity_guid = (int) $entity_guid;
  265. $entity = get_entity($entity_guid);
  266. if (!$entity instanceof ElggEntity) {
  267. return false;
  268. }
  269. $query = "SELECT * from {$CONFIG->dbprefix}private_settings where entity_guid = {$entity_guid}";
  270. $result = get_data($query);
  271. if ($result) {
  272. $return = array();
  273. foreach ($result as $r) {
  274. $return[$r->name] = $r->value;
  275. }
  276. return $return;
  277. }
  278. return false;
  279. }
  280. /**
  281. * Sets a private setting for an entity.
  282. *
  283. * @param int $entity_guid The entity GUID
  284. * @param string $name The name of the setting
  285. * @param string $value The value of the setting
  286. *
  287. * @return bool
  288. * @see get_private_setting()
  289. * @see get_all_private_settings()
  290. * @see remove_private_setting()
  291. * @see remove_all_private_settings()
  292. * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
  293. */
  294. function set_private_setting($entity_guid, $name, $value) {
  295. global $CONFIG;
  296. $entity_guid = (int) $entity_guid;
  297. $name = sanitise_string($name);
  298. $value = sanitise_string($value);
  299. $result = insert_data("INSERT into {$CONFIG->dbprefix}private_settings
  300. (entity_guid, name, value) VALUES
  301. ($entity_guid, '$name', '$value')
  302. ON DUPLICATE KEY UPDATE value='$value'");
  303. return $result !== false;
  304. }
  305. /**
  306. * Deletes a private setting for an entity.
  307. *
  308. * @param int $entity_guid The Entity GUID
  309. * @param string $name The name of the setting
  310. *
  311. * @return bool
  312. * @see get_private_setting()
  313. * @see get_all_private_settings()
  314. * @see set_private_setting()
  315. * @see remove_all_private_settings()
  316. * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
  317. */
  318. function remove_private_setting($entity_guid, $name) {
  319. global $CONFIG;
  320. $entity_guid = (int) $entity_guid;
  321. $entity = get_entity($entity_guid);
  322. if (!$entity instanceof ElggEntity) {
  323. return false;
  324. }
  325. $name = sanitise_string($name);
  326. return delete_data("DELETE from {$CONFIG->dbprefix}private_settings
  327. WHERE name = '{$name}'
  328. AND entity_guid = {$entity_guid}");
  329. }
  330. /**
  331. * Deletes all private settings for an entity.
  332. *
  333. * @param int $entity_guid The Entity GUID
  334. *
  335. * @return bool
  336. * @see get_private_setting()
  337. * @see get_all_private_settings()
  338. * @see set_private_setting()
  339. * @see remove_private_settings()
  340. * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings
  341. */
  342. function remove_all_private_settings($entity_guid) {
  343. global $CONFIG;
  344. $entity_guid = (int) $entity_guid;
  345. $entity = get_entity($entity_guid);
  346. if (!$entity instanceof ElggEntity) {
  347. return false;
  348. }
  349. return delete_data("DELETE from {$CONFIG->dbprefix}private_settings
  350. WHERE entity_guid = {$entity_guid}");
  351. }