Ejemplo n.º 1
0
 /**
  * Build a query based on the given options
  * 
  * @param array $arrOptions The options array
  * 
  * @return string The query string
  */
 public static function find($arrOptions)
 {
     $objBase = new \DcaExtractor($arrOptions['table']);
     if (!$objBase->hasRelations()) {
         $strQuery = "SELECT * FROM " . $arrOptions['table'];
     } else {
         $arrJoins = array();
         $arrFields = array($arrOptions['table'] . ".*");
         $intCount = 0;
         foreach ($objBase->getRelations() as $strKey => $arrConfig) {
             // Automatically join the single-relation records
             if ($arrConfig['load'] == 'eager' || $arrOptions['eager']) {
                 if ($arrConfig['type'] == 'hasOne' || $arrConfig['type'] == 'belongsTo') {
                     ++$intCount;
                     $objRelated = new \DcaExtractor($arrConfig['table']);
                     foreach (array_keys($objRelated->getFields()) as $strField) {
                         $arrFields[] = 'j' . $intCount . '.' . $strField . ' AS ' . $strKey . '__' . $strField;
                     }
                     $arrJoins[] = " LEFT JOIN " . $arrConfig['table'] . " j{$intCount} ON " . $arrOptions['table'] . "." . $strKey . "=j{$intCount}.id";
                 }
             }
         }
         // Generate the query
         $strQuery = "SELECT " . implode(', ', $arrFields) . " FROM " . $arrOptions['table'] . implode("", $arrJoins);
     }
     // Where condition
     if ($arrOptions['column'] !== null) {
         $strQuery .= " WHERE " . (is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . $arrOptions['column'] . "=?");
     }
     // Order by
     if ($arrOptions['order'] !== null) {
         $strQuery .= " ORDER BY " . $arrOptions['order'];
     }
     return $strQuery;
 }
Ejemplo n.º 2
0
 /**
  * Auto-format model data based on DCA config
  * @param   \Model
  * @param   callable
  * @return  \ArrayObject
  */
 public static function generate(\Model $objModel = null, $varCallable = null)
 {
     if (null === $objModel) {
         return new \ArrayObject(array(), \ArrayObject::ARRAY_AS_PROPS);
     }
     $strTable = $objModel->getTable();
     $objDca = new \DcaExtractor($strTable);
     $arrRelations = $objDca->getRelations();
     $arrData = array();
     \System::loadLanguageFile($strTable);
     \Controller::loadDataContainer($strTable);
     $arrFields =& $GLOBALS['TL_DCA'][$strTable]['fields'];
     foreach ($objModel->row() as $strField => $varValue) {
         $arrAdditional = array();
         $strLabel = Format::dcaLabel($strTable, $strField);
         if (isset($arrRelations[$strField])) {
             $objRelated = $objModel->getRelated($strField);
             if ($objRelated == null) {
                 $arrData[$strField] = new Plain('', $strLabel, $arrAdditional);
             } elseif ($objRelated instanceof \Model\Collection) {
                 $arrCollection = array();
                 foreach ($objRelated as $objRelatedModel) {
                     $arrCollection[] = new Relation($objRelatedModel, '', array(), $varCallable);
                 }
                 $arrData[$strField] = new Collection($arrCollection, $strLabel);
             } else {
                 $arrData[$strField] = new Relation($objRelated, $strLabel, array(), $varCallable);
             }
             continue;
         }
         $arrAdditional['formatted'] = Format::dcaValue($strTable, $strField, $varValue);
         if (in_array($arrFields[$strField]['eval']['rgxp'], array('date', 'datim', 'time'))) {
             $arrData[$strField] = new Timestamp($varValue, $strLabel, $arrAdditional);
         } else {
             $arrData[$strField] = new Plain($varValue, $strLabel, $arrAdditional);
         }
     }
     if (null !== $varCallable) {
         call_user_func_array($varCallable, array($objModel, &$arrData));
     }
     return new \ArrayObject($arrData, \ArrayObject::ARRAY_AS_PROPS);
 }
Ejemplo n.º 3
0
 /**
  * Load the relations and optionally process a result set
  * 
  * @param \Database_Result $objResult An optional database result
  */
 public function __construct(\Database_Result $objResult = null)
 {
     parent::__construct();
     $objRelations = new \DcaExtractor(static::$strTable);
     $this->arrRelations = $objRelations->getRelations();
     if ($objResult !== null) {
         $this->arrData = $objResult->row();
         // Look for joined fields
         foreach ($this->arrData as $k => $v) {
             if (strpos($k, '__') !== false) {
                 list($key, $field) = explode('__', $k, 2);
                 // Create the related model
                 if (!isset($this->arrRelated[$key])) {
                     $table = $this->arrRelations[$key]['table'];
                     $strClass = $this->getModelClassFromTable($table);
                     $this->arrRelated[$key] = new $strClass();
                 }
                 $this->arrRelated[$key]->{$field} = $v;
                 unset($this->arrData[$k]);
             }
         }
     }
 }
Ejemplo n.º 4
0
 /**
  * Build model based on database result
  *
  * @param \Database\Result $objResult
  *
  * @return \Model
  */
 public static function createModelFromDbResult(\Database\Result $objResult)
 {
     $strClass = '';
     if (is_numeric($objResult->type)) {
         $objRelations = new \DcaExtractor(static::$strTable);
         $arrRelations = $objRelations->getRelations();
         if (isset($arrRelations['type'])) {
             $strTypeClass = static::getClassFromTable($arrRelations['type']['table']);
             $objType = $strTypeClass::findOneBy($arrRelations['type']['field'], $objResult->type);
             if (null !== $objType) {
                 $strClass = static::getClassForModelType($objType->class);
             }
         }
     } else {
         $strClass = static::getClassForModelType($objResult->type);
     }
     // Try to use the current class as fallback
     if ($strClass == '') {
         $strClass = get_called_class();
         $objReflection = new \ReflectionClass($strClass);
         if ($objReflection->isAbstract()) {
             return null;
         }
     }
     $objModel = new $strClass($objResult);
     if (null !== static::$strInterface && !is_a($objModel, static::$strInterface)) {
         throw new \RuntimeException(get_class($objModel) . ' must implement interface ' . static::$strInterface);
     }
     return $objModel;
 }
Ejemplo n.º 5
0
 /**
  * Return select statement to load product data including multilingual fields
  * @param array an array of columns
  * @return string
  */
 protected static function buildFindQuery(array $arrOptions)
 {
     $objBase = new \DcaExtractor($arrOptions['table']);
     $arrJoins = array();
     $arrFields = array($arrOptions['table'] . ".*", "IF(" . $arrOptions['table'] . ".pid>0, parent.type, " . $arrOptions['table'] . ".type) AS type", "'" . str_replace('-', '_', $GLOBALS['TL_LANGUAGE']) . "' AS language");
     foreach (Attribute::getMultilingualFields() as $attribute) {
         $arrFields[] = "IFNULL(translation.{$attribute}, " . $arrOptions['table'] . ".{$attribute}) AS {$attribute}";
     }
     foreach (Attribute::getFetchFallbackFields() as $attribute) {
         $arrFields[] = "{$arrOptions['table']}.{$attribute} AS {$attribute}_fallback";
     }
     $arrFields[] = "c.sorting";
     $arrJoins[] = " LEFT OUTER JOIN " . \Isotope\Model\ProductCategory::getTable() . " c ON {$arrOptions['table']}.id=c.pid";
     $arrJoins[] = " LEFT OUTER JOIN " . $arrOptions['table'] . " translation ON " . $arrOptions['table'] . ".id=translation.pid AND translation.language='" . str_replace('-', '_', $GLOBALS['TL_LANGUAGE']) . "'";
     $arrJoins[] = " LEFT OUTER JOIN " . $arrOptions['table'] . " parent ON " . $arrOptions['table'] . ".pid=parent.id";
     if ($objBase->hasRelations()) {
         $intCount = 0;
         foreach ($objBase->getRelations() as $strKey => $arrConfig) {
             // Automatically join the single-relation records
             if ($arrConfig['load'] == 'eager' || $arrOptions['eager']) {
                 if ($arrConfig['type'] == 'hasOne' || $arrConfig['type'] == 'belongsTo') {
                     if (is_array($arrOptions['joinAliases']) && ($key = array_search($arrConfig['table'], $arrOptions['joinAliases'])) !== false) {
                         $strJoinAlias = $key;
                         unset($arrOptions['joinAliases'][$key]);
                     } else {
                         ++$intCount;
                         $strJoinAlias = 'j' . $intCount;
                     }
                     $objRelated = new \DcaExtractor($arrConfig['table']);
                     foreach (array_keys($objRelated->getFields()) as $strField) {
                         $arrFields[] = $strJoinAlias . '.' . $strField . ' AS ' . $strKey . '__' . $strField;
                     }
                     $arrJoins[] = " LEFT JOIN " . $arrConfig['table'] . " {$strJoinAlias} ON " . $arrOptions['table'] . "." . $strKey . "={$strJoinAlias}.id";
                 }
             }
         }
     }
     // Generate the query
     $strQuery = "SELECT " . implode(', ', $arrFields) . " FROM " . $arrOptions['table'] . implode("", $arrJoins);
     // Where condition
     if (!is_array($arrOptions['column'])) {
         $arrOptions['column'] = array($arrOptions['table'] . '.' . $arrOptions['column'] . '=?');
     }
     // The model must never find a language record
     $strQuery .= " WHERE {$arrOptions['table']}.language='' AND " . implode(" AND ", $arrOptions['column']);
     // Group by
     if ($arrOptions['group'] !== null) {
         $strQuery .= " GROUP BY " . $arrOptions['group'];
     }
     // Order by
     if ($arrOptions['order'] !== null) {
         $strQuery .= " ORDER BY " . $arrOptions['order'];
     }
     return $strQuery;
 }
Ejemplo n.º 6
0
 /**
  * Load the relations and optionally process a result set
  *
  * @param \Database\Result $objResult An optional database result
  */
 public function __construct(\Database\Result $objResult = null)
 {
     $this->arrModified = array();
     $objDca = new \DcaExtractor(static::$strTable);
     $this->arrRelations = $objDca->getRelations();
     if ($objResult !== null) {
         $arrRelated = array();
         $arrData = $objResult->row();
         // Look for joined fields
         foreach ($arrData as $k => $v) {
             if (strpos($k, '__') !== false) {
                 list($key, $field) = explode('__', $k, 2);
                 if (!isset($arrRelated[$key])) {
                     $arrRelated[$key] = array();
                 }
                 $arrRelated[$key][$field] = $v;
                 unset($arrData[$k]);
             }
         }
         // Create the related models
         foreach ($arrRelated as $key => $row) {
             $table = $this->arrRelations[$key]['table'];
             $strClass = static::getClassFromTable($table);
             $intPk = $strClass::getPk();
             // If the primary key is empty, set null (see #5356)
             if (!isset($row[$intPk])) {
                 $this->arrRelated[$key] = null;
             } else {
                 $objRelated = \Model\Registry::getInstance()->fetch($table, $row[$intPk]);
                 if ($objRelated !== null) {
                     $objRelated->mergeRow($row);
                 } else {
                     $objRelated = new $strClass();
                     $objRelated->setRow($row);
                 }
                 $this->arrRelated[$key] = $objRelated;
             }
         }
         $this->setRow($arrData);
         // see #5439
         \Model\Registry::getInstance()->register($this);
     }
 }
Ejemplo n.º 7
0
 /**
  * Create the DCA extract cache files
  */
 public function generateDcaExtracts()
 {
     $included = array();
     $arrExtracts = array();
     // Only check the active modules (see #4541)
     foreach (\ModuleLoader::getActive() as $strModule) {
         $strDir = 'system/modules/' . $strModule . '/dca';
         if (!is_dir(TL_ROOT . '/' . $strDir)) {
             continue;
         }
         foreach (scan(TL_ROOT . '/' . $strDir) as $strFile) {
             // Ignore non PHP files and files which have been included before
             if (strncmp($strFile, '.', 1) === 0 || substr($strFile, -4) != '.php' || in_array($strFile, $included)) {
                 continue;
             }
             $strTable = substr($strFile, 0, -4);
             $objExtract = new \DcaExtractor($strTable);
             if ($objExtract->isDbTable()) {
                 $arrExtracts[$strTable] = $objExtract;
             }
             $included[] = $strFile;
         }
     }
     // Create one file per table
     foreach ($arrExtracts as $strTable => $objExtract) {
         // Create the file
         $objFile = new \File('system/cache/sql/' . $strTable . '.php', true);
         $objFile->write("<?php\n\n");
         // Meta
         $arrMeta = $objExtract->getMeta();
         $objFile->append("\$this->arrMeta = array\n(");
         $objFile->append("\t'engine' => '{$arrMeta['engine']}',");
         $objFile->append("\t'charset' => '{$arrMeta['charset']}',");
         $objFile->append(');', "\n\n");
         // Fields
         $arrFields = $objExtract->getFields();
         $objFile->append("\$this->arrFields = array\n(");
         foreach ($arrFields as $field => $sql) {
             $sql = str_replace('"', '\\"', $sql);
             $objFile->append("\t'{$field}' => \"{$sql}\",");
         }
         $objFile->append(');', "\n\n");
         // Order fields
         $arrFields = $objExtract->getOrderFields();
         $objFile->append("\$this->arrOrderFields = array\n(");
         foreach ($arrFields as $field) {
             $objFile->append("\t'{$field}',");
         }
         $objFile->append(');', "\n\n");
         // Keys
         $arrKeys = $objExtract->getKeys();
         $objFile->append("\$this->arrKeys = array\n(");
         foreach ($arrKeys as $field => $type) {
             $objFile->append("\t'{$field}' => '{$type}',");
         }
         $objFile->append(');', "\n\n");
         // Relations
         $arrRelations = $objExtract->getRelations();
         $objFile->append("\$this->arrRelations = array\n(");
         foreach ($arrRelations as $field => $config) {
             $objFile->append("\t'{$field}' => array\n\t(");
             foreach ($config as $k => $v) {
                 $objFile->append("\t\t'{$k}' => '{$v}',");
             }
             $objFile->append("\t),");
         }
         $objFile->append(');', "\n\n");
         // Set the database table flag
         $objFile->append("\$this->blnIsDbTable = true;", "\n");
         // Close the file (moves it to its final destination)
         $objFile->close();
     }
     // Add a log entry
     $this->log('Generated the DCA extracts', __METHOD__, TL_CRON);
 }