Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

CallInitializer.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 5.62 KiB


001  <?php
002   
003  declare(strict_types=1);
004   
005  namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
006   
007  use ProxyManager\Generator\MethodGenerator;
008  use ProxyManager\Generator\Util\IdentifierSuffixer;
009  use ProxyManager\ProxyGenerator\Util\Properties;
010  use ReflectionProperty;
011  use Zend\Code\Generator\ParameterGenerator;
012  use Zend\Code\Generator\PropertyGenerator;
013   
014  /**
015   * Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::isProxyInitialized}
016   * for lazy loading value holder objects
017   *
018   * @author Marco Pivetta <ocramius@gmail.com>
019   * @license MIT
020   */
021  class CallInitializer extends MethodGenerator
022  {
023      /**
024       * Constructor
025       *
026       * @param PropertyGenerator $initializerProperty
027       * @param PropertyGenerator $initTracker
028       * @param Properties        $properties
029       */
030      public function __construct(
031          PropertyGenerator $initializerProperty,
032          PropertyGenerator $initTracker,
033          Properties $properties
034      ) {
035          $docBlock = <<<'DOCBLOCK'
036  Triggers initialization logic for this ghost object
037   
038  @param string  $methodName
039  @param mixed[] $parameters
040   
041  @return mixed
042  DOCBLOCK;
043   
044   
045          parent::__construct(
046              IdentifierSuffixer::getIdentifier('callInitializer'),
047              [
048                  new ParameterGenerator('methodName'),
049                  new ParameterGenerator('parameters', 'array'),
050              ],
051              static::FLAG_PRIVATE,
052              null,
053              $docBlock
054          );
055   
056          $initializer    = $initializerProperty->getName();
057          $initialization = $initTracker->getName();
058   
059          $bodyTemplate = <<<'PHP'
060  if ($this->%s || ! $this->%s) {
061      return;
062  }
063   
064  $this->%s = true;
065   
066  %s
067  %s
068   
069  $result = $this->%s->__invoke($this, $methodName, $parameters, $this->%s, $properties);
070  $this->%s = false;
071   
072  return $result;
073  PHP;
074   
075   
076          $this->setBody(sprintf(
077              $bodyTemplate,
078              $initialization,
079              $initializer,
080              $initialization,
081              $this->propertiesInitializationCode($properties),
082              $this->propertiesReferenceArrayCode($properties),
083              $initializer,
084              $initializer,
085              $initialization
086          ));
087      }
088   
089      private function propertiesInitializationCode(Properties $properties) : string
090      {
091          $assignments = [];
092   
093          foreach ($properties->getAccessibleProperties() as $property) {
094              $assignments[] = '$this->'
095                  . $property->getName()
096                  . ' = ' . $this->getExportedPropertyDefaultValue($property)
097                  . ';';
098          }
099   
100          foreach ($properties->getGroupedPrivateProperties() as $className => $privateProperties) {
101              $cacheKey      = 'cache' . str_replace('\\', '_', $className);
102              $assignments[] = 'static $' . $cacheKey . ";\n\n"
103                  . '$' . $cacheKey . ' ?: $' . $cacheKey . " = \\Closure::bind(function (\$instance) {\n"
104                  . $this->getPropertyDefaultsAssignments($privateProperties) . "\n"
105                  . '}, null, ' . var_export($className, true) . ");\n\n"
106                  . '$' . $cacheKey . "(\$this);\n\n";
107          }
108   
109          return implode("\n", $assignments) . "\n\n";
110      }
111   
112      /**
113       * @param ReflectionProperty[] $properties
114       */
115      private function getPropertyDefaultsAssignments(array $properties) : string
116      {
117          return implode(
118              "\n",
119              array_map(
120                  function (ReflectionProperty $property) : string {
121                      return '    $instance->' . $property->getName()
122                          . ' = ' . $this->getExportedPropertyDefaultValue($property) . ';';
123                  },
124                  $properties
125              )
126          );
127      }
128   
129      private function propertiesReferenceArrayCode(Properties $properties) : string
130      {
131          $assignments = [];
132   
133          foreach ($properties->getAccessibleProperties() as $propertyInternalName => $property) {
134              $assignments[] = '    '
135                  . var_export($propertyInternalName, true) . ' => & $this->' . $property->getName()
136                  . ',';
137          }
138   
139          $code = "\$properties = [\n" . implode("\n", $assignments) . "\n];\n\n";
140   
141          // must use assignments, as direct reference during array definition causes a fatal error (not sure why)
142          foreach ($properties->getGroupedPrivateProperties() as $className => $classPrivateProperties) {
143              $cacheKey  = 'cacheFetch' . str_replace('\\', '_', $className);
144   
145              $code .= 'static $' . $cacheKey . ";\n\n"
146                  . '$' . $cacheKey . ' ?: $' . $cacheKey
147                  . " = \\Closure::bind(function (\$instance, array & \$properties) {\n"
148                  . $this->generatePrivatePropertiesAssignmentsCode($classPrivateProperties)
149                  . "}, \$this, " . var_export($className, true) . ");\n\n"
150                  . '$' . $cacheKey . "(\$this, \$properties);";
151          }
152   
153          return $code;
154      }
155   
156      /**
157       * @param ReflectionProperty[] $properties indexed by internal name
158       *
159       * @return string
160       */
161      private function generatePrivatePropertiesAssignmentsCode(array $properties) : string
162      {
163          $code = '';
164   
165          foreach ($properties as $property) {
166              $key   = "\0" . $property->getDeclaringClass()->getName() . "\0" . $property->getName();
167              $code .= '    $properties[' . var_export($key, true) . '] = '
168                  . '& $instance->' . $property->getName() . ";\n";
169          }
170   
171          return $code;
172      }
173   
174      private function getExportedPropertyDefaultValue(ReflectionProperty $property) : string
175      {
176          $name     = $property->getName();
177          $defaults = $property->getDeclaringClass()->getDefaultProperties();
178   
179          return var_export($defaults[$name] ?? null, true);
180      }
181  }
182