예제 #1
0
 /**
  * Returns SQL appropriate for relationship joins and wheres
  *
  * @todo add support for multiple relationships and guids.
  *
  * @param string $column               Column name the GUID should be checked against.
  *                                     Provide in table.column format.
  * @param string $relationship         Type of the relationship
  * @param int    $relationship_guid    Entity GUID to check
  * @param bool   $inverse_relationship Is $relationship_guid the target of the relationship?
  *
  * @return mixed
  * @access private
  */
 public function getEntityRelationshipWhereSql($column, $relationship = null, $relationship_guid = null, $inverse_relationship = false)
 {
     if ($relationship == null && $relationship_guid == null) {
         return '';
     }
     $wheres = array();
     $joins = array();
     $group_by = '';
     if ($inverse_relationship) {
         $joins[] = "JOIN {$this->db->getTablePrefix()}entity_relationships r on r.guid_one = {$column}";
     } else {
         $joins[] = "JOIN {$this->db->getTablePrefix()}entity_relationships r on r.guid_two = {$column}";
     }
     if ($relationship) {
         $wheres[] = "r.relationship = '" . $this->db->sanitizeString($relationship) . "'";
     }
     if ($relationship_guid) {
         if ($inverse_relationship) {
             $wheres[] = "r.guid_two = '{$relationship_guid}'";
         } else {
             $wheres[] = "r.guid_one = '{$relationship_guid}'";
         }
     } else {
         // See #5775. Queries that do not include a relationship_guid must be grouped by entity table alias,
         // otherwise the result set is not unique
         $group_by = $column;
     }
     if ($where_str = implode(' AND ', $wheres)) {
         return array('wheres' => array("({$where_str})"), 'joins' => $joins, 'group_by' => $group_by);
     }
     return '';
 }
예제 #2
0
 /**
  * Get subscription records from the database
  *
  * Records are an object with two vars: guid and methods with the latter
  * being a comma-separated list of subscription relationship names.
  *
  * @param int $container_guid The GUID of the subscription target
  * @return array
  */
 protected function getSubscriptionRecords($container_guid)
 {
     $container_guid = $this->db->sanitizeInt($container_guid);
     // create IN clause
     $rels = $this->getMethodRelationships();
     if (!$rels) {
         return array();
     }
     array_walk($rels, array($this->db, 'sanitizeString'));
     $methods_string = "'" . implode("','", $rels) . "'";
     $db_prefix = $this->db->getTablePrefix();
     $query = "SELECT guid_one AS guid, GROUP_CONCAT(relationship SEPARATOR ',') AS methods\n\t\t\tFROM {$db_prefix}entity_relationships\n\t\t\tWHERE guid_two = {$container_guid} AND\n\t\t\t\t\trelationship IN ({$methods_string}) GROUP BY guid_one";
     return $this->db->getData($query);
 }
예제 #3
0
 /**
  * {@inheritDoc}
  */
 public function gc($max_lifetime)
 {
     $life = time() - $max_lifetime;
     $query = "DELETE FROM {$this->db->getTablePrefix()}users_sessions WHERE ts < '{$life}'";
     return (bool) $this->db->deleteData($query);
 }
예제 #4
0
 /**
  * Constructor
  *
  * @param Database    $db       The database
  * @param EntityTable $entities Entities table
  */
 public function __construct(Database $db, EntityTable $entities)
 {
     $this->db = $db;
     $this->entities = $entities;
     $this->table = $this->db->getTablePrefix() . 'private_settings';
 }
예제 #5
0
 /**
  * The full name of the metastrings table, including prefix.
  * 
  * @return string
  */
 public function getTableName()
 {
     return $this->db->getTablePrefix() . "metastrings";
 }
예제 #6
0
 /**
  * Returns metadata name and value SQL where for entities.
  * NB: $names and $values are not paired. Use $pairs for this.
  * Pairs default to '=' operand.
  *
  * This function is reused for annotations because the tables are
  * exactly the same.
  *
  * @param string     $e_table           Entities table name
  * @param string     $n_table           Normalized metastrings table name (Where entities,
  *                                    values, and names are joined. annotations / metadata)
  * @param array|null $names             Array of names
  * @param array|null $values            Array of values
  * @param array|null $pairs             Array of names / values / operands
  * @param string     $pair_operator     ("AND" or "OR") Operator to use to join the where clauses for pairs
  * @param bool       $case_sensitive    Case sensitive metadata names?
  * @param array|null $order_by_metadata Array of names / direction
  * @param array|null $owner_guids       Array of owner GUIDs
  *
  * @return false|array False on fail, array('joins', 'wheres')
  * @access private
  */
 function getEntityMetadataWhereSql($e_table, $n_table, $names = null, $values = null, $pairs = null, $pair_operator = 'AND', $case_sensitive = true, $order_by_metadata = null, $owner_guids = null)
 {
     // short circuit if nothing requested
     // 0 is a valid (if not ill-conceived) metadata name.
     // 0 is also a valid metadata value for false, null, or 0
     // 0 is also a valid(ish) owner_guid
     if (!$names && $names !== 0 && (!$values && $values !== 0) && (!$pairs && $pairs !== 0) && (!$owner_guids && $owner_guids !== 0) && !$order_by_metadata) {
         return '';
     }
     // join counter for incremental joins.
     $i = 1;
     // binary forces byte-to-byte comparision of strings, making
     // it case- and diacritical-mark- sensitive.
     // only supported on values.
     $binary = $case_sensitive ? ' BINARY ' : '';
     $access = _elgg_get_access_where_sql(array('table_alias' => 'n_table'));
     $return = array('joins' => array(), 'wheres' => array(), 'orders' => array());
     // will always want to join these tables if pulling metastrings.
     $return['joins'][] = "JOIN {$this->db->getTablePrefix()}{$n_table} n_table on\n\t\t\t{$e_table}.guid = n_table.entity_guid";
     $wheres = array();
     // get names wheres and joins
     $names_where = '';
     if ($names !== null) {
         if (!is_array($names)) {
             $names = array($names);
         }
         $sanitised_names = array();
         foreach ($names as $name) {
             // normalise to 0.
             if (!$name) {
                 $name = '0';
             }
             $sanitised_names[] = '\'' . $this->db->sanitizeString($name) . '\'';
         }
         if ($names_str = implode(',', $sanitised_names)) {
             $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msn on n_table.name_id = msn.id";
             $names_where = "(msn.string IN ({$names_str}))";
         }
     }
     // get values wheres and joins
     $values_where = '';
     if ($values !== null) {
         if (!is_array($values)) {
             $values = array($values);
         }
         $sanitised_values = array();
         foreach ($values as $value) {
             // normalize to 0
             if (!$value) {
                 $value = 0;
             }
             $sanitised_values[] = '\'' . $this->db->sanitizeString($value) . '\'';
         }
         if ($values_str = implode(',', $sanitised_values)) {
             $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msv on n_table.value_id = msv.id";
             $values_where = "({$binary}msv.string IN ({$values_str}))";
         }
     }
     if ($names_where && $values_where) {
         $wheres[] = "({$names_where} AND {$values_where} AND {$access})";
     } elseif ($names_where) {
         $wheres[] = "({$names_where} AND {$access})";
     } elseif ($values_where) {
         $wheres[] = "({$values_where} AND {$access})";
     }
     // add pairs
     // pairs must be in arrays.
     if (is_array($pairs)) {
         // check if this is an array of pairs or just a single pair.
         if (isset($pairs['name']) || isset($pairs['value'])) {
             $pairs = array($pairs);
         }
         $pair_wheres = array();
         // @todo when the pairs are > 3 should probably split the query up to
         // denormalize the strings table.
         foreach ($pairs as $index => $pair) {
             // @todo move this elsewhere?
             // support shortcut 'n' => 'v' method.
             if (!is_array($pair)) {
                 $pair = array('name' => $index, 'value' => $pair);
             }
             // must have at least a name and value
             if (!isset($pair['name']) || !isset($pair['value'])) {
                 // @todo should probably return false.
                 continue;
             }
             // case sensitivity can be specified per pair.
             // default to higher level setting.
             if (isset($pair['case_sensitive'])) {
                 $pair_binary = $pair['case_sensitive'] ? ' BINARY ' : '';
             } else {
                 $pair_binary = $binary;
             }
             if (isset($pair['operand'])) {
                 $operand = $this->db->sanitizeString($pair['operand']);
             } else {
                 $operand = ' = ';
             }
             // for comparing
             $trimmed_operand = trim(strtolower($operand));
             $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}"));
             // certain operands can't work well with strings that can be interpreted as numbers
             // for direct comparisons like IN, =, != we treat them as strings
             // gt/lt comparisons need to stay unencapsulated because strings '5' > '15'
             // see https://github.com/Elgg/Elgg/issues/7009
             $num_safe_operands = array('>', '<', '>=', '<=');
             $num_test_operand = trim(strtoupper($operand));
             if (is_numeric($pair['value']) && in_array($num_test_operand, $num_safe_operands)) {
                 $value = $this->db->sanitizeString($pair['value']);
             } else {
                 if (is_bool($pair['value'])) {
                     $value = (int) $pair['value'];
                 } else {
                     if (is_array($pair['value'])) {
                         $values_array = array();
                         foreach ($pair['value'] as $pair_value) {
                             if (is_numeric($pair_value) && !in_array($num_test_operand, $num_safe_operands)) {
                                 $values_array[] = $this->db->sanitizeString($pair_value);
                             } else {
                                 $values_array[] = "'" . $this->db->sanitizeString($pair_value) . "'";
                             }
                         }
                         if ($values_array) {
                             $value = '(' . implode(', ', $values_array) . ')';
                         }
                         // @todo allow support for non IN operands with array of values.
                         // will have to do more silly joins.
                         $operand = 'IN';
                     } else {
                         if ($trimmed_operand == 'in') {
                             $value = "({$pair['value']})";
                         } else {
                             $value = "'" . $this->db->sanitizeString($pair['value']) . "'";
                         }
                     }
                 }
             }
             $name = $this->db->sanitizeString($pair['name']);
             // @todo The multiple joins are only needed when the operator is AND
             $return['joins'][] = "JOIN {$this->db->getTablePrefix()}{$n_table} n_table{$i}\n\t\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
             $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msn{$i}\n\t\t\t\t\ton n_table{$i}.name_id = msn{$i}.id";
             $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msv{$i}\n\t\t\t\t\ton n_table{$i}.value_id = msv{$i}.id";
             $pair_wheres[] = "(msn{$i}.string = '{$name}' AND {$pair_binary}msv{$i}.string\n\t\t\t\t\t{$operand} {$value} AND {$access})";
             $i++;
         }
         if ($where = implode(" {$pair_operator} ", $pair_wheres)) {
             $wheres[] = "({$where})";
         }
     }
     // add owner_guids
     if ($owner_guids) {
         if (is_array($owner_guids)) {
             $sanitised = array_map('sanitise_int', $owner_guids);
             $owner_str = implode(',', $sanitised);
         } else {
             $owner_str = (int) $owner_guids;
         }
         $wheres[] = "(n_table.owner_guid IN ({$owner_str}))";
     }
     if ($where = implode(' AND ', $wheres)) {
         $return['wheres'][] = "({$where})";
     }
     if (is_array($order_by_metadata)) {
         if (count($order_by_metadata) > 0 && !isset($order_by_metadata[0])) {
             // singleton, so fix
             $order_by_metadata = array($order_by_metadata);
         }
         foreach ($order_by_metadata as $order_by) {
             if (is_array($order_by) && isset($order_by['name'])) {
                 $name = $this->db->sanitizeString($order_by['name']);
                 if (isset($order_by['direction'])) {
                     $direction = $this->db->sanitizeString($order_by['direction']);
                 } else {
                     $direction = 'ASC';
                 }
                 $return['joins'][] = "JOIN {$this->db->getTablePrefix()}{$n_table} n_table{$i}\n\t\t\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
                 $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msn{$i}\n\t\t\t\t\t\ton n_table{$i}.name_id = msn{$i}.id";
                 $return['joins'][] = "JOIN {$this->metastringsTable->getTableName()} msv{$i}\n\t\t\t\t\t\ton n_table{$i}.value_id = msv{$i}.id";
                 $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}"));
                 $return['wheres'][] = "(msn{$i}.string = '{$name}' AND {$access})";
                 if (isset($order_by['as']) && $order_by['as'] == 'integer') {
                     $return['orders'][] = "CAST(msv{$i}.string AS SIGNED) {$direction}";
                 } else {
                     $return['orders'][] = "msv{$i}.string {$direction}";
                 }
                 $i++;
             }
         }
     }
     return $return;
 }
예제 #7
0
파일: Mutex.php 프로젝트: nirajkaushal/Elgg
 /**
  * Checks if mutex is locked
  *
  * @param string $namespace Namespace to use for the database table
  * @return bool
  */
 public function isLocked($namespace)
 {
     $this->assertNamespace($namespace);
     return (bool) count($this->db->getData("SHOW TABLES LIKE '{$this->db->getTablePrefix()}{$namespace}_lock'"));
 }