gctools-outilsgc /
gcconnex
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Elgg metastrngs |
||
| 4 | * Functions to manage object metastrings. |
||
| 5 | * |
||
| 6 | * @package Elgg.Core |
||
| 7 | * @subpackage DataModel.MetaStrings |
||
| 8 | */ |
||
| 9 | |||
| 10 | /** |
||
| 11 | * Gets the metastring identifier for a value. |
||
| 12 | * |
||
| 13 | * Elgg normalizes the names and values of annotations and metadata. This function |
||
| 14 | * provides the identifier used as the index in the metastrings table. Plugin |
||
| 15 | * developers should only use this if denormalizing names/values for performance |
||
| 16 | * reasons (to avoid multiple joins on the metastrings table). |
||
| 17 | * |
||
| 18 | * @param string $string The value |
||
| 19 | * @param bool $case_sensitive Should the retrieval be case sensitive? |
||
| 20 | * If not, there may be more than one result |
||
| 21 | * |
||
| 22 | * @return int|array metastring id or array of ids |
||
| 23 | * @since 1.9.0 |
||
| 24 | */ |
||
| 25 | function elgg_get_metastring_id($string, $case_sensitive = true) { |
||
| 26 | return _elgg_services()->metastringsTable->getId($string, $case_sensitive); |
||
| 27 | } |
||
| 28 | |||
| 29 | /** |
||
| 30 | * Add a metastring. |
||
| 31 | * |
||
| 32 | * @warning You should not call this directly. Use elgg_get_metastring_id(). |
||
| 33 | * |
||
| 34 | * @param string $string The value to be normalized |
||
| 35 | * @return int The identifier for this string |
||
| 36 | */ |
||
| 37 | function _elgg_add_metastring($string) { |
||
| 38 | return _elgg_services()->metastringsTable->add($string); |
||
| 39 | } |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Returns an array of either \ElggAnnotation or \ElggMetadata objects. |
||
| 43 | * Accepts all elgg_get_entities() options for entity restraints. |
||
| 44 | * |
||
| 45 | * @see elgg_get_entities |
||
| 46 | * |
||
| 47 | * @param array $options Array in format: |
||
| 48 | * |
||
| 49 | * metastring_names => null|ARR metastring names |
||
| 50 | * |
||
| 51 | * metastring_values => null|ARR metastring values |
||
| 52 | * |
||
| 53 | * metastring_ids => null|ARR metastring ids |
||
| 54 | * |
||
| 55 | * metastring_case_sensitive => BOOL Overall Case sensitive |
||
| 56 | * |
||
| 57 | * metastring_owner_guids => null|ARR Guids for metadata owners |
||
| 58 | * |
||
| 59 | * metastring_created_time_lower => INT Lower limit for created time. |
||
| 60 | * |
||
| 61 | * metastring_created_time_upper => INT Upper limit for created time. |
||
| 62 | * |
||
| 63 | * metastring_calculation => STR Perform the MySQL function on the metastring values |
||
| 64 | * returned. |
||
| 65 | * This differs from egef_annotation_calculation in that |
||
| 66 | * it returns only the calculation of all annotation values. |
||
| 67 | * You can sum, avg, count, etc. egef_annotation_calculation() |
||
| 68 | * returns \ElggEntities ordered by a calculation on their |
||
| 69 | * annotation values. |
||
| 70 | * |
||
| 71 | * metastring_type => STR metadata or annotation(s) |
||
| 72 | * |
||
| 73 | * @return \ElggExtender[]|int An array or count of metastring based objects |
||
| 74 | * @access private |
||
| 75 | */ |
||
| 76 | function _elgg_get_metastring_based_objects($options) { |
||
| 77 | $options = _elgg_normalize_metastrings_options($options); |
||
| 78 | |||
| 79 | switch ($options['metastring_type']) { |
||
| 80 | case 'metadata': |
||
| 81 | $type = 'metadata'; |
||
| 82 | $callback = 'row_to_elggmetadata'; |
||
| 83 | break; |
||
| 84 | |||
| 85 | case 'annotations': |
||
| 86 | case 'annotation': |
||
| 87 | $type = 'annotations'; |
||
| 88 | $callback = 'row_to_elggannotation'; |
||
| 89 | break; |
||
| 90 | |||
| 91 | default: |
||
| 92 | return false; |
||
| 93 | } |
||
| 94 | |||
| 95 | $defaults = array( |
||
| 96 | // entities |
||
| 97 | 'types' => ELGG_ENTITIES_ANY_VALUE, |
||
| 98 | 'subtypes' => ELGG_ENTITIES_ANY_VALUE, |
||
| 99 | 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, |
||
| 100 | |||
| 101 | 'guids' => ELGG_ENTITIES_ANY_VALUE, |
||
| 102 | 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, |
||
| 103 | 'container_guids' => ELGG_ENTITIES_ANY_VALUE, |
||
| 104 | 'site_guids' => get_config('site_guid'), |
||
| 105 | |||
| 106 | 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, |
||
| 107 | 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, |
||
| 108 | 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, |
||
| 109 | 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, |
||
| 110 | |||
| 111 | // options are normalized to the plural in case we ever add support for them. |
||
| 112 | 'metastring_names' => ELGG_ENTITIES_ANY_VALUE, |
||
| 113 | 'metastring_values' => ELGG_ENTITIES_ANY_VALUE, |
||
| 114 | //'metastring_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, |
||
| 115 | //'metastring_name_value_pairs_operator' => 'AND', |
||
| 116 | |||
| 117 | 'metastring_case_sensitive' => true, |
||
| 118 | //'order_by_metastring' => array(), |
||
| 119 | 'metastring_calculation' => ELGG_ENTITIES_NO_VALUE, |
||
| 120 | |||
| 121 | 'metastring_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, |
||
| 122 | 'metastring_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, |
||
| 123 | |||
| 124 | 'metastring_owner_guids' => ELGG_ENTITIES_ANY_VALUE, |
||
| 125 | |||
| 126 | 'metastring_ids' => ELGG_ENTITIES_ANY_VALUE, |
||
| 127 | |||
| 128 | // sql |
||
| 129 | 'order_by' => 'n_table.time_created ASC, n_table.id ASC', |
||
| 130 | 'limit' => elgg_get_config('default_limit'), |
||
| 131 | 'offset' => 0, |
||
| 132 | 'count' => false, |
||
| 133 | 'selects' => array(), |
||
| 134 | 'wheres' => array(), |
||
| 135 | 'joins' => array(), |
||
| 136 | |||
| 137 | 'distinct' => true, |
||
| 138 | 'preload_owners' => false, |
||
| 139 | 'callback' => $callback, |
||
| 140 | ); |
||
| 141 | |||
| 142 | // @todo Ignore site_guid right now because of #2910 |
||
| 143 | $options['site_guid'] = ELGG_ENTITIES_ANY_VALUE; |
||
| 144 | |||
| 145 | $options = array_merge($defaults, $options); |
||
| 146 | |||
| 147 | // can't use helper function with type_subtype_pair because |
||
| 148 | // it's already an array...just need to merge it |
||
| 149 | View Code Duplication | if (isset($options['type_subtype_pair'])) { |
|
| 150 | if (isset($options['type_subtype_pairs'])) { |
||
| 151 | $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], |
||
| 152 | $options['type_subtype_pair']); |
||
| 153 | } else { |
||
| 154 | $options['type_subtype_pairs'] = $options['type_subtype_pair']; |
||
| 155 | } |
||
| 156 | } |
||
| 157 | |||
| 158 | $singulars = array( |
||
| 159 | 'type', 'subtype', 'type_subtype_pair', |
||
| 160 | 'guid', 'owner_guid', 'container_guid', 'site_guid', |
||
| 161 | 'metastring_name', 'metastring_value', |
||
| 162 | 'metastring_owner_guid', 'metastring_id', |
||
| 163 | 'select', 'where', 'join' |
||
| 164 | ); |
||
| 165 | |||
| 166 | $options = _elgg_normalize_plural_options_array($options, $singulars); |
||
| 167 | |||
| 168 | if (!$options) { |
||
|
0 ignored issues
–
show
|
|||
| 169 | return false; |
||
| 170 | } |
||
| 171 | |||
| 172 | $db_prefix = elgg_get_config('dbprefix'); |
||
| 173 | |||
| 174 | // evaluate where clauses |
||
| 175 | if (!is_array($options['wheres'])) { |
||
| 176 | $options['wheres'] = array($options['wheres']); |
||
| 177 | } |
||
| 178 | |||
| 179 | $wheres = $options['wheres']; |
||
| 180 | |||
| 181 | // entities |
||
| 182 | $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], |
||
| 183 | $options['subtypes'], $options['type_subtype_pairs']); |
||
| 184 | |||
| 185 | $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']); |
||
| 186 | $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']); |
||
| 187 | $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']); |
||
| 188 | $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']); |
||
| 189 | |||
| 190 | $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], |
||
| 191 | $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']); |
||
| 192 | |||
| 193 | |||
| 194 | $wheres[] = _elgg_get_entity_time_where_sql('n_table', $options['metastring_created_time_upper'], |
||
| 195 | $options['metastring_created_time_lower'], null, null); |
||
| 196 | |||
| 197 | $wheres[] = _elgg_get_guid_based_where_sql('n_table.owner_guid', |
||
| 198 | $options['metastring_owner_guids']); |
||
| 199 | |||
| 200 | // see if any functions failed |
||
| 201 | // remove empty strings on successful functions |
||
| 202 | View Code Duplication | foreach ($wheres as $i => $where) { |
|
| 203 | if ($where === false) { |
||
| 204 | return false; |
||
| 205 | } elseif (empty($where)) { |
||
| 206 | unset($wheres[$i]); |
||
| 207 | } |
||
| 208 | } |
||
| 209 | |||
| 210 | // remove identical where clauses |
||
| 211 | $wheres = array_unique($wheres); |
||
| 212 | |||
| 213 | // evaluate join clauses |
||
| 214 | if (!is_array($options['joins'])) { |
||
| 215 | $options['joins'] = array($options['joins']); |
||
| 216 | } |
||
| 217 | |||
| 218 | $joins = array(); |
||
| 219 | $joins[] = "JOIN {$db_prefix}entities e ON n_table.entity_guid = e.guid"; |
||
| 220 | |||
| 221 | // evaluate selects |
||
| 222 | if (!is_array($options['selects'])) { |
||
| 223 | $options['selects'] = array($options['selects']); |
||
| 224 | } |
||
| 225 | |||
| 226 | $selects = $options['selects']; |
||
| 227 | |||
| 228 | // For performance reasons we don't want the joins required for metadata / annotations |
||
| 229 | // unless we're going through one of their callbacks. |
||
| 230 | // this means we expect the functions passing different callbacks to pass their required joins. |
||
| 231 | // If we're doing a calculation |
||
| 232 | $custom_callback = ($options['callback'] == 'row_to_elggmetadata' |
||
| 233 | || $options['callback'] == 'row_to_elggannotation'); |
||
| 234 | $is_calculation = $options['metastring_calculation'] ? true : false; |
||
| 235 | |||
| 236 | if ($custom_callback || $is_calculation) { |
||
| 237 | $joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id"; |
||
| 238 | $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id"; |
||
| 239 | |||
| 240 | $selects[] = 'n.string as name'; |
||
| 241 | $selects[] = 'v.string as value'; |
||
| 242 | } |
||
| 243 | |||
| 244 | // add optional joins |
||
| 245 | $joins = array_merge($joins, $options['joins']); |
||
| 246 | |||
| 247 | // metastrings |
||
| 248 | $metastring_clauses = _elgg_get_metastring_sql('n_table', $options['metastring_names'], |
||
| 249 | $options['metastring_values'], null, $options['metastring_ids'], |
||
| 250 | $options['metastring_case_sensitive']); |
||
| 251 | |||
| 252 | if ($metastring_clauses) { |
||
|
0 ignored issues
–
show
The expression
$metastring_clauses of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using Loading history...
|
|||
| 253 | $wheres = array_merge($wheres, $metastring_clauses['wheres']); |
||
| 254 | $joins = array_merge($joins, $metastring_clauses['joins']); |
||
| 255 | } else { |
||
| 256 | $wheres[] = _elgg_get_access_where_sql(array( |
||
| 257 | 'table_alias' => 'n_table', |
||
| 258 | 'guid_column' => 'entity_guid', |
||
| 259 | )); |
||
| 260 | } |
||
| 261 | |||
| 262 | $distinct = $options['distinct'] ? "DISTINCT " : ""; |
||
| 263 | |||
| 264 | if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) { |
||
| 265 | $selects = array_unique($selects); |
||
| 266 | // evalutate selects |
||
| 267 | $select_str = ''; |
||
| 268 | if ($selects) { |
||
|
0 ignored issues
–
show
The expression
$selects of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using Loading history...
|
|||
| 269 | foreach ($selects as $select) { |
||
| 270 | $select_str .= ", $select"; |
||
| 271 | } |
||
| 272 | } |
||
| 273 | |||
| 274 | $query = "SELECT $distinct n_table.*{$select_str} FROM {$db_prefix}$type n_table"; |
||
| 275 | } elseif ($options['count']) { |
||
| 276 | // count is over the entities |
||
| 277 | $query = "SELECT count($distinct e.guid) as calculation FROM {$db_prefix}$type n_table"; |
||
| 278 | } else { |
||
| 279 | $query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table"; |
||
| 280 | } |
||
| 281 | |||
| 282 | View Code Duplication | foreach ($joins as $i => $join) { |
|
| 283 | if ($join === false) { |
||
| 284 | return false; |
||
| 285 | } elseif (empty($join)) { |
||
| 286 | unset($joins[$i]); |
||
| 287 | } |
||
| 288 | } |
||
| 289 | |||
| 290 | // remove identical join clauses |
||
| 291 | $joins = array_unique($joins); |
||
| 292 | |||
| 293 | // add joins |
||
| 294 | foreach ($joins as $j) { |
||
| 295 | $query .= " $j "; |
||
| 296 | } |
||
| 297 | |||
| 298 | // add wheres |
||
| 299 | $query .= ' WHERE '; |
||
| 300 | |||
| 301 | foreach ($wheres as $w) { |
||
| 302 | $query .= " $w AND "; |
||
| 303 | } |
||
| 304 | |||
| 305 | // Add access controls |
||
| 306 | $query .= _elgg_get_access_where_sql(array('table_alias' => 'e')); |
||
| 307 | |||
| 308 | // reverse order by |
||
| 309 | if (isset($options['reverse_order_by']) && $options['reverse_order_by']) { |
||
| 310 | $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']); |
||
| 311 | } |
||
| 312 | |||
| 313 | if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) { |
||
| 314 | if (isset($options['group_by'])) { |
||
| 315 | $options['group_by'] = sanitise_string($options['group_by']); |
||
| 316 | $query .= " GROUP BY {$options['group_by']}"; |
||
| 317 | } |
||
| 318 | |||
| 319 | View Code Duplication | if (isset($options['order_by']) && $options['order_by']) { |
|
| 320 | $options['order_by'] = sanitise_string($options['order_by']); |
||
| 321 | $query .= " ORDER BY {$options['order_by']}, n_table.id"; |
||
| 322 | } |
||
| 323 | |||
| 324 | View Code Duplication | if ($options['limit']) { |
|
| 325 | $limit = sanitise_int($options['limit']); |
||
| 326 | $offset = sanitise_int($options['offset'], false); |
||
| 327 | $query .= " LIMIT $offset, $limit"; |
||
| 328 | } |
||
| 329 | |||
| 330 | $dt = get_data($query, $options['callback']); |
||
| 331 | |||
| 332 | if ($options['preload_owners'] && is_array($dt) && count($dt) > 1) { |
||
| 333 | _elgg_services()->entityPreloader->preload($dt, ['owner_guid']); |
||
| 334 | } |
||
| 335 | |||
| 336 | return $dt; |
||
| 337 | } else { |
||
| 338 | $result = get_data_row($query); |
||
| 339 | return $result->calculation; |
||
| 340 | } |
||
| 341 | } |
||
| 342 | |||
| 343 | /** |
||
| 344 | * Returns an array of joins and wheres for use in metastrings. |
||
| 345 | * |
||
| 346 | * @note The $pairs is reserved for name/value pairs if we want to implement those. |
||
| 347 | * |
||
| 348 | * @param string $table The annotation or metadata table name or alias |
||
| 349 | * @param array $names An array of names |
||
| 350 | * @param array $values An array of values |
||
| 351 | * @param array $pairs Name / value pairs. Not currently used. |
||
| 352 | * @param array $ids Metastring IDs |
||
| 353 | * @param bool $case_sensitive Should name and values be case sensitive? |
||
| 354 | * |
||
| 355 | * @return array |
||
| 356 | * @access private |
||
| 357 | */ |
||
| 358 | function _elgg_get_metastring_sql($table, $names = null, $values = null, |
||
| 359 | $pairs = null, $ids = null, $case_sensitive = false) { |
||
| 360 | |||
| 361 | if ((!$names && $names !== 0) |
||
| 362 | && (!$values && $values !== 0) |
||
| 363 | && !$ids |
||
| 364 | && (!$pairs && $pairs !== 0)) { |
||
| 365 | |||
| 366 | return array(); |
||
| 367 | } |
||
| 368 | |||
| 369 | $db_prefix = elgg_get_config('dbprefix'); |
||
| 370 | |||
| 371 | // binary forces byte-to-byte comparision of strings, making |
||
| 372 | // it case- and diacritical-mark- sensitive. |
||
| 373 | // only supported on values. |
||
| 374 | $binary = ($case_sensitive) ? ' BINARY ' : ''; |
||
| 375 | |||
| 376 | $return = array ( |
||
| 377 | 'joins' => array (), |
||
| 378 | 'wheres' => array() |
||
| 379 | ); |
||
| 380 | |||
| 381 | $wheres = array(); |
||
| 382 | |||
| 383 | // get names wheres and joins |
||
| 384 | $names_where = ''; |
||
| 385 | View Code Duplication | if ($names !== null) { |
|
| 386 | if (!is_array($names)) { |
||
| 387 | $names = array($names); |
||
| 388 | } |
||
| 389 | |||
| 390 | $sanitised_names = array(); |
||
| 391 | foreach ($names as $name) { |
||
| 392 | // normalise to 0. |
||
| 393 | if (!$name) { |
||
| 394 | $name = '0'; |
||
| 395 | } |
||
| 396 | $sanitised_names[] = '\'' . sanitise_string($name) . '\''; |
||
| 397 | } |
||
| 398 | |||
| 399 | if ($names_str = implode(',', $sanitised_names)) { |
||
| 400 | $return['joins'][] = "JOIN {$db_prefix}metastrings msn on $table.name_id = msn.id"; |
||
| 401 | $names_where = "(msn.string IN ($names_str))"; |
||
| 402 | } |
||
| 403 | } |
||
| 404 | |||
| 405 | // get values wheres and joins |
||
| 406 | $values_where = ''; |
||
| 407 | View Code Duplication | if ($values !== null) { |
|
| 408 | if (!is_array($values)) { |
||
| 409 | $values = array($values); |
||
| 410 | } |
||
| 411 | |||
| 412 | $sanitised_values = array(); |
||
| 413 | foreach ($values as $value) { |
||
| 414 | // normalize to 0 |
||
| 415 | if (!$value) { |
||
| 416 | $value = 0; |
||
| 417 | } |
||
| 418 | $sanitised_values[] = '\'' . sanitise_string($value) . '\''; |
||
| 419 | } |
||
| 420 | |||
| 421 | if ($values_str = implode(',', $sanitised_values)) { |
||
| 422 | $return['joins'][] = "JOIN {$db_prefix}metastrings msv on $table.value_id = msv.id"; |
||
| 423 | $values_where = "({$binary}msv.string IN ($values_str))"; |
||
| 424 | } |
||
| 425 | } |
||
| 426 | |||
| 427 | if ($ids !== null) { |
||
| 428 | if (!is_array($ids)) { |
||
| 429 | $ids = array($ids); |
||
| 430 | } |
||
| 431 | |||
| 432 | $ids_str = implode(',', $ids); |
||
| 433 | |||
| 434 | if ($ids_str) { |
||
| 435 | $wheres[] = "n_table.id IN ($ids_str)"; |
||
| 436 | } |
||
| 437 | } |
||
| 438 | |||
| 439 | View Code Duplication | if ($names_where && $values_where) { |
|
| 440 | $wheres[] = "($names_where AND $values_where)"; |
||
| 441 | } elseif ($names_where) { |
||
| 442 | $wheres[] = $names_where; |
||
| 443 | } elseif ($values_where) { |
||
| 444 | $wheres[] = $values_where; |
||
| 445 | } |
||
| 446 | |||
| 447 | $wheres[] = _elgg_get_access_where_sql(array( |
||
| 448 | 'table_alias' => $table, |
||
| 449 | 'guid_column' => 'entity_guid', |
||
| 450 | )); |
||
| 451 | |||
| 452 | if ($where = implode(' AND ', $wheres)) { |
||
| 453 | $return['wheres'][] = "($where)"; |
||
| 454 | } |
||
| 455 | |||
| 456 | return $return; |
||
| 457 | } |
||
| 458 | |||
| 459 | /** |
||
| 460 | * Normalizes metadata / annotation option names to their corresponding metastrings name. |
||
| 461 | * |
||
| 462 | * @param array $options An options array |
||
| 463 | * @return array |
||
| 464 | * @access private |
||
| 465 | */ |
||
| 466 | function _elgg_normalize_metastrings_options(array $options = array()) { |
||
| 467 | |||
| 468 | // support either metastrings_type or metastring_type |
||
| 469 | // because I've made this mistake many times and hunting it down is a pain... |
||
| 470 | $type = elgg_extract('metastring_type', $options, null); |
||
| 471 | $type = elgg_extract('metastrings_type', $options, $type); |
||
| 472 | |||
| 473 | $options['metastring_type'] = $type; |
||
| 474 | |||
| 475 | // support annotation_ and annotations_ because they're way too easy to confuse |
||
| 476 | $prefixes = array('metadata_', 'annotation_', 'annotations_'); |
||
| 477 | |||
| 478 | // map the metadata_* options to metastring_* options |
||
| 479 | $map = array( |
||
| 480 | 'names' => 'metastring_names', |
||
| 481 | 'values' => 'metastring_values', |
||
| 482 | 'case_sensitive' => 'metastring_case_sensitive', |
||
| 483 | 'owner_guids' => 'metastring_owner_guids', |
||
| 484 | 'created_time_lower' => 'metastring_created_time_lower', |
||
| 485 | 'created_time_upper' => 'metastring_created_time_upper', |
||
| 486 | 'calculation' => 'metastring_calculation', |
||
| 487 | 'ids' => 'metastring_ids', |
||
| 488 | ); |
||
| 489 | |||
| 490 | foreach ($prefixes as $prefix) { |
||
| 491 | $singulars = array("{$prefix}name", "{$prefix}value", "{$prefix}owner_guid", "{$prefix}id"); |
||
| 492 | $options = _elgg_normalize_plural_options_array($options, $singulars); |
||
| 493 | |||
| 494 | foreach ($map as $specific => $normalized) { |
||
| 495 | $key = $prefix . $specific; |
||
| 496 | if (isset($options[$key])) { |
||
| 497 | $options[$normalized] = $options[$key]; |
||
| 498 | } |
||
| 499 | } |
||
| 500 | } |
||
| 501 | |||
| 502 | return $options; |
||
| 503 | } |
||
| 504 | |||
| 505 | /** |
||
| 506 | * Enables or disables a metastrings-based object by its id. |
||
| 507 | * |
||
| 508 | * @warning To enable disabled metastrings you must first use |
||
| 509 | * {@link access_show_hidden_entities()}. |
||
| 510 | * |
||
| 511 | * @param int $id The object's ID |
||
| 512 | * @param string $enabled Value to set to: yes or no |
||
| 513 | * @param string $type Metastring type: metadata or annotation |
||
| 514 | * |
||
| 515 | * @return bool |
||
| 516 | * @throws InvalidParameterException |
||
| 517 | * @access private |
||
| 518 | */ |
||
| 519 | function _elgg_set_metastring_based_object_enabled_by_id($id, $enabled, $type) { |
||
| 520 | $id = (int)$id; |
||
| 521 | $db_prefix = elgg_get_config('dbprefix'); |
||
| 522 | |||
| 523 | $object = _elgg_get_metastring_based_object_from_id($id, $type); |
||
| 524 | |||
| 525 | switch ($type) { |
||
| 526 | case 'annotation': |
||
| 527 | case 'annotations': |
||
| 528 | $type = 'annotation'; |
||
| 529 | $table = "{$db_prefix}annotations"; |
||
| 530 | break; |
||
| 531 | |||
| 532 | case 'metadata': |
||
| 533 | $table = "{$db_prefix}metadata"; |
||
| 534 | break; |
||
| 535 | } |
||
| 536 | |||
| 537 | if ($enabled === 'yes' || $enabled === 1 || $enabled === true) { |
||
|
0 ignored issues
–
show
|
|||
| 538 | $enabled = 'yes'; |
||
| 539 | $event = 'enable'; |
||
| 540 | } elseif ($enabled === 'no' || $enabled === 0 || $enabled === false) { |
||
|
0 ignored issues
–
show
|
|||
| 541 | $enabled = 'no'; |
||
| 542 | $event = 'disable'; |
||
| 543 | } else { |
||
| 544 | return false; |
||
| 545 | } |
||
| 546 | |||
| 547 | $return = false; |
||
| 548 | |||
| 549 | if ($object) { |
||
| 550 | // don't set it if it's already set. |
||
| 551 | if ($object->enabled == $enabled) { |
||
| 552 | $return = false; |
||
| 553 | } elseif ($object->canEdit() && (elgg_trigger_event($event, $type, $object))) { |
||
|
0 ignored issues
–
show
$object is of type object<ElggExtender>, but the function expects a string|null.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 554 | $return = update_data("UPDATE $table SET enabled = '$enabled' where id = $id"); |
||
|
0 ignored issues
–
show
The variable
$table does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 555 | } |
||
| 556 | } |
||
| 557 | |||
| 558 | return $return; |
||
| 559 | } |
||
| 560 | |||
| 561 | /** |
||
| 562 | * Runs metastrings-based objects found using $options through $callback |
||
| 563 | * |
||
| 564 | * @warning Unlike _elgg_get_metastring_based_objects() this will not accept an |
||
| 565 | * empty options array! |
||
| 566 | * |
||
| 567 | * @warning This returns null on no ops. |
||
| 568 | * |
||
| 569 | * @param array $options An options array. {@link _elgg_get_metastring_based_objects()} |
||
| 570 | * @param string $callback The callback to pass each result through |
||
| 571 | * @param bool $inc_offset Increment the offset? Pass false for callbacks that delete / disable |
||
| 572 | * |
||
| 573 | * @return bool|null true on success, false on failure, null if no objects are found. |
||
| 574 | * @access private |
||
| 575 | */ |
||
| 576 | function _elgg_batch_metastring_based_objects(array $options, $callback, $inc_offset = true) { |
||
| 577 | if (!$options || !is_array($options)) { |
||
|
0 ignored issues
–
show
The expression
$options of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using Loading history...
|
|||
| 578 | return false; |
||
| 579 | } |
||
| 580 | |||
| 581 | $batch = new \ElggBatch('_elgg_get_metastring_based_objects', $options, $callback, 50, $inc_offset); |
||
| 582 | return $batch->callbackResult; |
||
| 583 | } |
||
| 584 | |||
| 585 | /** |
||
| 586 | * Returns a singular metastring-based object by its ID. |
||
| 587 | * |
||
| 588 | * @param int $id The metastring-based object's ID |
||
| 589 | * @param string $type The type: annotation or metadata |
||
| 590 | * @return \ElggExtender |
||
| 591 | * @access private |
||
| 592 | */ |
||
| 593 | function _elgg_get_metastring_based_object_from_id($id, $type) { |
||
| 594 | $id = (int)$id; |
||
| 595 | if (!$id) { |
||
| 596 | return false; |
||
| 597 | } |
||
| 598 | |||
| 599 | $options = array( |
||
| 600 | 'metastring_type' => $type, |
||
| 601 | 'metastring_id' => $id, |
||
| 602 | ); |
||
| 603 | |||
| 604 | $obj = _elgg_get_metastring_based_objects($options); |
||
| 605 | |||
| 606 | if ($obj && count($obj) == 1) { |
||
| 607 | return $obj[0]; |
||
| 608 | } |
||
| 609 | |||
| 610 | return false; |
||
| 611 | } |
||
| 612 | |||
| 613 | /** |
||
| 614 | * Deletes a metastring-based object by its id |
||
| 615 | * |
||
| 616 | * @param int $id The object's ID |
||
| 617 | * @param string $type The object's metastring type: annotation or metadata |
||
| 618 | * @return bool |
||
| 619 | * @access private |
||
| 620 | */ |
||
| 621 | function _elgg_delete_metastring_based_object_by_id($id, $type) { |
||
| 622 | $id = (int)$id; |
||
| 623 | $db_prefix = elgg_get_config('dbprefix'); |
||
| 624 | |||
| 625 | switch ($type) { |
||
| 626 | case 'annotations': |
||
| 627 | case 'annotation': |
||
| 628 | $table = $db_prefix . 'annotations'; |
||
| 629 | $type = 'annotation'; |
||
| 630 | break; |
||
| 631 | |||
| 632 | case 'metadata': |
||
| 633 | $table = $db_prefix . 'metadata'; |
||
| 634 | $type = 'metadata'; |
||
| 635 | break; |
||
| 636 | |||
| 637 | default: |
||
| 638 | return false; |
||
| 639 | } |
||
| 640 | |||
| 641 | $obj = _elgg_get_metastring_based_object_from_id($id, $type); |
||
| 642 | |||
| 643 | if ($obj) { |
||
| 644 | // Tidy up if memcache is enabled. |
||
| 645 | // @todo only metadata is supported |
||
| 646 | if ($type == 'metadata') { |
||
| 647 | static $metabyname_memcache; |
||
| 648 | if ((!$metabyname_memcache) && (is_memcache_available())) { |
||
| 649 | $metabyname_memcache = new \ElggMemcache('metabyname_memcache'); |
||
| 650 | } |
||
| 651 | |||
| 652 | if ($metabyname_memcache) { |
||
| 653 | // @todo why name_id? is that even populated? |
||
| 654 | $metabyname_memcache->delete("{$obj->entity_guid}:{$obj->name_id}"); |
||
| 655 | } |
||
| 656 | } |
||
| 657 | |||
| 658 | if ($obj->canEdit()) { |
||
| 659 | // bc code for when we triggered 'delete', 'annotations' #4770 |
||
| 660 | $result = true; |
||
| 661 | if ($type == "annotation") { |
||
| 662 | $result = elgg_trigger_event('delete', 'annotations', $obj); |
||
|
0 ignored issues
–
show
$obj is of type object<ElggExtender>, but the function expects a string|null.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 663 | if ($result === false) { |
||
| 664 | elgg_deprecated_notice("Use the event 'delete', 'annotation'", 1.9); |
||
| 665 | } |
||
| 666 | } |
||
| 667 | |||
| 668 | if (elgg_trigger_event('delete', $type, $obj) && $result) { |
||
|
0 ignored issues
–
show
$obj is of type object<ElggExtender>, but the function expects a string|null.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 669 | return (bool)delete_data("DELETE FROM $table WHERE id = $id"); |
||
| 670 | } |
||
| 671 | } |
||
| 672 | } |
||
| 673 | |||
| 674 | return false; |
||
| 675 | } |
||
| 676 | |||
| 677 | /** |
||
| 678 | * Returns options to pass to elgg_get_entities() for metastrings operations. |
||
| 679 | * |
||
| 680 | * @param string $type Metastring type: annotation or metadata |
||
| 681 | * @param array $options Options |
||
| 682 | * |
||
| 683 | * @return array |
||
| 684 | * @access private |
||
| 685 | */ |
||
| 686 | function _elgg_entities_get_metastrings_options($type, $options) { |
||
| 687 | $valid_types = array('metadata', 'annotation'); |
||
| 688 | if (!in_array($type, $valid_types)) { |
||
| 689 | return false; |
||
| 690 | } |
||
| 691 | |||
| 692 | // the options for annotations are singular (annotation_name) but the table |
||
| 693 | // is plural (elgg_annotations) so rewrite for the table name. |
||
| 694 | $n_table = ($type == 'annotation') ? 'annotations' : $type; |
||
| 695 | |||
| 696 | $singulars = array("{$type}_name", "{$type}_value", |
||
| 697 | "{$type}_name_value_pair", "{$type}_owner_guid"); |
||
| 698 | $options = _elgg_normalize_plural_options_array($options, $singulars); |
||
| 699 | |||
| 700 | $clauses = _elgg_get_entity_metadata_where_sql('e', $n_table, $options["{$type}_names"], |
||
| 701 | $options["{$type}_values"], $options["{$type}_name_value_pairs"], |
||
| 702 | $options["{$type}_name_value_pairs_operator"], $options["{$type}_case_sensitive"], |
||
| 703 | $options["order_by_{$type}"], $options["{$type}_owner_guids"]); |
||
| 704 | |||
| 705 | if ($clauses) { |
||
| 706 | // merge wheres to pass to elgg_get_entities() |
||
| 707 | if (isset($options['wheres']) && !is_array($options['wheres'])) { |
||
| 708 | $options['wheres'] = array($options['wheres']); |
||
| 709 | } elseif (!isset($options['wheres'])) { |
||
| 710 | $options['wheres'] = array(); |
||
| 711 | } |
||
| 712 | |||
| 713 | $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']); |
||
| 714 | |||
| 715 | // merge joins to pass to elgg_get_entities() |
||
| 716 | if (isset($options['joins']) && !is_array($options['joins'])) { |
||
| 717 | $options['joins'] = array($options['joins']); |
||
| 718 | } elseif (!isset($options['joins'])) { |
||
| 719 | $options['joins'] = array(); |
||
| 720 | } |
||
| 721 | |||
| 722 | $options['joins'] = array_merge($options['joins'], $clauses['joins']); |
||
| 723 | |||
| 724 | if ($clauses['orders']) { |
||
| 725 | $order_by_metadata = implode(", ", $clauses['orders']); |
||
| 726 | View Code Duplication | if (isset($options['order_by']) && $options['order_by']) { |
|
| 727 | $options['order_by'] = "$order_by_metadata, {$options['order_by']}"; |
||
| 728 | } else { |
||
| 729 | $options['order_by'] = "$order_by_metadata, e.time_created DESC"; |
||
| 730 | } |
||
| 731 | } |
||
| 732 | } |
||
| 733 | |||
| 734 | return $options; |
||
| 735 | } |
||
| 736 | |||
| 737 | /** |
||
| 738 | * Metastring unit tests |
||
| 739 | * |
||
| 740 | * @param string $hook unit_test |
||
| 741 | * @param string $type system |
||
| 742 | * @param array $value Array of other tests |
||
| 743 | * |
||
| 744 | * @return array |
||
| 745 | * @access private |
||
| 746 | */ |
||
| 747 | function _elgg_metastrings_test($hook, $type, $value) { |
||
| 748 | global $CONFIG; |
||
| 749 | $value[] = $CONFIG->path . 'engine/tests/ElggCoreMetastringsTest.php'; |
||
| 750 | return $value; |
||
| 751 | } |
||
| 752 | |||
| 753 | return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) { |
||
| 754 | $hooks->registerHandler('unit_test', 'system', '_elgg_metastrings_test'); |
||
| 755 | }; |
||
| 756 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.