[ Index ]

PHP Cross Reference of phpBB-3.3.7-deutsch

title

Body

[close]

/vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/LazyLoadingGhost/MethodGenerator/ -> CallInitializer.php (source)

   1  <?php
   2  /*
   3   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   4   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   5   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   6   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   7   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   8   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   9   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14   *
  15   * This software consists of voluntary contributions made by many individuals
  16   * and is licensed under the MIT license.
  17   */
  18  
  19  declare(strict_types=1);
  20  
  21  namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
  22  
  23  use ProxyManager\Generator\MethodGenerator;
  24  use Zend\Code\Generator\ParameterGenerator;
  25  use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
  26  use ProxyManager\ProxyGenerator\Util\Properties;
  27  use ReflectionProperty;
  28  use Zend\Code\Generator\PropertyGenerator;
  29  
  30  /**
  31   * Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::isProxyInitialized}
  32   * for lazy loading value holder objects
  33   *
  34   * @author Marco Pivetta <ocramius@gmail.com>
  35   * @license MIT
  36   */
  37  class CallInitializer extends MethodGenerator
  38  {
  39      /**
  40       * Constructor
  41       *
  42       * @param PropertyGenerator $initializerProperty
  43       * @param PropertyGenerator $initTracker
  44       * @param Properties        $properties
  45       */
  46      public function __construct(
  47          PropertyGenerator $initializerProperty,
  48          PropertyGenerator $initTracker,
  49          Properties $properties
  50      ) {
  51          $docBlock = <<<'DOCBLOCK'
  52  Triggers initialization logic for this ghost object
  53  
  54  @param string  $methodName
  55  @param mixed[] $parameters
  56  
  57  @return mixed
  58  DOCBLOCK;
  59  
  60          parent::__construct(
  61              UniqueIdentifierGenerator::getIdentifier('callInitializer'),
  62              [
  63                  new ParameterGenerator('methodName'),
  64                  new ParameterGenerator('parameters', 'array'),
  65              ],
  66              static::FLAG_PRIVATE,
  67              null,
  68              $docBlock
  69          );
  70  
  71          $initializer    = $initializerProperty->getName();
  72          $initialization = $initTracker->getName();
  73  
  74          $bodyTemplate = <<<'PHP'
  75  if ($this->%s || ! $this->%s) {
  76      return;
  77  }
  78  
  79  $this->%s = true;
  80  
  81  %s
  82  %s
  83  
  84  $result = $this->%s->__invoke($this, $methodName, $parameters, $this->%s, $properties);
  85  $this->%s = false;
  86  
  87  return $result;
  88  PHP;
  89  
  90          $this->setBody(sprintf(
  91              $bodyTemplate,
  92              $initialization,
  93              $initializer,
  94              $initialization,
  95              $this->propertiesInitializationCode($properties),
  96              $this->propertiesReferenceArrayCode($properties),
  97              $initializer,
  98              $initializer,
  99              $initialization
 100          ));
 101      }
 102  
 103      private function propertiesInitializationCode(Properties $properties) : string
 104      {
 105          $assignments = [];
 106  
 107          foreach ($properties->getAccessibleProperties() as $property) {
 108              $assignments[] = '$this->'
 109                  . $property->getName()
 110                  . ' = ' . $this->getExportedPropertyDefaultValue($property)
 111                  . ';';
 112          }
 113  
 114          foreach ($properties->getGroupedPrivateProperties() as $className => $privateProperties) {
 115              $cacheKey      = 'cache' . str_replace('\\', '_', $className);
 116              $assignments[] = 'static $' . $cacheKey . ";\n\n"
 117                  . '$' . $cacheKey . ' ?: $' . $cacheKey . " = \\Closure::bind(function (\$instance) {\n"
 118                  . $this->getPropertyDefaultsAssignments($privateProperties) . "\n"
 119                  . '}, null, ' . var_export($className, true) . ");\n\n"
 120                  . '$' . $cacheKey . "(\$this);\n\n";
 121          }
 122  
 123          return implode("\n", $assignments) . "\n\n";
 124      }
 125  
 126      /**
 127       * @param ReflectionProperty[] $properties
 128       *
 129       * @return string
 130       */
 131      private function getPropertyDefaultsAssignments(array $properties) : string
 132      {
 133          return implode(
 134              "\n",
 135              array_map(
 136                  function (ReflectionProperty $property) : string {
 137                      return '    $instance->' . $property->getName()
 138                          . ' = ' . $this->getExportedPropertyDefaultValue($property) . ';';
 139                  },
 140                  $properties
 141              )
 142          );
 143      }
 144  
 145      private function propertiesReferenceArrayCode(Properties $properties) : string
 146      {
 147          $assignments = [];
 148  
 149          foreach ($properties->getAccessibleProperties() as $propertyInternalName => $property) {
 150              $assignments[] = '    '
 151                  . var_export($propertyInternalName, true) . ' => & $this->' . $property->getName()
 152                  . ',';
 153          }
 154  
 155          $code = "\$properties = [\n" . implode("\n", $assignments) . "\n];\n\n";
 156  
 157          // must use assignments, as direct reference during array definition causes a fatal error (not sure why)
 158          foreach ($properties->getGroupedPrivateProperties() as $className => $classPrivateProperties) {
 159              $cacheKey  = 'cacheFetch' . str_replace('\\', '_', $className);
 160  
 161              $code .= 'static $' . $cacheKey . ";\n\n"
 162                  . '$' . $cacheKey . ' ?: $' . $cacheKey
 163                  . " = \\Closure::bind(function (\$instance, array & \$properties) {\n"
 164                  . $this->generatePrivatePropertiesAssignmentsCode($classPrivateProperties)
 165                  . "}, \$this, " . var_export($className, true) . ");\n\n"
 166                  . '$' . $cacheKey . "(\$this, \$properties);";
 167          }
 168  
 169          return $code;
 170      }
 171  
 172      /**
 173       * @param ReflectionProperty[] $properties indexed by internal name
 174       *
 175       * @return string
 176       */
 177      private function generatePrivatePropertiesAssignmentsCode(array $properties) : string
 178      {
 179          $code = '';
 180  
 181          foreach ($properties as $property) {
 182              $key   = "\0" . $property->getDeclaringClass()->getName() . "\0" . $property->getName();
 183              $code .= '    $properties[' . var_export($key, true) . '] = '
 184                  . '& $instance->' . $property->getName() . ";\n";
 185          }
 186  
 187          return $code;
 188      }
 189  
 190      private function getExportedPropertyDefaultValue(ReflectionProperty $property) : string
 191      {
 192          $name     = $property->getName();
 193          $defaults = $property->getDeclaringClass()->getDefaultProperties();
 194  
 195          return var_export($defaults[$name] ?? null, true);
 196      }
 197  }


Generated: Thu Mar 24 21:31:15 2022 Cross-referenced by PHPXref 0.7.1