annotations.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. /**
  3. * Elgg annotations
  4. * Functions to manage object annotations.
  5. *
  6. * @package Elgg
  7. * @subpackage Core
  8. */
  9. /**
  10. * Convert a database row to a new \ElggAnnotation
  11. *
  12. * @param \stdClass $row Db row result object
  13. *
  14. * @return \ElggAnnotation
  15. * @access private
  16. */
  17. function row_to_elggannotation($row) {
  18. if (!($row instanceof \stdClass)) {
  19. // @todo should throw in this case?
  20. return $row;
  21. }
  22. return new \ElggAnnotation($row);
  23. }
  24. /**
  25. * Get a specific annotation by its id.
  26. * If you want multiple annotation objects, use
  27. * {@link elgg_get_annotations()}.
  28. *
  29. * @param int $id The id of the annotation object being retrieved.
  30. *
  31. * @return \ElggAnnotation|false
  32. */
  33. function elgg_get_annotation_from_id($id) {
  34. return _elgg_services()->annotations->get($id);
  35. }
  36. /**
  37. * Deletes an annotation using its ID.
  38. *
  39. * @param int $id The annotation ID to delete.
  40. * @return bool
  41. */
  42. function elgg_delete_annotation_by_id($id) {
  43. return _elgg_services()->annotations->delete($id);
  44. }
  45. /**
  46. * Create a new annotation.
  47. *
  48. * @param int $entity_guid GUID of entity to be annotated
  49. * @param string $name Name of annotation
  50. * @param string $value Value of annotation
  51. * @param string $value_type Type of value (default is auto detection)
  52. * @param int $owner_guid Owner of annotation (default is logged in user)
  53. * @param int $access_id Access level of annotation
  54. *
  55. * @return int|bool id on success or false on failure
  56. */
  57. function create_annotation($entity_guid, $name, $value, $value_type = '',
  58. $owner_guid = 0, $access_id = ACCESS_PRIVATE) {
  59. return _elgg_services()->annotations->create(
  60. $entity_guid, $name, $value, $value_type, $owner_guid, $access_id);
  61. }
  62. /**
  63. * Update an annotation.
  64. *
  65. * @param int $annotation_id Annotation ID
  66. * @param string $name Name of annotation
  67. * @param string $value Value of annotation
  68. * @param string $value_type Type of value
  69. * @param int $owner_guid Owner of annotation
  70. * @param int $access_id Access level of annotation
  71. *
  72. * @return bool
  73. */
  74. function update_annotation($annotation_id, $name, $value, $value_type, $owner_guid, $access_id) {
  75. return _elgg_services()->annotations->update($annotation_id, $name, $value, $value_type, $owner_guid, $access_id);
  76. }
  77. /**
  78. * Returns annotations. Accepts all elgg_get_entities() options for entity
  79. * restraints.
  80. *
  81. * @see elgg_get_entities
  82. *
  83. * @param array $options Array in format:
  84. *
  85. * annotation_names => null|ARR Annotation names
  86. * annotation_values => null|ARR Annotation values
  87. * annotation_ids => null|ARR annotation ids
  88. * annotation_case_sensitive => BOOL Overall Case sensitive
  89. * annotation_owner_guids => null|ARR guids for annotation owners
  90. * annotation_created_time_lower => INT Lower limit for created time.
  91. * annotation_created_time_upper => INT Upper limit for created time.
  92. * annotation_calculation => STR Perform the MySQL function on the annotation values returned.
  93. * Do not confuse this "annotation_calculation" option with the
  94. * "calculation" option to elgg_get_entities_from_annotation_calculation().
  95. * The "annotation_calculation" option causes this function to
  96. * return the result of performing a mathematical calculation on
  97. * all annotations that match the query instead of \ElggAnnotation
  98. * objects.
  99. * See the docs for elgg_get_entities_from_annotation_calculation()
  100. * for the proper use of the "calculation" option.
  101. *
  102. *
  103. * @return \ElggAnnotation[]|mixed
  104. * @since 1.8.0
  105. */
  106. function elgg_get_annotations(array $options = array()) {
  107. return _elgg_services()->annotations->find($options);
  108. }
  109. /**
  110. * Returns a rendered list of annotations with pagination.
  111. *
  112. * @param array $options Annotation getter and display options.
  113. * {@link elgg_get_annotations()} and {@link elgg_list_entities()}.
  114. *
  115. * @return string The list of entities
  116. * @since 1.8.0
  117. */
  118. function elgg_list_annotations($options) {
  119. $defaults = array(
  120. 'limit' => 25,
  121. 'offset' => (int) max(get_input('annoff', 0), 0),
  122. 'no_results' => '',
  123. );
  124. $options = array_merge($defaults, $options);
  125. return elgg_list_entities($options, 'elgg_get_annotations', 'elgg_view_annotation_list');
  126. }
  127. /**
  128. * Deletes annotations based on $options.
  129. *
  130. * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
  131. * This requires at least one constraint: annotation_owner_guid(s),
  132. * annotation_name(s), annotation_value(s), or guid(s) must be set.
  133. *
  134. * @param array $options An options array. {@link elgg_get_annotations()}
  135. * @return bool|null true on success, false on failure, null if no annotations to delete.
  136. * @since 1.8.0
  137. */
  138. function elgg_delete_annotations(array $options) {
  139. return _elgg_services()->annotations->deleteAll($options);
  140. }
  141. /**
  142. * Disables annotations based on $options.
  143. *
  144. * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
  145. *
  146. * @param array $options An options array. {@link elgg_get_annotations()}
  147. * @return bool|null true on success, false on failure, null if no annotations disabled.
  148. * @since 1.8.0
  149. */
  150. function elgg_disable_annotations(array $options) {
  151. return _elgg_services()->annotations->disableAll($options);
  152. }
  153. /**
  154. * Enables annotations based on $options.
  155. *
  156. * @warning Unlike elgg_get_annotations() this will not accept an empty options array!
  157. *
  158. * @warning In order to enable annotations, you must first use
  159. * {@link access_show_hidden_entities()}.
  160. *
  161. * @param array $options An options array. {@link elgg_get_annotations()}
  162. * @return bool|null true on success, false on failure, null if no metadata enabled.
  163. * @since 1.8.0
  164. */
  165. function elgg_enable_annotations(array $options) {
  166. return _elgg_services()->annotations->enableAll($options);
  167. }
  168. /**
  169. * Returns entities based upon annotations. Also accepts all options available
  170. * to elgg_get_entities() and elgg_get_entities_from_metadata().
  171. *
  172. * Entity creation time is selected as maxtime. To sort based upon
  173. * this, pass 'order_by' => 'maxtime asc' || 'maxtime desc'
  174. *
  175. * @see elgg_get_entities
  176. * @see elgg_get_entities_from_metadata
  177. *
  178. * @param array $options Array in format:
  179. *
  180. * annotation_names => null|ARR annotations names
  181. *
  182. * annotation_values => null|ARR annotations values
  183. *
  184. * annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
  185. * 'operator' => '=', 'case_sensitive' => true) entries.
  186. * Currently if multiple values are sent via an array (value => array('value1', 'value2')
  187. * the pair's operator will be forced to "IN".
  188. *
  189. * annotation_name_value_pairs_operator => null|STR The operator to use for combining
  190. * (name = value) OPERATOR (name = value); default AND
  191. *
  192. * annotation_case_sensitive => BOOL Overall Case sensitive
  193. *
  194. * order_by_annotation => null|ARR (array('name' => 'annotation_text1', 'direction' => ASC|DESC,
  195. * 'as' => text|integer),
  196. *
  197. * Also supports array('name' => 'annotation_text1')
  198. *
  199. * annotation_owner_guids => null|ARR guids for annotaiton owners
  200. *
  201. * @return mixed If count, int. If not count, array. false on errors.
  202. * @since 1.7.0
  203. */
  204. function elgg_get_entities_from_annotations(array $options = array()) {
  205. return _elgg_services()->annotations->getEntities($options);
  206. }
  207. /**
  208. * Returns a viewable list of entities from annotations.
  209. *
  210. * @param array $options Options array
  211. *
  212. * @see elgg_get_entities_from_annotations()
  213. * @see elgg_list_entities()
  214. *
  215. * @return string
  216. */
  217. function elgg_list_entities_from_annotations($options = array()) {
  218. return elgg_list_entities($options, 'elgg_get_entities_from_annotations');
  219. }
  220. /**
  221. * Get entities ordered by a mathematical calculation on annotation values
  222. *
  223. * @tip Note that this function uses { @link elgg_get_annotations() } to return a list of entities ordered by a mathematical
  224. * calculation on annotation values, and { @link elgg_get_entities_from_annotations() } to return a count of entities
  225. * if $options['count'] is set to a truthy value
  226. *
  227. * @param array $options An options array:
  228. * 'calculation' => The calculation to use. Must be a valid MySQL function.
  229. * Defaults to sum. Result selected as 'annotation_calculation'.
  230. * Don't confuse this "calculation" option with the
  231. * "annotation_calculation" option to elgg_get_annotations().
  232. * This "calculation" option is applied to each entity's set of
  233. * annotations and is selected as annotation_calculation for that row.
  234. * See the docs for elgg_get_annotations() for proper use of the
  235. * "annotation_calculation" option.
  236. * 'order_by' => The order for the sorting. Defaults to 'annotation_calculation desc'.
  237. * 'annotation_names' => The names of annotations on the entity.
  238. * 'annotation_values' => The values of annotations on the entity.
  239. *
  240. * 'metadata_names' => The name of metadata on the entity.
  241. * 'metadata_values' => The value of metadata on the entitiy.
  242. * 'callback' => Callback function to pass each row through.
  243. * @tip This function is different from other ege* functions,
  244. * as it uses a metastring-based getter function { @link elgg_get_annotations() },
  245. * therefore the callback function should be a derivative of { @link entity_row_to_elggstar() }
  246. * and not of { @link row_to_annotation() }
  247. *
  248. * @return \ElggEntity[]|int An array or a count of entities
  249. * @see elgg_get_annotations()
  250. * @see elgg_get_entities_from_annotations()
  251. */
  252. function elgg_get_entities_from_annotation_calculation($options) {
  253. return _elgg_services()->annotations->getEntitiesFromCalculation($options);
  254. }
  255. /**
  256. * List entities from an annotation calculation.
  257. *
  258. * @see elgg_get_entities_from_annotation_calculation()
  259. *
  260. * @param array $options An options array.
  261. *
  262. * @return string
  263. */
  264. function elgg_list_entities_from_annotation_calculation($options) {
  265. $defaults = array(
  266. 'calculation' => 'sum',
  267. 'order_by' => 'annotation_calculation desc'
  268. );
  269. $options = array_merge($defaults, $options);
  270. return elgg_list_entities($options, 'elgg_get_entities_from_annotation_calculation');
  271. }
  272. /**
  273. * Check to see if a user has already created an annotation on an object
  274. *
  275. * @param int $entity_guid Entity guid
  276. * @param string $annotation_type Type of annotation
  277. * @param int $owner_guid Defaults to logged in user.
  278. *
  279. * @return bool
  280. * @since 1.8.0
  281. */
  282. function elgg_annotation_exists($entity_guid, $annotation_type, $owner_guid = null) {
  283. return _elgg_services()->annotations->exists($entity_guid, $annotation_type, $owner_guid);
  284. }
  285. /**
  286. * Set the URL for a comment when called from a plugin hook
  287. *
  288. * @param string $hook Hook name
  289. * @param string $type Hook type
  290. * @param string $url URL string
  291. * @param array $params Parameters of the hook
  292. * @return string
  293. * @access private
  294. */
  295. function _elgg_set_comment_url($hook, $type, $url, $params) {
  296. $annotation = $params['extender'];
  297. /* @var \ElggExtender $annotation */
  298. if ($annotation->getSubtype() == 'generic_comment') {
  299. $entity = $annotation->getEntity();
  300. if ($entity) {
  301. return $entity->getURL() . '#item-annotation-' . $annotation->id;
  302. }
  303. }
  304. }
  305. /**
  306. * Register annotation unit tests
  307. *
  308. * @param string $hook
  309. * @param string $type
  310. * @param array $tests
  311. * @return array
  312. * @access private
  313. */
  314. function _elgg_annotations_test($hook, $type, $tests) {
  315. global $CONFIG;
  316. $tests[] = $CONFIG->path . 'engine/tests/ElggCoreAnnotationAPITest.php';
  317. $tests[] = $CONFIG->path . 'engine/tests/ElggAnnotationTest.php';
  318. return $tests;
  319. }
  320. /**
  321. * Initialize the annotation library
  322. * @access private
  323. */
  324. function _elgg_annotations_init() {
  325. elgg_register_plugin_hook_handler('extender:url', 'annotation', '_elgg_set_comment_url');
  326. elgg_register_plugin_hook_handler('unit_test', 'system', '_elgg_annotations_test');
  327. }
  328. return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
  329. $events->registerHandler('init', 'system', '_elgg_annotations_init');
  330. };