vendor/pimcore/pimcore/lib/Model/AbstractModel.php line 257

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Model;
  15. use Pimcore\Logger;
  16. use Pimcore\Model\DataObject\Traits\ObjectVarTrait;
  17. /**
  18.  * @method void beginTransaction()
  19.  * @method void commit()
  20.  * @method void rollBack()
  21.  * @method void configure()
  22.  * @method array getValidTableColumns(string $table, bool $cache)
  23.  * @method void resetValidTableColumnsCache(string $table)
  24.  */
  25. abstract class AbstractModel implements ModelInterface
  26. {
  27.     use ObjectVarTrait;
  28.     /**
  29.      * @var \Pimcore\Model\Dao\AbstractDao|null
  30.      */
  31.     protected $dao;
  32.     /**
  33.      * @var array
  34.      */
  35.     private static $daoClassCache = [];
  36.     /**
  37.      * @var array|null
  38.      */
  39.     private static $daoClassMap null;
  40.     /**
  41.      * @return \Pimcore\Model\Dao\AbstractDao
  42.      */
  43.     public function getDao()
  44.     {
  45.         if (!$this->dao) {
  46.             $this->initDao();
  47.         }
  48.         return $this->dao;
  49.     }
  50.     /**
  51.      * @param \Pimcore\Model\Dao\AbstractDao|null $dao
  52.      *
  53.      * @return self
  54.      */
  55.     public function setDao($dao)
  56.     {
  57.         $this->dao $dao;
  58.         return $this;
  59.     }
  60.     /**
  61.      * @param string|null $key
  62.      * @param bool $forceDetection
  63.      *
  64.      * @throws \Exception
  65.      */
  66.     public function initDao($key null$forceDetection false)
  67.     {
  68.         $myClass get_class($this);
  69.         $cacheKey $myClass . ($key ? ('-' $key) : '');
  70.         $dao null;
  71.         $myClass $key $key $myClass;
  72.         if (null === self::$daoClassMap) {
  73.             // static classmap is generated by command: ./bin/console internal:model-dao-mapping-generator
  74.             self::$daoClassMap = include(__DIR__ '/../../config/dao-classmap.php');
  75.         }
  76.         if (!$forceDetection && array_key_exists($cacheKeyself::$daoClassCache)) {
  77.             $dao self::$daoClassCache[$cacheKey];
  78.         } elseif (!$key || $forceDetection) {
  79.             if (isset(self::$daoClassMap[$myClass])) {
  80.                 $dao self::$daoClassMap[$myClass];
  81.             } else {
  82.                 $dao self::locateDaoClass($myClass);
  83.             }
  84.         } else {
  85.             $delimiter '_'// old prefixed class style
  86.             if (str_contains($key'\\') !== false) {
  87.                 $delimiter '\\'// that's the new with namespaces
  88.             }
  89.             $dao $key $delimiter 'Dao';
  90.         }
  91.         if (!$dao) {
  92.             Logger::critical('No dao implementation found for: ' $myClass);
  93.             throw new \Exception('No dao implementation found for: ' $myClass);
  94.         }
  95.         self::$daoClassCache[$cacheKey] = $dao;
  96.         $dao '\\' ltrim($dao'\\');
  97.         $this->dao = new $dao();
  98.         $this->dao->setModel($this);
  99.         $this->dao->configure();
  100.         if (method_exists($this->dao'init')) {
  101.             $this->dao->init();
  102.         }
  103.     }
  104.     /**
  105.      * @param string $modelClass
  106.      *
  107.      * @return string|null
  108.      */
  109.     public static function locateDaoClass($modelClass)
  110.     {
  111.         $forbiddenClassNames = ['Pimcore\\Resource'];
  112.         $classes class_parents($modelClass);
  113.         array_unshift($classes$modelClass);
  114.         foreach ($classes as $class) {
  115.             $delimiter '_'// old prefixed class style
  116.             if (strpos($class'\\')) {
  117.                 $delimiter '\\'// that's the new with namespaces
  118.             }
  119.             $classParts explode($delimiter$class);
  120.             $length count($classParts);
  121.             $daoClass null;
  122.             for ($i 0$i $length$i++) {
  123.                 $classNames = [
  124.                     implode($delimiter$classParts) . $delimiter 'Dao',
  125.                     implode($delimiter$classParts) . $delimiter 'Resource',
  126.                 ];
  127.                 foreach ($classNames as $tmpClassName) {
  128.                     if (class_exists($tmpClassName) && !in_array($tmpClassName$forbiddenClassNames)) {
  129.                         $daoClass $tmpClassName;
  130.                         break;
  131.                     }
  132.                 }
  133.                 if ($daoClass) {
  134.                     break;
  135.                 }
  136.                 array_pop($classParts);
  137.             }
  138.             if ($daoClass) {
  139.                 return $daoClass;
  140.             }
  141.         }
  142.         return null;
  143.     }
  144.     /**
  145.      * @param array $data
  146.      *
  147.      * @return $this
  148.      */
  149.     public function setValues($data = [])
  150.     {
  151.         if (is_array($data) && count($data) > 0) {
  152.             foreach ($data as $key => $value) {
  153.                 $this->setValue($key$value);
  154.             }
  155.         }
  156.         return $this;
  157.     }
  158.     /**
  159.      * @param string $key
  160.      * @param mixed $value
  161.      *
  162.      * @return $this
  163.      */
  164.     public function setValue($key$value)
  165.     {
  166.         $method 'set' $key;
  167.         if (strcasecmp($method__FUNCTION__) !== 0) {
  168.             if (method_exists($this$method)) {
  169.                 $this->$method($value);
  170.             } elseif (method_exists($this'set' preg_replace('/^o_/'''$key))) {
  171.                 // compatibility mode for objects (they do not have any set_oXyz() methods anymore)
  172.                 $this->$method($value);
  173.             }
  174.         }
  175.         return $this;
  176.     }
  177.     /**
  178.      * @return array
  179.      */
  180.     public function __sleep()
  181.     {
  182.         $blockedVars = ['dao''o_dirtyFields''activeDispatchingEvents'];
  183.         $vars get_object_vars($this);
  184.         return array_diff(array_keys($vars), $blockedVars);
  185.     }
  186.     /**
  187.      * @param string $method
  188.      * @param array $args
  189.      *
  190.      * @return mixed
  191.      *
  192.      * @throws \Exception
  193.      */
  194.     public function __call($method$args)
  195.     {
  196.         // protected / private methods shouldn't be delegated to the dao -> this can have dangerous effects
  197.         if (!is_callable([$this$method])) {
  198.             throw new \Exception("Unable to call private/protected method '" $method "' on object " get_class($this));
  199.         }
  200.         // check if the method is defined in ´dao
  201.         if (method_exists($this->getDao(), $method)) {
  202.             try {
  203.                 $r call_user_func_array([$this->getDao(), $method], $args);
  204.                 return $r;
  205.             } catch (\Exception $e) {
  206.                 Logger::emergency((string) $e);
  207.                 throw $e;
  208.             }
  209.         } else {
  210.             Logger::error('Class: ' get_class($this) . ' => call to undefined method ' $method);
  211.             throw new \Exception('Call to undefined method ' $method ' in class ' get_class($this));
  212.         }
  213.     }
  214.     public function __clone()
  215.     {
  216.         $this->dao null;
  217.     }
  218.     /**
  219.      * @return array
  220.      */
  221.     public function __debugInfo()
  222.     {
  223.         $result get_object_vars($this);
  224.         unset($result['dao']);
  225.         return $result;
  226.     }
  227.     /**
  228.      * @return Factory
  229.      */
  230.     protected static function getModelFactory()
  231.     {
  232.         return \Pimcore::getContainer()->get('pimcore.model.factory');
  233.     }
  234.     /**
  235.      * @internal
  236.      *
  237.      * @param array $data
  238.      *
  239.      * @throws \Exception
  240.      */
  241.     protected static function checkCreateData(array $data)
  242.     {
  243.         if (isset($data['id'])) {
  244.             throw new \Exception(sprintf('Calling %s including `id` key in the data-array is not supported, use setId() instead.'__METHOD__));
  245.         }
  246.     }
  247. }