Gets a named entity manager.
public getEntityManager ( string $name = null ) : EntityManager | ||
$name | string | The entity manager name (null for the default one) |
return | EntityManager |
/** * @param object $entity * @param Constraint $constraint * @return bool */ public function isValid($entity, Constraint $constraint) { if (!is_array($constraint->fields) && !is_string($constraint->fields)) { throw new UnexpectedTypeException($constraint->fields, 'array'); } $fields = (array) $constraint->fields; if (count($fields) == 0) { throw new ConstraintDefinitionException("At least one field has to be specified."); } $em = $this->registry->getEntityManager($constraint->em); $className = $this->context->getCurrentClass(); $class = $em->getClassMetadata($className); $criteria = array(); foreach ($fields as $fieldName) { if (!isset($class->reflFields[$fieldName])) { throw new ConstraintDefinitionException("Only field names mapped by Doctrine can be validated for uniqueness."); } $criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity); } $repository = $em->getRepository($className); $result = $repository->findBy($criteria); if (count($result) > 0 && $result[0] !== $entity) { $oldPath = $this->context->getPropertyPath(); $this->context->setPropertyPath(empty($oldPath) ? $fields[0] : $oldPath . "." . $fields[0]); $this->context->addViolation($constraint->message, array(), $criteria[$fields[0]]); $this->context->setPropertyPath($oldPath); } return true; // all true, we added the violation already! }
/** * @param object $entity * @param Constraint $constraint * @return bool */ public function isValid($entity, Constraint $constraint) { if (!is_array($constraint->fields) && !is_string($constraint->fields)) { throw new UnexpectedTypeException($constraint->fields, 'array'); } $fields = (array) $constraint->fields; if (count($fields) == 0) { throw new ConstraintDefinitionException("At least one field has to be specified."); } $em = $this->registry->getEntityManager($constraint->em); $className = $this->context->getCurrentClass(); $class = $em->getClassMetadata($className); $criteria = array(); foreach ($fields as $fieldName) { if (!isset($class->reflFields[$fieldName])) { throw new ConstraintDefinitionException("Only field names mapped by Doctrine can be validated for uniqueness."); } $criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity); if ($criteria[$fieldName] === null) { return true; } else { if (isset($class->associationMappings[$fieldName])) { $relatedClass = $em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']); $relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]); if (count($relatedId) > 1) { throw new ConstraintDefinitionException("Associated entities are not allowed to have more than one identifier field to be " . "part of a unique constraint in: " . $class->name . "#" . $fieldName); } $criteria[$fieldName] = array_pop($relatedId); } } } $repository = $em->getRepository($className); $result = $repository->findBy($criteria); /* If no entity matched the query criteria or a single entity matched, * which is the same as the entity being validated, the criteria is * unique. */ if (0 == count($result) || 1 == count($result) && $entity === $result[0]) { return true; } $oldPath = $this->context->getPropertyPath(); $this->context->setPropertyPath(empty($oldPath) ? $fields[0] : $oldPath . "." . $fields[0]); $this->context->addViolation($constraint->message, array(), $criteria[$fields[0]]); $this->context->setPropertyPath($oldPath); return true; // all true, we added the violation already! }
/** * @param \Class $class * * @return EntityManager */ public function getEntityManager($class = null) { if (!$class) { return $this->_registry->getEntityManager(); } if (is_object($class)) { $class = get_class($class); } if (!isset($this->_cache[$class])) { $em = $this->_registry->getManagerForClass($class); if (!$em) { throw new \RuntimeException(sprintf('No entity manager defined for class %s', $class)); } $this->_cache[$class] = $em; } return $this->_cache[$class]; }
/** * @param TokenInterface $token */ protected function getOrCreateAccessToken(TokenInterface $token) { $user = $token->getUser(); $tokenManager = new TokenManager($this->doctrine->getEntityManager(), 'Acme\\SPA\\ApiBundle\\Entity\\OAuth\\AccessToken'); $oauthToken = $tokenManager->findTokenBy(array('user' => $token->getUser())); if (!$oauthToken instanceof AccessToken) { // id 1 is our chaplin client $chaplinClient = $this->doctrine->getRepository('AcmeSPAApiBundle:Oauth\\Client')->find(1); $oauthToken = $tokenManager->createToken(); // TODO: create a more sophisticated access token $oauthToken->setToken(uniqid()); $oauthToken->setClient($chaplinClient); $oauthToken->setUser($user); $oauthToken->updateToken($token); } return $oauthToken; }
private function updateInformation(Package $package, PackageInterface $data, $flags) { $em = $this->doctrine->getEntityManager(); $version = new Version(); $version->setNormalizedVersion($data->getVersion()); // check if we have that version yet foreach ($package->getVersions() as $existingVersion) { if ($existingVersion->getNormalizedVersion() === $version->getNormalizedVersion()) { if ($existingVersion->getDevelopment() || $flags & self::UPDATE_TAGS) { $version = $existingVersion; break; } // mark it updated to avoid it being pruned $existingVersion->setUpdatedAt(new \DateTime()); return; } } $version->setName($package->getName()); $version->setVersion($data->getPrettyVersion()); $version->setDevelopment($data->isDev()); $em->persist($version); $version->setDescription($data->getDescription()); $package->setDescription($data->getDescription()); $version->setHomepage($data->getHomepage()); $version->setLicense($data->getLicense() ?: array()); $version->setPackage($package); $version->setUpdatedAt(new \DateTime()); $version->setReleasedAt($data->getReleaseDate()); if ($data->getSourceType()) { $source['type'] = $data->getSourceType(); $source['url'] = $data->getSourceUrl(); $source['reference'] = $data->getSourceReference(); $version->setSource($source); } if ($data->getDistType()) { $dist['type'] = $data->getDistType(); $dist['url'] = $data->getDistUrl(); $dist['reference'] = $data->getDistReference(); $dist['shasum'] = $data->getDistSha1Checksum(); $version->setDist($dist); } if ($data->getType()) { $version->setType($data->getType()); if ($data->getType() && $data->getType() !== $package->getType()) { $package->setType($data->getType()); } } $version->setTargetDir($data->getTargetDir()); $version->setAutoload($data->getAutoload()); $version->setExtra($data->getExtra()); $version->setBinaries($data->getBinaries()); $version->setIncludePaths($data->getIncludePaths()); $version->setSupport($data->getSupport()); $version->getTags()->clear(); if ($data->getKeywords()) { foreach ($data->getKeywords() as $keyword) { $tag = Tag::getByName($em, $keyword, true); if (!$version->getTags()->contains($tag)) { $version->addTag($tag); } } } $authorRepository = $this->doctrine->getRepository('PackagistWebBundle:Author'); $version->getAuthors()->clear(); if ($data->getAuthors()) { foreach ($data->getAuthors() as $authorData) { $author = null; // skip authors with no information if (empty($authorData['email']) && empty($authorData['name'])) { continue; } if (!empty($authorData['email'])) { $author = $authorRepository->findOneByEmail($authorData['email']); } if (!$author && !empty($authorData['homepage'])) { $author = $authorRepository->findOneBy(array('name' => $authorData['name'], 'homepage' => $authorData['homepage'])); } if (!$author && !empty($authorData['name'])) { $author = $authorRepository->findOneByNameAndPackage($authorData['name'], $package); } if (!$author) { $author = new Author(); $em->persist($author); } foreach (array('email', 'name', 'homepage', 'role') as $field) { if (isset($authorData[$field])) { $author->{'set' . $field}($authorData[$field]); } } $author->setUpdatedAt(new \DateTime()); if (!$version->getAuthors()->contains($author)) { $version->addAuthor($author); } if (!$author->getVersions()->contains($version)) { $author->addVersion($version); } } } // handle links foreach ($this->supportedLinkTypes as $linkType => $opts) { $links = array(); foreach ($data->{$opts['method']}() as $link) { $constraint = $link->getPrettyConstraint(); if (false !== strpos($constraint, '~')) { $constraint = str_replace(array('[', ']'), '', $link->getConstraint()); $constraint = preg_replace('{(\\d\\.\\d)(\\.0)+(?=$|,|-)}', '$1', $constraint); $constraint = preg_replace('{([><=,]) }', '$1', $constraint); $constraint = preg_replace('{(<[0-9.]+)-dev}', '$1', $constraint); } if (false !== strpos($constraint, ',') && false !== strpos($constraint, '@')) { $constraint = preg_replace_callback('{([><]=?\\s*[^@]+?)@([a-z]+)}i', function ($matches) { if ($matches[2] === 'stable') { return $matches[1]; } return $matches[1] . '-' . $matches[2]; }, $constraint); } $links[$link->getTarget()] = $constraint; } foreach ($version->{'get' . $linkType}() as $link) { // clear links that have changed/disappeared (for updates) if (!isset($links[$link->getPackageName()]) || $links[$link->getPackageName()] !== $link->getPackageVersion()) { $version->{'get' . $linkType}()->removeElement($link); $em->remove($link); } else { // clear those that are already set unset($links[$link->getPackageName()]); } } foreach ($links as $linkPackageName => $linkPackageVersion) { $class = 'Packagist\\WebBundle\\Entity\\' . $opts['entity']; $link = new $class(); $link->setPackageName($linkPackageName); $link->setPackageVersion($linkPackageVersion); $version->{'add' . $linkType . 'Link'}($link); $link->setVersion($version); $em->persist($link); } } // handle suggests if ($suggests = $data->getSuggests()) { foreach ($version->getSuggest() as $link) { // clear links that have changed/disappeared (for updates) if (!isset($suggests[$link->getPackageName()]) || $suggests[$link->getPackageName()] !== $link->getPackageVersion()) { $version->getSuggest()->removeElement($link); $em->remove($link); } else { // clear those that are already set unset($suggests[$link->getPackageName()]); } } foreach ($suggests as $linkPackageName => $linkPackageVersion) { $link = new SuggestLink(); $link->setPackageName($linkPackageName); $link->setPackageVersion($linkPackageVersion); $version->addSuggestLink($link); $link->setVersion($version); $em->persist($link); } } if (!$package->getVersions()->contains($version)) { $package->addVersions($version); } }
private function updateInformation(OutputInterface $output, RegistryInterface $doctrine, $package, PackageInterface $data) { $em = $doctrine->getEntityManager(); $version = new Version(); $version->setName($package->getName()); $version->setNormalizedVersion(preg_replace('{-dev$}i', '', $data->getVersion())); // check if we have that version yet foreach ($package->getVersions() as $existingVersion) { if ($existingVersion->equals($version)) { // avoid updating newer versions, in case two branches have the same version in their composer.json if ($existingVersion->getReleasedAt() > $data->getReleaseDate()) { return; } if ($existingVersion->getDevelopment()) { $version = $existingVersion; break; } return; } } $version->setVersion($data->getPrettyVersion()); $version->setDevelopment(substr($data->getVersion(), -4) === '-dev'); $em->persist($version); $version->setDescription($data->getDescription()); $package->setDescription($data->getDescription()); $version->setHomepage($data->getHomepage()); $version->setLicense($data->getLicense() ?: array()); $version->setPackage($package); $version->setUpdatedAt(new \DateTime()); $version->setReleasedAt($data->getReleaseDate()); if ($data->getSourceType()) { $source['type'] = $data->getSourceType(); $source['url'] = $data->getSourceUrl(); $source['reference'] = $data->getSourceReference(); $version->setSource($source); } if ($data->getDistType()) { $dist['type'] = $data->getDistType(); $dist['url'] = $data->getDistUrl(); $dist['reference'] = $data->getDistReference(); $dist['shasum'] = $data->getDistSha1Checksum(); $version->setDist($dist); } if ($data->getType()) { $version->setType($data->getType()); if ($data->getType() && $data->getType() !== $package->getType()) { $package->setType($data->getType()); } } $version->setTargetDir($data->getTargetDir()); $version->setAutoload($data->getAutoload()); $version->setExtra($data->getExtra()); $version->setBinaries($data->getBinaries()); $version->getTags()->clear(); if ($data->getKeywords()) { foreach ($data->getKeywords() as $keyword) { $version->addTag(Tag::getByName($em, $keyword, true)); } } $version->getAuthors()->clear(); if ($data->getAuthors()) { foreach ($data->getAuthors() as $authorData) { $author = null; // skip authors with no information if (empty($authorData['email']) && empty($authorData['name'])) { continue; } if (!empty($authorData['email'])) { $author = $doctrine->getRepository('PackagistWebBundle:Author')->findOneByEmail($authorData['email']); } if (!$author && !empty($authorData['homepage'])) { $author = $doctrine->getRepository('PackagistWebBundle:Author')->findOneBy(array('name' => $authorData['name'], 'homepage' => $authorData['homepage'])); } if (!$author && !empty($authorData['name'])) { $author = $doctrine->getRepository('PackagistWebBundle:Author')->findOneByNameAndPackage($authorData['name'], $package); } if (!$author) { $author = new Author(); $em->persist($author); } foreach (array('email', 'name', 'homepage') as $field) { if (isset($authorData[$field])) { $author->{'set' . $field}($authorData[$field]); } } $author->setUpdatedAt(new \DateTime()); if (!$version->getAuthors()->contains($author)) { $version->addAuthor($author); } if (!$author->getVersions()->contains($version)) { $author->addVersion($version); } } } foreach ($this->supportedLinkTypes as $linkType => $linkEntity) { $links = array(); foreach ($data->{'get' . $linkType . 's'}() as $link) { $links[$link->getTarget()] = $link->getPrettyConstraint(); } foreach ($version->{'get' . $linkType}() as $link) { // clear links that have changed/disappeared (for updates) if (!isset($links[$link->getPackageName()]) || $links[$link->getPackageName()] !== $link->getPackageVersion()) { $version->{'get' . $linkType}()->removeElement($link); $em->remove($link); } else { // clear those that are already set unset($links[$link->getPackageName()]); } } foreach ($links as $linkPackageName => $linkPackageVersion) { $class = 'Packagist\\WebBundle\\Entity\\' . $linkEntity; $link = new $class(); $link->setPackageName($linkPackageName); $link->setPackageVersion($linkPackageVersion); $version->{'add' . $linkType . 'Link'}($link); $link->setVersion($version); $em->persist($link); } } if (!$package->getVersions()->contains($version)) { $package->addVersions($version); } }
/** * Dump a set of packages to the web root * * @param array $packageIds * @param Boolean $force * @param Boolean $verbose */ public function dump(array $packageIds, $force = false, $verbose = false) { // prepare build dir $webDir = $this->webDir; $buildDir = $this->buildDir; $this->fs->remove($buildDir); $this->fs->mkdir($buildDir); $this->fs->mkdir($webDir . '/p/'); if (!$force) { if ($verbose) { echo 'Copying existing files' . PHP_EOL; } exec('cp -rpf ' . escapeshellarg($webDir . '/p') . ' ' . escapeshellarg($buildDir . '/p'), $output, $exit); if (0 !== $exit) { $this->fs->mirror($webDir . '/p/', $buildDir . '/p/', null, array('override' => true)); } } $modifiedFiles = array(); $modifiedIndividualFiles = array(); $total = count($packageIds); $current = 0; $step = 50; while ($packageIds) { $packages = $this->doctrine->getRepository('PackagistWebBundle:Package')->getPackagesWithVersions(array_splice($packageIds, 0, $step)); if ($verbose) { echo '[' . sprintf('%' . strlen($total) . 'd', $current) . '/' . $total . '] Processing ' . $step . ' packages' . PHP_EOL; } $current += $step; // prepare packages in memory foreach ($packages as $package) { $affectedFiles = array(); $name = strtolower($package->getName()); // clean up versions in individual files if (file_exists($buildDir . '/p/' . $name . '.files')) { $files = json_decode(file_get_contents($buildDir . '/p/' . $name . '.files')); foreach ($files as $file) { $key = $this->getIndividualFileKey($buildDir . '/' . $file); $this->loadIndividualFile($buildDir . '/' . $file, $key); if (isset($this->individualFiles[$key]['packages'][$name])) { unset($this->individualFiles[$key]['packages'][$name]); $modifiedIndividualFiles[$key] = true; } } } // (re)write versions in individual files foreach ($package->getVersions() as $version) { foreach (array_slice($version->getNames(), 0, 150) as $versionName) { if (!preg_match('{^[A-Za-z0-9_-][A-Za-z0-9_.-]+/[A-Za-z0-9_-][A-Za-z0-9_.-]+?$}', $versionName) || strpos($versionName, '..')) { continue; } $file = $buildDir . '/p/' . $versionName . '.json'; $key = $this->getIndividualFileKey($file); $this->dumpVersionToIndividualFile($version, $file, $key); $modifiedIndividualFiles[$key] = true; $affectedFiles[$key] = true; } } // store affected files to clean up properly in the next update $this->fs->mkdir(dirname($buildDir . '/p/' . $name)); file_put_contents($buildDir . '/p/' . $name . '.files', json_encode(array_keys($affectedFiles))); $modifiedIndividualFiles['p/' . $name . '.files'] = true; // clean up all versions of that package foreach (glob($buildDir . '/p/packages*.json') as $file) { $key = 'p/' . basename($file); $this->loadFile($file); if (isset($this->files[$key]['packages'][$name])) { unset($this->files[$key]['packages'][$name]); $modifiedFiles[$key] = true; } } // (re)write versions foreach ($package->getVersions() as $version) { $file = $buildDir . '/p/' . $this->getTargetFile($version); $modifiedFiles['p/' . basename($file)] = true; $this->dumpVersion($version, $file); } $package->setDumpedAt(new \DateTime()); } // update dump dates $this->doctrine->getEntityManager()->flush(); $this->doctrine->getEntityManager()->clear(); unset($packages); if ($current % 250 === 0 || !$packageIds) { if ($verbose) { echo 'Dumping individual files' . PHP_EOL; } // dump individual files to build dir foreach ($this->individualFiles as $file => $dummy) { $this->dumpIndividualFile($buildDir . '/' . $file, $file); } $this->individualFiles = array(); } } // prepare individual files listings if ($verbose) { echo 'Preparing individual files listings' . PHP_EOL; } $individualListings = array(); $finder = Finder::create()->files()->ignoreVCS(true)->name('*.json')->in($buildDir . '/p/')->depth('1'); foreach ($finder as $file) { $key = $this->getIndividualFileKey(strtr($file, '\\', '/')); if ($force && !isset($modifiedIndividualFiles[$key])) { continue; } $listing = 'p/' . $this->getTargetListing($file); $this->listings[$listing]['providers'][$key] = array('sha256' => hash_file('sha256', $file)); $individualListings[$listing] = true; } // prepare root file $rootFile = $buildDir . '/p/packages.json'; $this->loadFile($rootFile); if (!isset($this->files['p/packages.json']['packages'])) { $this->files['p/packages.json']['packages'] = array(); } $url = $this->router->generate('track_download', array('name' => 'VND/PKG')); $this->files['p/packages.json']['notify'] = str_replace('VND/PKG', '%package%', $url); if ($verbose) { echo 'Dumping individual listings' . PHP_EOL; } // dump listings to build dir foreach ($individualListings as $listing => $dummy) { $this->dumpListing($buildDir . '/' . $listing); $this->files['p/packages.json']['providers-includes'][$listing] = array('sha256' => hash_file('sha256', $buildDir . '/' . $listing)); } if ($verbose) { echo 'Dumping package metadata' . PHP_EOL; } // dump files to build dir foreach ($modifiedFiles as $file => $dummy) { $this->dumpFile($buildDir . '/' . $file); $this->files['p/packages.json']['includes'][$file] = array('sha1' => sha1_file($buildDir . '/' . $file)); } if ($verbose) { echo 'Dumping root' . PHP_EOL; } // sort & dump root file ksort($this->files['p/packages.json']['packages']); ksort($this->files['p/packages.json']['providers-includes']); ksort($this->files['p/packages.json']['includes']); $this->dumpFile($rootFile); if ($verbose) { echo 'Putting new files in production' . PHP_EOL; } // put the new files in production exec(sprintf('mv %s %s && mv %s %1$s', escapeshellarg($webDir . '/p'), escapeshellarg($webDir . '/p-old'), escapeshellarg($buildDir . '/p')), $out, $exit); if (0 !== $exit) { throw new \RuntimeException("Rename failed:\n\n" . implode("\n", $out)); } if (defined('PHP_WINDOWS_VERSION_BUILD')) { rename($webDir . '/p/packages.json', $webDir . '/packages.json'); } else { if (!is_link($webDir . '/packages.json')) { unlink($webDir . '/packages.json'); symlink($webDir . '/p/packages.json', $webDir . '/packages.json'); } } // clean up old dir $retries = 5; do { exec(sprintf('rm -rf %s', escapeshellarg($webDir . '/p-old'))); usleep(200); clearstatcache(); } while (is_dir($webDir . '/p-old') && $retries--); if ($force) { if ($verbose) { echo 'Cleaning up outdated files' . PHP_EOL; } // clear files that were not created in this build foreach (glob($webDir . '/p/packages-*.json') as $file) { if (!isset($modifiedFiles['p/' . basename($file)])) { unlink($file); } } foreach (glob($webDir . '/p/providers-*.json') as $file) { if (!isset($individualListings['p/' . basename($file)])) { unlink($file); } } $finder = Finder::create()->files()->depth('1')->ignoreVCS(true)->name('/\\.(json|files)$/')->in($webDir . '/p/'); foreach ($finder as $file) { $key = $this->getIndividualFileKey(strtr($file, '\\', '/')); if (!isset($modifiedIndividualFiles[$key])) { unlink($file); } } } }