作者:pschei
项目:psc-cm
/**
* Überprüft die Daten anhand der Constraints und fügt die Daten zum Index hinzu
*
* Schmeisst eine Exception wenn die daten bereits im Index sind
* diese Exception wird mit duplicateIdentifier gesetzt, wenn in $data der key 'identifier' für den vorigen Index-Eintrag gesetzt war
*/
public function process(array $data)
{
foreach ($this->uniqueConstraints as $constraint) {
$constraintValue = array();
foreach ($constraint->getKeys() as $key) {
// da wir diese reihenfolge nehmen, ist diese immer gleich
$type = $constraint->getKeyType($key);
if (!array_key_exists($key, $data)) {
throw new WrongDataException(sprintf("In Data ist der Schlüssel '%s' nicht vorhanden. Erwartet: '%s'", $key, $type->getName()));
}
$value = $data[$key];
if (!$this->typeMatcher->isTypeof($value, $type)) {
$e = new TypeExpectedException(sprintf("Data %s für Key: '%s' sollte vom Type '%s' sein", \Psc\Code\Code::varInfo($value), $key, $type->getName()));
$e->expectedType = $type;
throw $e;
}
$constraintValue[$key] = $value;
}
// schlüssel darf es nicht geben, wert nicht gesetzt kann es nicht geben
if (($indexEntry = $this->index->get($constraintValue, FALSE, DataInput::THROW_EXCEPTION)) === FALSE) {
// ok: nicht im index => zum index hinzufügen
$this->index->set($constraintValue, array_key_exists('identifier', $data) ? $data['identifier'] : TRUE);
} else {
throw UniqueConstraintException::factory($constraint->getName(), $this->getStringValue($constraintValue), $constraintValue, !is_bool($indexEntry) ? $indexEntry : NULL);
}
}
}
作者:pschei
项目:psc-cm
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (!in_array($value, $this->getValues())) {
throw new \InvalidArgumentException("Invalid '" . $this->name . "' value " . \Psc\Code\Code::varInfo($value) . ' Erlaubt sind: ' . \Psc\Code\Code::varInfo($this->values));
}
return $value;
}
作者:pschei
项目:psc-cm
public function createComponent($class)
{
$class = Code::expandNamespace($class, 'Psc\\UI\\Component');
$component = new $class();
$this->manager->dispatchEvent(self::EVENT_COMPONENT_CREATED, array('component' => $component, 'componentClass' => $class), $this);
return $component;
}
作者:pschei
项目:psc-cm
public function matchIValue($value)
{
if (($p = mb_strtolower($this->part())) === $value) {
return $this->success($p);
}
$this->fail($p . ' matched ' . Code::varInfo($value) . ' nicht');
}
作者:pschei
项目:psc-cm
public function __construct(array $buttons, TranslationContainer $translationContainer, $flags = NULL)
{
$this->translationContainer = $translationContainer;
$this->buttons = array();
foreach ($buttons as $button) {
if ($button === 'save') {
$this->addSaveButton();
} elseif ($button === 'insert-open') {
$this->addInsertOpenButton();
} elseif ($button === 'save-close') {
$this->addSaveCloseButton();
} elseif ($button === 'insert-close') {
$this->addInsertCloseButton();
} elseif ($button === 'insert') {
$this->addInsertButton();
} elseif ($button === 'reload') {
$this->addReloadButton();
} elseif ($button === 'reset') {
$this->addResetButton();
} elseif ($button === 'view') {
$this->addViewButton();
} elseif ($button === 'preview') {
$this->addPreviewButton();
} elseif ($button instanceof \Psc\UI\Button) {
$this->buttons[] = $button;
} else {
throw new \InvalidArgumentException('Unbekannter Parameter in array $buttons (1. Parameter) : ' . Code::varInfo($button));
}
}
if ($flags === NULL) {
$this->flags = self::ALIGN_RIGHT | self::CLEAR;
} else {
$this->flags = $flags;
}
}
作者:pschei
项目:psc-cm
protected function log(\Exception $e, $contextInfo = NULL)
{
if ($e instanceof \ErrorException) {
$errorType = self::$errors[$e->getSeverity()];
} else {
$errorType = Code::getClass($e);
}
// wir müssen hier den error selbst loggen, da php nichts mehr macht (die faule banane)
$php = NULL;
$php .= 'PHP ' . $errorType . ': ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine() . "\n";
$php .= $errorType . ': ' . \Psc\Exception::getExceptionText($e, 'text') . "\n";
error_log($php, 0);
/* Debug-Mail */
$debug = NULL;
$debug .= '[' . date('d.M.Y H:i:s') . "] ";
$debug .= $errorType . ': ' . \Psc\Exception::getExceptionText($e, 'text') . "\n";
if ($e instanceof \Psc\Code\ErrorException) {
$debug .= "\n" . $e->contextDump;
}
if (isset($contextInfo)) {
$debug .= "\nContextInfo: \n" . $contextInfo;
}
if (isset($this->recipient) && !PSC::inTests()) {
if ($ret = @mail($this->recipient, '[Psc-ErrorHandler] [' . $e->getCode() . '] ' . $e->getMessage(), $debug, 'From: www@' . PSC::getEnvironment()->getHostName() . "\r\n" . 'Content-Type: text/plain; charset=UTF-8' . "\r\n") === FALSE) {
error_log('[\\Psc\\Code\\ErrorHandler.php:' . __LINE__ . '] Die Fehlerinformationen konnten nicht an den lokalen Mailer übergeben werden.', 0);
}
}
}
作者:pschei
项目:psc-cm
/**
* Synchronisiert eine Collection von (Datenbank-)Objekten mit einer Collection von Daten / Unique-Kriterien oder Exportieren Objekten
*
* Die $fromCollection ist die Collection der bereits hydrierten Objekte. (fertige Tags)
* die $toCollection ist die noch nicht hydrierte Collection der Objekte die Objekte in $fromCollection repräsentieren (Tag Labels)
*
* zur Hilfe werden zwei Funktionen benötigt.
* Die hydrierFunktion erstellt aus den Daten asu $toCollection ein Objekt aus $fromCollection ( $label ===> Entity $tag )
* die hash Funktion erstellt aus einem Objekt von $fromCollection einen Skalar ( Entity $tag => $id )
*
* Article und Test beispiel:
*
* $fromCollection = $article->getTags();
* $toCollection = array('Tag1Name','Tag2Name','....');
*
* so ungefähr!! muss NULL zurückgeben nicht array
* $hydrateUniqueObject = function (\stdClass $json) {
* return $em->createQueryBuilder()
* ->select('tag')->from('Entities\Tag')
* ->where('id = :id OR uniqueconstraint = :unique)
* ->setParameter(
* array(
* 'id'=>$json->id,
* 'unique'>$json->label
* )
* )
* ;
* };
*
* $hashObject = function (Tag $tag) {
* return $tag->getIdentifier();
* };
*
* @param ArrayCollection $dbCollection die Collection als fertige Objekte aus der Datenbank
* @param collection $toCollection eine noch nicht hydrierte Collection von Objekten die Objekte in $fromCollection repräsentieren kann
*
* @return list($insert,$updates,$deletes) die jeweiligen listen von dispatchten events
*/
public function process($fromCollection, $toCollection)
{
// wir haben keine Ahnung welche Objekte in der $fromCollection und welche in der $toCollection sind
$fromCollection = \Psc\Code\Code::castArray($fromCollection);
// damit wir eine copy machen
$updates = $inserts = $deletes = array();
$index = array();
foreach ($toCollection as $toCollectionKey => $toObject) {
$fromObject = $this->hydrateUniqueObject($toObject, $toCollectionKey);
// kein objekt konnte hydriert werden
if ($fromObject === NULL) {
$inserts[] = $this->dispatchInsert($toObject, array('key' => $toCollectionKey));
// inserts müssen nicht in den index, da sie nicht im universum gefunden wurden, können sie auch nicht in $fromCollection sein
} else {
// objekt hydriert, kann mit korrekter id sein oder matching unique-constraint
$updates[] = $this->dispatchUpdate($fromObject, array('from' => $fromObject, 'to' => $toObject, 'key' => $toCollectionKey));
$index[$this->hashObject($fromObject)] = TRUE;
}
}
foreach ($fromCollection as $fromObject) {
if (!array_key_exists($this->hashObject($fromObject), $index)) {
// object ist weder ein insert noch ein update
$deletes[] = $this->dispatchDelete($fromObject);
}
}
return array($inserts, $updates, $deletes);
}
作者:pschei
项目:psc-cm
/**
* Erstellt eine neue Rule durch eine Spezifikation (was so quasi alles sein kann)
*
* Die Parameter dieser Funktion sind sehr Variabel
* Möglicherweise ist es einfacher generate[A-Za-z+]Rule zu benutzen
*/
public static function generateRule($ruleSpecification)
{
$rs = $ruleSpecification;
if (is_string($rs)) {
if ($rs == 'nes') {
return new NesValidatorRule();
}
if ($rs == 'id') {
return new IdValidatorRule();
}
if ($rs == 'pi' || $rs == 'pint') {
return new PositiveIntValidatorRule();
}
if ($rs == 'array') {
return new ArrayValidatorRule();
}
if ($rs == 'pi0' || $rs == 'pint0') {
$rule = new PositiveIntValidatorRule();
$rule->setZeroAllowed(TRUE);
return $rule;
}
if (S::startsWith($rs, '/') && S::endsWith($rs, '/')) {
return self::generateRegexpRule($rs);
}
$c = '\\' . __NAMESPACE__ . '\\' . ucfirst($rs) . 'ValidatorRule';
if (class_exists($c)) {
return new $c();
}
throw new \Psc\Exception('Unbekannte Parameter für generateRule ' . Code::varInfo($rs));
}
if (is_array($rs)) {
$num = count($rs);
}
throw new \Psc\Exception('Unbekannte Parameter für generateRule ' . Code::varInfo($rs));
}
作者:pschei
项目:psc-cm
protected function getIdentifierCaster(EntityPropertyMeta $identifierMeta)
{
if ($identifierMeta->getType() instanceof IntegerType) {
$idCaster = function ($idString, $debugKey) {
$id = \Psc\Code\Code::castId($idString, FALSE);
if ($id === FALSE) {
throw new ValidatorRuleException(sprintf("Der Wert '%s' des Schlüssels %s kann nicht zu einer numerischen Id gecastet werden", $idString, $debugKey));
}
return $id;
};
} elseif ($identifierMeta->getType() instanceof StringType) {
$idCaster = function ($idString, $debugKey) {
if (!is_string($idString)) {
throw new ValidatorRuleException(sprintf("Der Type '%s' des Schlüssels %s muss ein String sein", gettype($idString), $debugKey));
}
if (mb_strlen($idString) == 0) {
throw new ValidatorRuleException(sprintf("Der Wert '%s' des Schlüssels %s kann nicht zu einem Identifier gecastet werden", $idString, $debugKey));
}
return $idString;
};
} else {
throw new \Psc\Code\NotImplementedException(sprintf('IdCaster für Type %s ist nicht implementiert', $identifierMeta->getType()));
}
return $idCaster;
}
作者:pschei
项目:serien-loader-clien
/**
* @return list($threadLink, $threadId);
*/
public function findThread($boardId, Season $season)
{
$this->logger->writeln('Suche Thread für ' . $season . ' in board: ' . $boardId);
$this->req = new URLRequest('http://www.subcentral.de/index.php?page=Board&boardID=' . $boardId, $this->cookieJar);
$html = $this->req->init()->process();
/* wir holen uns den richtigen Thread aus den "wichtigen Themen" */
$dom = xml::doc($html);
$res = xml::query($dom, '#stickiesStatus table td.columnTopic div.topic p');
$stickies = array();
// das sind nicht alle wegen break!
foreach ($res as $topicP) {
$topicP = xml::doc($topicP);
$topicA = A::first(xml::query($topicP, 'a'));
$title = (string) $topicA->nodeValue;
$stickies[] = $title;
$prefix = xml::query($topicP, 'span.prefix strong');
if (count($prefix) == 1 && $prefix[0]->nodeValue == '[Subs]' && Preg::match($title, '/(Staffel\\s*' . $season->getNum() . '|S0*' . $season->getNum() . ')/i') > 0) {
$link = $topicA->getAttribute('href');
$threadId = (int) Preg::qmatch($link, '/threadId=([0-9]+)/');
break;
}
}
if (!isset($link)) {
$pe = new SubcentralException('Pfad nicht gefunden: "#stickiesStatus table td.columnTopic div.topic p a" in ' . $this->req->getURL() . ' ' . Code::varInfo($stickies));
$e = new SubcentralException('Thread für Staffel: ' . $season->getNum() . ' für Serie: ' . $season->getTvShow()->getTitle() . ' nicht gefunden', 0, $pe);
$this->logger->writeln($e->getMessage());
$this->logger->writeln($pe->getMessage());
throw $e;
}
$link = 'http://www.subcentral.de/' . $link;
return array($link, $threadId);
}
作者:pschei
项目:psc-cm
public function validate($data)
{
if (empty($data)) {
$e = new EmptyDataException();
$e->setDefaultValue(array());
throw $e;
}
$data = json_decode($data, true);
if (count($data) == 0) {
$e = new EmptyDataException();
$e->setDefaultValue(array());
throw $e;
}
$rep = $this->em->getRepository($this->entityName);
$collection = $rep->findAllByIds($data, $this->idName);
// überspringt dies fehlende Ids?
// sortieren nach der Data List (da findAllByIds das nicht tut, und das ist auch gut so)
$getter = \Psc\Code\Code::castGetter($this->idName);
$keys = array_flip($data);
usort($collection, function ($entityA, $entityB) use($keys, $getter) {
$keyA = $keys[$getter($entityA)];
$keyB = $keys[$getter($entityB)];
if ($keyA === $keyB) {
return 0;
}
return $keyA > $keyB ? 1 : -1;
});
if (count($collection) == count($data)) {
return $collection;
} else {
throw new \Psc\Exception('Unexpected: Es wurden: ' . count($collection) . ' IDs hydriert, aber ' . count($data) . ' IDs angegeben.');
}
}
作者:pschei
项目:psc-cm
/**
* Ruft den Getter für das Feld $field auf dem Entity auf
*
* @param string $field der Name des Feldes in CamelCase
* @return mixed
*/
public function callGetter($field)
{
$f = 'get' . ucfirst($field);
if (!method_exists($this, $f)) {
throw new \InvalidArgumentException($f . '() existiert nicht in ' . \Psc\Code\Code::getClass($this));
}
return $this->{$f}();
}
作者:pschei
项目:psc-cm
public function process($fromCollection, $toCollection)
{
// der genericCollectionSynchronizer braucht ArrayCollections
$fromCollection = Code::castCollection($fromCollection);
$toCollection = Code::castCollection($toCollection);
// die defaults sind: compare nach object, hashe nach identifier, und die sind prima für uns
$this->innerSynchronizer->process($fromCollection, $toCollection);
}
作者:pschei
项目:psc-cm
public function get($identifier)
{
try {
return $this->repository->hydrate($identifier);
} catch (\Psc\Doctrine\EntityNotFoundException $e) {
throw new NoUserException('User mit dem Identifier: ' . Code::varInfo($identifier) . ' nicht gefunden.', 0, $e);
}
}
作者:pschei
项目:psc-cm
/**
* @return Webforge\Common\System\File
*/
protected function getGClassFromFile()
{
$project = \Psc\PSC::getProject();
$gClass = new GClass(Code::mapFileToClass($this->file, $project->dir('lib')));
$gClass->setSrcFileName((string) $this->file);
// damit wir wirklich fremde sourcen angeben können
return $gClass;
}
作者:pschei
项目:psc-cm
/**
*
* in einem PHPUnit - TestCase darf man dann das hier machen:
*
* $baseDir = $resourceHelper->getBaseDirectory($this);
*
* Was dann in diesem Dir liegt bleibt dem Test überlassen
*/
public function getTestDirectory(\PHPUnit_Framework_TestCase $test)
{
if ($this->usePersonalDirs) {
$testName = Code::getClassName(get_class($test));
return $this->getFixturesDirectory()->sub($testName . '/');
} else {
return $this->project->dir('test-files');
}
}
作者:pschei
项目:psc-cm
public function escapeFor($type)
{
\Psc\Code\Code::value($type, self::WINDOWS, self::UNIX);
if ($this->escapeFor != NULL && $type != $this->escapeFor && count($this->args) > 0) {
throw new \RuntimeException('You switched to another escapeFor Mode, but you have already added arguments (through constructor?). Use escapeFor as last Argument from create/construct or as first chain-command');
}
$this->escapeFor = $type;
return $this;
}
作者:pschei
项目:psc-cm
/**
* @dataProvider provideMockCollections
*/
public function testSetMockCollection($colls)
{
$entity = $this->createTestEntity();
foreach ($colls as $coll) {
$set = \Psc\Code\Code::castSetter($coll);
$this->assertChainable($set($this->emm, array($entity)));
$this->assertEquals(array($entity), $this->emm->getMockCollection($coll)->toArray());
}
}
作者:pschei
项目:psc-cm
public function setUpFixtures()
{
// overload this
if (\Psc\Code\Code::isTraversable($this->fixtures)) {
foreach ($this->fixtures as $fixture) {
$this->dcFixtures->add($fixture);
}
}
}
作者:pschei
项目:psc-cm
/**
* @param array Webforge\Types[] Schlüssel sind Namen der Felder (Ebenen getrennt mit .), Werte sind Webforge\Types\Type-Objekte
*/
public function addTypesFromArray(array $types)
{
foreach ($types as $field => $type) {
if (!$type instanceof Type) {
throw new TypeExpectedException('Instances from Type as values from the array expected. ' . Code::varInfo($type) . ' was provided.');
}
$this->setFieldType($field, $type);
}
return $this;
}