/** * * Initializes the relationship given an associative array of values that is produced * by parsing the relationships.ini file. * * @param $rel_values Initializing parameters for relationship. Possible keys include: * __sql__ : An sql query to define the relationship. * * */ function _init(&$rel_values) { $r =& $this->_schema; /* * First we will check the array for parameters. Parameters might include * default values for new records in the relationship - or for existing records * in the relationship. */ foreach ($rel_values as $key => $value) { if (strpos($key, ":") !== false) { $path = explode(":", $key); $len = count($path); $val =& $r; for ($i = 0; $i < $len; $i++) { //if (!isset($val[$path[$i]]) ){ if ($i == $len - 1) { $val[$path[$i]] = $value; } else { if (!isset($val[$path[$i]])) { $val[$path[$i]] = array(); } $valTemp =& $val; unset($val); $val =& $valTemp[$path[$i]]; unset($valTemp); } //} } } } if (isset($rel_values['__cardinality__'])) { $r['__cardinality__'] = $rel_values['__cardinality__']; } if (array_key_exists('__sql__', $rel_values)) { // The relationship was defined using an SQL statement $r['sql'] = $rel_values['__sql__']; $matches = array(); /* MOD START 051021 - shannah@sfu.ca - Using PEAR SQL parser package instead of regexes. */ $parser = new SQL_Parser(); $struct = $parser->parse($r['sql']); if (PEAR::isError($struct)) { error_log($struct->toString() . "\n" . implode("\n", $struct->getBacktrace())); throw new Exception("Failed to parse relationship SQ. See error log for details.", E_USER_ERROR); } $parser_wrapper = new SQL_Parser_wrapper($struct); $parser_wrapper->fixColumns(); $r['parsed_sql'] =& $struct; $r['tables'] = $struct['table_names']; $r['columns'] = $struct['column_names']; foreach ($struct['columns'] as $colstruct) { if ($colstruct['type'] == 'ident' and @$colstruct['alias']) { $r['aliases'][$colstruct['value']] = $colstruct['alias']; } } $temp = array(); foreach ($r['columns'] as $column) { $col = $parser_wrapper->resolveColumnName($column); if (preg_match('/\\.$/', $col)) { $col = $col . '*'; } $temp[] = $col; } $r['columns'] = $temp; unset($struct); unset($temp); /* MOD END 051021 */ } else { // The relationship was not defined using SQL. It merely defines match columns // and select columns $select = '*'; // Default selection to all columns if (array_key_exists('__select__', $rel_values)) { // __select__ should be comma-delimited list of column names. $select = $rel_values['__select__']; } $tables = array(); // stores list of table names involved in this relation // Let's generate an SQL query based on the information given // $from = 'from '; // from portion of generated sql query $where = 'where '; // where portion of generated sql query foreach ($rel_values as $c1 => $c2) { // Iterate through all of the match columns of the relationship if (in_array($c1, array('__sql__', '__select__', '__sort__', '__domain__', '__cardinality__'))) { continue; } // special flags like sql, select, and sort are not column matchings.. we skip them. if (strpos($c1, ":") !== false) { continue; } // This is a parameter so we ignore it. // get the paths of the related columns // Match columns may be given as Table_name.Column_name dotted pairs... we need to separate // the tablenames from the column names. $p1 = explode('.', $c1); $p2 = explode('.', $c2); if (count($p1) == 1) { // Only column name is given.. we assume the tablename is the current table. array_unshift($p1, $this->_sourceTable->tablename); } if (count($p2) == 1) { // Only the column name is given for rhs... assume current table name. array_unshift($p2, $this->_sourceTable->tablename); } // add the tables to our table array... we omit the current table though. if (!in_array($p1[0], $tables) && $p1[0] != $this->_sourceTable->tablename) { $tables[] = $p1[0]; } if (!in_array($p2[0], $tables) && $p2[0] != $this->_sourceTable->tablename) { $tables[] = $p2[0]; } // Simplify references to current table to be replaced by variable value if ($p1[0] == $this->_sourceTable->tablename) { $lhs = "'\${$p1['1']}'"; } else { $lhs = "{$p1['0']}.{$p1['1']}"; } if ($p2[0] == $this->_sourceTable->tablename) { if (strpos($p2[1], '$') === 0) { $var = ''; } else { $var = '$'; } $rhs = "'" . $var . $p2[1] . "'"; } else { $rhs = "{$p2['0']}.{$p2['1']}"; } // append condition to where clause $where .= strlen($where) > 6 ? ' and ' : ''; $where .= "{$lhs}={$rhs}"; } foreach ($tables as $table) { $from .= $table . ', '; } $from = substr($from, 0, strlen($from) - 2); $r['sql'] = "select {$select} {$from} {$where}"; /* MOD START 051021 - shannah@sfu.ca - Using PEAR SQL parser package instead of regexes. */ $parser = new SQL_Parser(null, 'MySQL'); $struct = $parser->parse($r['sql']); $parser_wrapper = new SQL_Parser_wrapper($struct, 'MySQL'); $parser_wrapper->fixColumns(); $r['parsed_sql'] =& $struct; $r['tables'] = $struct['table_names']; $r['columns'] = $struct['column_names']; $temp = array(); foreach ($r['columns'] as $column) { $col = $parser_wrapper->resolveColumnName($column); if (preg_match('/\\.$/', $col)) { $col = $col . '*'; } $temp[] = $col; } $r['columns'] = $temp; unset($struct); } $res = $this->_normalizeColumns(); if (PEAR::isError($res)) { return $res; } $r['short_columns'] = array(); foreach ($r['columns'] as $col) { list($table, $col) = explode('.', $col); $r['short_columns'][] = $col; } }