/** * Root finder: * Takes a site id and returns the id of the root page. * @param integer $site_id * @return mixed page id integer if found; NULL if not found */ function root_finder( $site_id ) { $es = new entity_selector( ); $es->add_type( id_of( 'minisite_page') ); $es->add_relation( 'entity.state = "Live"' ); $es->add_right_relationship( $site_id, get_owns_relationship_id(id_of('minisite_page')) ); $results = $es->run_one(); foreach( $results as $page ) { $page_id = $page->get_value( 'id' ); if( is_site_root( $page_id ) ) return $page_id; } }
/** * Set up a dbselector object for grabbing Reason entities * * @param integer $type the id of the type to grab * @param mixed $site_id an site id (integer) or an array of site ids * @param string $sharing either "owns", "borrows", "owns borrows", or "" * @param array $table_mod tables to be included or excluded * @param string $table_action either "include" or "exclude" -- specifies what to do with tables given in $table_mod */ function get_entities_by_type_object($type, $site_id = '', $sharing = 'owns', $table_mod = array(), $table_action = '') { if (!($type = (int) $type)) { trigger_error('get_entities_by_type_object() requires an integer type id as its first parameter.'); return ''; } $dbq = new DBSelector(); if ($table_action == 'include') { $tables = $table_mod; } else { $tables = get_entity_tables_by_type($type); } if ($table_action == 'exclude') { $tables = array_diff($tables, $table_mod); } foreach ($tables as $table) { $dbq->add_field($table, '*'); $dbq->add_table($table); // don't match entity table against itself if ($table != 'entity') { $dbq->add_relation('`entity`.`id` = `' . $table . '`.`id`'); } } $dbq->add_relation('`entity`.`type` = "' . $type . '"'); if ($site_id && $sharing) { $dbq->add_table('r', 'relationship'); if (!reason_relationship_names_are_unique()) { $dbq->add_table('ar', 'allowable_relationship'); } if (is_array($site_id)) { array_walk($site_id, 'db_prep_walk'); $dbq->add_relation('r.entity_a IN (' . implode(',', $site_id) . ')'); } else { $dbq->add_relation('r.entity_a = "' . reason_sql_string_escape($site_id) . '"'); } $dbq->add_relation('r.entity_b = entity.id'); if (!reason_relationship_names_are_unique()) { $dbq->add_relation('r.type = ar.id'); } if (preg_match('/owns/', $sharing) && preg_match('/borrows/', $sharing)) { if (reason_relationship_names_are_unique()) { $owns_rel_id = get_owns_relationship_id($type); $borrows_rel_id = get_borrows_relationship_id($type); $dbq->add_relation('(r.type = ' . $owns_rel_id . ' OR r.type = ' . $borrows_rel_id . ')'); } else { $dbq->add_relation('(ar.name = "owns" OR ar.name = "borrows")'); } } elseif (preg_match('/borrows/', $sharing)) { if (reason_relationship_names_are_unique()) { $borrows_rel_id = get_borrows_relationship_id($type); $dbq->add_relation('(r.type = ' . $borrows_rel_id . ')'); } else { $dbq->add_relation('ar.name = "borrows"'); } } else { if (reason_relationship_names_are_unique()) { $owns_rel_id = get_owns_relationship_id($type); $dbq->add_relation('(r.type = ' . $owns_rel_id . ')'); } else { $dbq->add_relation('ar.name = "owns"'); } } } return $dbq; }
/** * Create a new allowable relationship * * Checks to make sure we are not duplicating an existing allowable relationship before creating new one. * * Checks include: * 1. the type ids must be the ids of existing reason types * 2. the name must be a nonempty string containing only numbers, letters, and underscores that does not already exist in the allowable relationship table (exception: borrows and owns) * 3. for borrows or owns relationships, the type must not already have an allowable relationship of that type * * @param integer $a_side_type_id The id of the type on the left side of the relationship * @param integer $b_side_type_id The id of the type on the right side of the relationship * @param string $name The unique name of the allowable relationship (or "owns" or "borrows") * @param array $other_data Additional data to be stored in the allowable_relationship table, keyed by field name * @return mixed id of newly created relationship if successful; false if failure * * @todo update to do verification and handling of new "type" field */ function create_allowable_relationship($a_side_type_id,$b_side_type_id,$name,$other_data = array()) { // validate data $a_side_type_id = turn_into_int($a_side_type_id); $b_side_type_id = turn_into_int($b_side_type_id); $name = turn_into_string($name); if(empty($a_side_type_id)) { trigger_error('$a_side_type_id must be a nonzero integer in create_allowable_relationship()'); return false; } $a_ent = new entity($a_side_type_id); if(!empty($a_ent)) { if($a_ent->get_value('type') != id_of('type')) { trigger_error('$a_side_type_id must be the ID of a Reason type entity'); return false; } } else { trigger_error('$a_side_type_id is not the ID of a Reason entity'); return false; } if(empty($b_side_type_id)) { trigger_error('$b_side_type_id must be a nonzero integer in create_allowable_relationship()'); return false; } $b_ent = new entity($b_side_type_id); if(!empty($b_ent)) { if($b_ent->get_value('type') != id_of('type')) { trigger_error('$b_side_type_id must be the ID of a Reason type entity'); return false; } } else { trigger_error('$b_side_type_id is not the ID of a Reason entity'); return false; } if(empty($name)) { trigger_error('$name must be a string in create_allowable_relationship()'); return false; } if( !preg_match( "|^[0-9a-z_]*$|i" , $name ) ) { trigger_error('$name must only contain numbers, letters, and underscores'); return false; } if (!reason_relationship_names_are_unique()) { $repeatable_names = array('borrows','owns'); if( !in_array($name,$repeatable_names) && reason_relationship_name_exists($name, false) ) { trigger_error('Unable to create allowable relationship named '.$name.' because there is already an allowable relationship with that name in Reason'); return false; } if(in_array($name,$repeatable_names)) { if($a_side_type_id != id_of('site')) { trigger_error('The a_side_type_id of borrows and owns relationships must be the id of the site type'); return false; } // check to see if an owns/borrows relationship already exists for this type if ( (($name == 'owns') && get_owns_relationship_id($b_side_type_id)) || (($name == 'borrows') && get_borrows_relationship_id($b_side_type_id)) ) { trigger_error($name.' relationship already exists between '.$a_side_type_id.' and '.$b_side_type_id.'.'); return false; } } } else { if (reason_relationship_name_exists($name, false)) { trigger_error('Unable to create allowable relationship named '.$name.' because there is already an allowable relationship with that name in Reason'); return false; } if (isset($other_data['type']) && ( ($other_data['type'] == 'owns') || ($other_data['type'] == 'borrows') ) ) { if ($a_side_type_id != id_of('site')) { trigger_error('The a_side_type_id of borrows and owns relationships must be the id of the site type'); return false; } // enforce our naming convention $owns_name_should_be = $a_ent->get_value('unique_name') . '_owns_' . $b_ent->get_value('unique_name'); $borrows_name_should_be = $a_ent->get_value('unique_name') . '_borrows_' . $b_ent->get_value('unique_name'); if ( ($other_data['type'] == 'owns') && ($name != $owns_name_should_be) ) { trigger_error('A new allowable relationship of type owns must follow the naming convention a_side_unique_name_owns_b_side_entity_unique_name'); return false; } elseif ( ($other_data['type'] == 'borrows') && ($name != $borrows_name_should_be) ) { trigger_error('A new allowable relationship of type borrows must follow the naming convention a_side_unique_name_borrows_b_side_entity_unique_name'); return false; } } if (isset($other_data['type']) && ($other_data['type'] == 'archive')) { if ($a_side_type_id != $b_side_type_id) { trigger_error('The a_side_type_id and b_side_type_id of archive relationships must be the same.'); return false; } $archive_name_should_be = $a_ent->get_value('unique_name') . '_archive'; if ($name != $archive_name_should_be) { trigger_error('A new allowable relationship of type archive must follow the naming convention type_unique_name_archive'); return false; } } } // do the creation of the allowable relationship $default_values = array( 'directionality'=>'unidirectional', 'is_sortable'=>'no', 'connections'=>'many_to_many', 'required'=>'no', ); if (reason_relationship_names_are_unique()) $default_values['type'] = 'association'; $values = array_merge($default_values,$other_data); $values['relationship_a'] = $a_side_type_id; $values['relationship_b'] = $b_side_type_id; $values['name'] = $name; $sqler = new SQLER(); if($sqler->insert('allowable_relationship',$values)) { $insert_id = mysql_insert_id(); reason_refresh_relationship_names(); return $insert_id; } else { return false; } }
function move_into_site($orphan_id, $types, $owner_site_id) { if (empty($this->_user_id)) { trigger_error('Must set user id before calling move_into_site()'); return false; } if (!get_owner_site_id($orphan_id)) { $owns_rel_id = get_owns_relationship_id($types); // If there is an existing entry in the relationship table, delete it $q = 'DELETE FROM `relationship` WHERE `entity_b` = "' . reason_sql_string_escape($orphan_id) . '" AND `type` = "' . reason_sql_string_escape($owns_rel_id) . '"'; $r = db_query($q, 'Unable to delete old owns relationship'); // create new ownership entry create_relationship($owner_site_id, $orphan_id, $owns_rel_id); } else { trigger_error($orphan_id . ' not actually an orphan'); return false; } }
/** * Get the URL of the site that owns a given page * * This function returns a URL relative to the server root * * @param integer $page_id * @return mixed string URL if successful; else null */ function get_site_URL($page_id) { static $cache; if (isset($cache[$page_id])) { $results = $cache[$page_id]; } else { $es = new entity_selector(); $es->add_type(id_of('site')); $es->limit_tables('site'); $es->limit_fields('site.base_url'); $es->add_left_relationship($page_id, get_owns_relationship_id(id_of('minisite_page'))); $es->set_num(1); $results = $es->run_one(); $cache[$page_id] = $results; } if (!empty($results)) { $site = current($results); return $site->get_value('base_url'); } }
/** * Returns an entity of the site that owns this entity * @return entity */ function get_owner() { $right_rels = $this->get_right_relationship(get_owns_relationship_id($this->get_value('type'))); if (!empty($right_rels[0])) { return $right_rels[0]; } else { return 0; } }
/** * We use a DBSelector to construct a super basic query to quickly get the owner id. * * This method probably ought to be a method directly on minisite page entities ... but alas we aren't there yet. * For efficiency sake, we could eliminate this if the owner was stored on the page entity and not across a relationship * * @access private * @param object minisite_page entity * @return int owner id for a minisite page */ function _get_owner_id(&$page) { if (!$page->has_value('owner_id')) { $d = new DBselector(); $d->add_table( 'r', 'relationship' ); $d->add_field( 'r', 'entity_a', 'owner_id' ); $d->add_relation( 'r.type = ' . get_owns_relationship_id(id_of('minisite_page'))); $d->add_relation( 'r.entity_b = ' . $page->id() ); $d->set_num(1); $result = db_query( $d->get_query() , 'Error getting owner ID.' ); if( $row = mysql_fetch_assoc($result)) { $page->set_value('owner_id', $row['owner_id']); } else { $page->set_value('owner_id', false); } } return $page->get_value('owner_id'); }
/** * Adds a new field to the entity which is actually not a field of entity, but rather a field of * an entity which is related to the current entities. The entities selected by the ES will be * on the right side of the relationship. * Will return multiples of an entity if it has multiples of the same relationship. Not sure * how to change this. * @param string $rel_name the name of the relationship between the entities * @param string $table the table where the field is * @param string $field the name of the field to be selected * @param string $alias that alias for the field * @param mixed $limit_results true return only row for which the related value is defined * false to return all results even if the value does not exist * string or array to limit results to the values passed * @return void */ function add_right_relationship_field($rel_name, $table, $field, $alias, $limit_results = true) { if ($rel_name != "owns" && $rel_name != "borrows" && !empty($rel_name)) { $rel_type_id = relationship_id_of($rel_name); } elseif ($rel_name == 'owns' || $rel_name == 'borrows') { if (empty($this->type)) { $call_info = array_shift(debug_backtrace()); $code_line = $call_info['line']; $file = array_pop(explode('/', $call_info['file'])); $msg = 'entity selector method add_right_relationship_field called by ' . $file . ' on line ' . $code_line . ' on a generic "owns" or "borrows" relationship when the type has not been set on the entity selector.'; trigger_error($msg, WARNING); return false; } elseif ($rel_name == "owns") { $rel_type_id = get_owns_relationship_id(reset($this->type)); } elseif ($rel_name == "borrows") { $rel_type_id = get_borrows_relationship_id(reset($this->type)); } } if (empty($rel_type_id)) { trigger_error('add_right_relationship_field failed - an id could not be determined from the relationship name provided'); return false; } if ($limit_results === false) { $cur_es = carl_clone($this); $this->union = true; } $es = new entity_selector(); $es->add_table('relationship', 'relationship'); $es->add_table('__entity__', 'entity'); if ($table != 'entity') { $es->add_table($table); } $tables = $this->merge_tables($es); if (!empty($tables['relationship'])) { $r = $tables['relationship']; } else { $r = 'relationship'; } if (!empty($tables['__entity__'])) { $e = $tables['__entity__']; } else { $e = '__entity__'; } if ($table == 'entity') { $t = $e; } else { if (!empty($tables[$table])) { $t = $tables[$table]; } else { $t = $table; } } if ($e != $t) { $this->add_relation($e . '.id = ' . $t . '.id'); } $this->add_relation($e . '.id = ' . $r . '.entity_a'); $this->add_relation('entity.id = ' . $r . '.entity_b'); $this->add_relation($r . '.type = ' . $rel_type_id); $this->add_field($t, $field, $alias); if ($this->_env['restrict_site'] and !empty($this->_env['site'])) { $this->add_relation('(' . $r . '.site=0 OR ' . $r . '.site=' . addslashes($this->_env['site']) . ')'); } if ($limit_results === false) { $this->union_fields[end($this->fields)] = '0 as ' . $alias; $this->diff['fields'][] = array_diff_assoc($this->fields, $cur_es->fields); $this->diff['tables'][] = array_diff_assoc($this->tables, $cur_es->tables); $this->diff['relations'][] = array_diff_assoc($this->relations, $cur_es->relations); } elseif (is_string($limit_results) || is_array($limit_results)) { if (is_array($limit_results) && empty($limit_results)) { $this->add_relation('0 = 1'); } else { $limit_values = is_string($limit_results) ? array($limit_results) : $limit_results; array_walk($limit_values, 'db_prep_walk'); $this->add_relation($t . '.' . $field . ' IN (' . implode(',', $limit_values) . ')'); } } return array($alias => array('table_orig' => $table, 'table' => $t, 'field' => $field)); }