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

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