Exemplo n.º 1
0
 /**
  * 
  * 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;
     }
 }