protected function hash($fqn, $uniqueData)
 {
     asort($uniqueData);
     return $fqn . '__' . A::implode($uniqueData, ',', function ($value, $field) {
         return $field . ':' . $value;
     });
 }
    public function run()
    {
        if (!isset($this->changes) || !is_array($this->changes)) {
            throw new \InvalidArgumentException('changes muss gesetzt sein');
        }
        if (!$this->changelog->exists()) {
            throw new \RuntimeException('changelogFile ' . $targetFile . ' muss existieren');
        }
        require $this->changelog;
        /* changeslist : 
           
           'bugfix: Im Sound Content stand nur "content" statt dem eigentlichen Soundtext',
           'geändert: Bei der Soundsuche wird bei sehr großen Results das Ergebnis auf 15 Einträge eingeschränkt'
           
           */
        /* version */
        //2.0.9-Beta
        $version = \Psc\Preg::qmatch($data[0]['version'], '/^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\-(Alpha|Beta|Gamma)$/i', array(1, 2, 3, 4));
        if (!is_array($version)) {
            throw new \RuntimeException('Fehler beim Version Parsing. Alte Version ' . $oldVersion);
        }
        if ($this->versionIncrement === 'minor') {
            $version[2]++;
        } else {
            throw new \InvalidArgumentException('Kann nichts anderes als minor für versionIncrement');
        }
        $newVersion = vsprintf('%d.%d.%d-%s', $version);
        $php = <<<'PHP'
$data[] = array(
  'version'=>'%version%',
  'time'=>'%time%',
  'changelog'=>array(
    %changesList%
  )
);

PHP;
        $php = \Psc\TPL\TPL::miniTemplate($php, array('version' => $newVersion, 'time' => date('H:i d.m.Y'), 'changesList' => \Webforge\Common\ArrayUtil::implode($this->changes, ",\n    ", function ($change) {
            return var_export($change, true);
        })));
        $contents = $this->changelog->getContents();
        $pos = mb_strpos($contents, $needle = '$data = array();' . "\n");
        if ($pos === FALSE) {
            throw new \RuntimeException('Cannot Modify File: ' . \Webforge\Common\String::cutAt($contents, 300) . ' enhält nicht ' . $needle);
        }
        $pos += mb_strlen($needle);
        $contents = mb_substr($contents, 0, $pos) . $php . "\n" . mb_substr($contents, $pos);
        $this->changelog->writeContents($contents);
    }
Exemple #3
0
 /**
  * @var mixed $print Closure|String wenn ein String wird dies als Attribute gesehen welches mit get$print() vom Objekt geladen werden kann
  */
 public static function listStrings($collection, $sep = ', ', $andsep = NULL, Closure $formatter = NULL)
 {
     $collection = Code::castArray($collection);
     $cnt = count($collection);
     if (isset($andsep) && $cnt >= 2) {
         $last = array_pop($collection);
     } else {
         $andsep = NULL;
     }
     $formatter = $formatter ?: function ($item) {
         return (string) $item;
     };
     $ret = A::implode($collection, $sep, $formatter);
     if (isset($andsep) && $last != NULL) {
         $ret .= $andsep . $formatter($last);
     }
     return $ret;
 }
Exemple #4
0
    protected function compileClosure(GMethod $method, $closureName)
    {
        // wir erzeugen sowas hier (ohne semikolon am ende)
        /*
          parameter von $funcName sind $name und $type
         
          $funcName = function ($name, $type) use ($that) {
            return $that->funcName($name, $type);
          }
        */
        $code = <<<'PHP'
$%closureName% = function (%parameters%) use ($that) {
  return $that->%method%(%callParameters%);
}
PHP;
        $codeWithFuncArgs = <<<'PHP'
$%closureName% = function () use ($that) {
  return call_user_func_array(array($that, '%method%'), func_get_args());
}
PHP;
        // wenn die innere funktion func_get_args() benutzt, müssen wir call_user_func nehmen ($codeWithFuncArgs)
        if (mb_strpos($method->getBody(), 'func_get_args()')) {
            // das ist natürlich nicht so schön als entscheidung, aber false positive macht nichts (außer bissl performance)
            $code = $codeWithFuncArgs;
            $parameters = $callParameters = NULL;
        } else {
            // kopiert von GFunction
            $parameters = \Webforge\Common\ArrayUtil::implode($method->getParameters(), ', ', function ($parameter) {
                return $parameter->php($useFQNHints = TRUE);
            });
            $callParameters = \Webforge\Common\ArrayUtil::implode($method->getParameters(), ', ', function ($parameter) {
                // für die 2ten parameter entfernen wir alle hints, damit wir nur die parameter auflistungen haben
                $parameter = clone $parameter;
                $parameter->setHint(NULL);
                $parameter->setArray(FALSE);
                $parameter->setDefault(GParameter::UNDEFINED);
                return $parameter->php();
            });
        }
        $code = \Psc\TPL\TPL::miniTemplate($code, array('parameters' => $parameters, 'callParameters' => $callParameters, 'method' => $method->getName(), 'closureName' => $closureName));
        return $code;
    }
Exemple #5
0
 public function compile()
 {
     $gClass = new \Psc\Code\Generate\GClass(\Psc\Code\Code::getClass($this));
     $gClass->elevateClass();
     $this->log('compiling ProjectEntities:');
     foreach ($gClass->getMethods() as $method) {
         if (\Psc\Preg::match($method->getName(), '/^compile[a-z0-9A-Z_]+$/') && $method->isPublic()) {
             $this->modelCompiler = NULL;
             // neuen erzeugen damit flags resetted werden, etc
             $m = $method->getName();
             $this->log('  ' . $m . ':');
             try {
                 $out = $this->{$m}($this->getModelCompiler());
             } catch (\Doctrine\DBAL\DBALException $e) {
                 if (mb_strpos($e->getMessage(), 'Unknown column type') !== FALSE) {
                     $types = A::implode(\Doctrine\DBAL\Types\Type::getTypesMap(), "\n", function ($fqn, $type) {
                         return $type . "\t\t" . ': ' . $fqn;
                     });
                     throw new \Psc\Exception('Database Error: Unknown Column Type: types are: ' . "\n" . $types, $e->getCode(), $e);
                 }
                 throw $e;
             } catch (\Exception $e) {
                 $this->log('    Fehler beim Aufruf von ' . $m);
                 throw $e;
             }
             if ($out instanceof \Webforge\Common\System\File) {
                 $this->log('    ' . $out . ' geschrieben');
             } elseif (is_array($out)) {
                 foreach ($out as $file) {
                     $this->log('    ' . $file . ' geschrieben');
                 }
             } elseif ($out instanceof \Psc\Doctrine\EntityBuilder) {
                 $this->log('    ' . $out->getWrittenFile() . ' geschrieben');
             }
         }
     }
     $this->log('finished.');
     return $this;
 }
Exemple #6
0
 public function generatePHP(array $imports = array())
 {
     if (!isset($this->gClass)) {
         throw new ClassWritingException('Klasse nicht gesetzt. (zuerst setClass() dann write().');
     }
     $use = NULL;
     /* merge mit params */
     foreach ($imports as $iClass) {
         $alias = NULL;
         if (is_array($iClass)) {
             list($iClass, $alias) = $iClass;
         }
         if (!$iClass instanceof GClass) {
             throw new \Psc\Exception('Imports können nur vom typ GClass sein');
         }
         $this->addImport($iClass, $alias);
     }
     if (count($this->foundImports) > 0) {
         $useImports = array();
         foreach ($this->foundImports as $alias => $gClass) {
             // wir filten nach den imports, die im selben Namespace sind und keinen besonderen Alias haben
             if ($alias !== $gClass->getClassName() || $gClass->getNamespace() !== $this->gClass->getNamespace()) {
                 $useImports[$alias] = $gClass;
             }
         }
         /* Render PHP */
         $classAlias = function ($gClass, $alias) {
             if ($alias === $gClass->getClassName()) {
                 return $gClass->getFQN();
             } else {
                 return $gClass->getFQN() . ' AS ' . $alias;
             }
         };
         if (count($useImports) > 0) {
             $use .= "\n";
             // abstand zu namespace (neue Zeile)
             if ($this->useStyle === self::USE_STYLE_LINES) {
                 $use .= A::joinc($useImports, "use %s;\n", $classAlias);
             } else {
                 $use .= 'use ' . A::implode($useImports, ",\n    ", $classAlias);
                 $use .= ';';
                 $use .= "\n";
                 // abstand zu class (neue Zeile)
             }
         }
     }
     $php = TPL::miniTemplate($this->template, array('class' => $this->gClass->php(), 'use' => $use, 'namespace' => $this->gClass->getNamespace() != NULL ? 'namespace ' . ltrim($this->gClass->getNamespace(), '\\') . ';' : NULL));
     return $php;
 }
Exemple #7
0
 protected static function buildRequirements(array $requirements)
 {
     return A::implode($requirements, ', ', function ($requirement) {
         return sprintf("'%s'", $requirement);
     });
 }
Exemple #8
0
 public function getParametersString()
 {
     $php = '(';
     $php .= A::implode($this->getParameters(), ', ', function ($parameter) {
         return $parameter->php();
     });
     $php .= ')';
     return $php;
 }
Exemple #9
0
 /**
  * Sucht den ersten der Services, der den Request bearbeiten will
  * 
  * @throws NoServiceFoundException
  */
 public function findService(ServiceRequest $serviceRequest)
 {
     $this->log('Find Services..');
     foreach ($this->services as $service) {
         $this->log('Service: ' . Code::getClass($service) . '::isResponsibleFor');
         if ($service->isResponsibleFor($serviceRequest)) {
             $this->log('ok: Service übernimmt den Request');
             return $service;
         }
     }
     throw NoServiceFoundException::build('Es konnte kein passender Service ermittelt werden. Es wurden %d Services (%s) befragt.', count($this->services), \Webforge\Common\ArrayUtil::implode($this->services, ', ', function ($svc) {
         return Code::getClass($svc);
     }))->set('serviceRequest', $serviceRequest)->end();
 }
Exemple #10
0
 /**
  * Gibt die Klasse als PHP Code zurück
  *
  * die Klasse ist noch nicht mit Namespace vor class notiert!
  * Eingerückt wird mit 2 whitespaces.
  * Em Ende befindet sich hinter der schließenden Klammer ein LF
  */
 public function php()
 {
     $cr = "\n";
     $php = $this->phpDocBlock(0);
     $ms = array(self::MODIFIER_ABSTRACT => 'abstract', self::MODIFIER_FINAL => 'final');
     foreach ($ms as $const => $modifier) {
         if (($const & $this->modifiers) == $const) {
             $php .= $modifier . ' ';
         }
     }
     $php .= 'class ' . $this->getClassName() . ' ';
     /* Extends */
     if (isset($this->parentClass)) {
         if ($this->parentClass->getNamespace() === $this->getNamespace()) {
             $php .= 'extends ' . $this->parentClass->getClassName() . ' ';
             // don't prefix namespace
         } else {
             $php .= 'extends ' . '\\' . $this->parentClass->getFQN() . ' ';
         }
     }
     /* Interfaces */
     if (count($this->getInterfaces()) > 0) {
         $php .= 'implements ';
         $that = $this;
         $php .= A::implode($this->getInterfaces(), ', ', function (GClass $iClass) use($that) {
             if ($that->getNamespace() === $iClass->getNamespace()) {
                 return $iClass->getClassName();
             } else {
                 return '\\' . $iClass->getFQN();
             }
         });
         $php .= ' ';
     }
     $php .= '{' . $cr;
     /* Die Funktionen machen immer den Abstand nach oben. Also vor jedem Property und jeder Methode macht dies ein "\n" */
     /* Constants */
     $php .= A::joinc($this->getConstants(), '  ' . $cr . '%s;' . $cr, function ($constant) {
         return $constant->php(2);
     });
     /* Properties */
     $php .= A::joinc($this->getProperties(), '  ' . $cr . '%s;' . $cr, function ($property) {
         return $property->php(2);
         // hier jetzt auch wegen DocBlock einrücken
     });
     /* Methods */
     $php .= A::joinc($this->getMethods(), '  ' . $cr . '%s' . $cr, function ($method) {
         return $method->php(2);
         // rückt selbst zwischen den Klammern ein, aber wir wollen ja den body z.b. auf 4 haben nicht auf 2
     });
     $php .= '}';
     // kein umbruch hinten, immer abstand nach oben!
     return $php;
 }
Exemple #11
0
 public static function debugCollection($collection, $glue = "\n", $label = NULL)
 {
     $ret = $label ? 'Collection ' . $label . $glue : NULL;
     if (count($collection) === 0) {
         $ret .= '[leere Collection]';
     } else {
         $ret .= \Webforge\Common\ArrayUtil::implode(Code::castArray($collection), $glue, function ($item, $key) {
             return sprintf('[%s] %s', $key, \Psc\Doctrine\Helper::debugEntity($item));
         });
     }
     return $ret;
 }
Exemple #12
0
 public static function convertToId($name)
 {
     if (is_array($name)) {
         return A::implode($name, '-', function ($part) {
             return is_array($part) ? 'Array' : $part;
         });
     }
     return $name;
 }