private function updateInformation(Package $package, PackageInterface $data, $flags) { $em = $this->doctrine->getManager(); $version = new Version(); $normVersion = $data->getVersion(); $existingVersion = $package->getVersion($normVersion); if ($existingVersion) { $source = $existingVersion->getSource(); // update if the right flag is set, or the source reference has changed (re-tag or new commit on branch) if ($source['reference'] !== $data->getSourceReference() || $flags & self::UPDATE_EQUAL_REFS) { $version = $existingVersion; } else { // mark it updated to avoid it being pruned $existingVersion->setUpdatedAt(new \DateTime()); return false; } } $version->setName($package->getName()); $version->setVersion($data->getPrettyVersion()); $version->setNormalizedVersion($normVersion); $version->setDevelopment($data->isDev()); $em->persist($version); $descr = $this->sanitize($data->getDescription()); $version->setDescription($descr); $package->setDescription($descr); $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); } else { $version->setSource(null); } if ($data->getDistType()) { $dist['type'] = $data->getDistType(); $dist['url'] = $data->getDistUrl(); $dist['reference'] = $data->getDistReference(); $dist['shasum'] = $data->getDistSha1Checksum(); $version->setDist($dist); } else { $version->setDist(null); } if ($data->getType()) { $type = $this->sanitize($data->getType()); $version->setType($type); if ($type !== $package->getType()) { $package->setType($type); } } $version->setTargetDir($data->getTargetDir()); $version->setAutoload($data->getAutoload()); $version->setExtra($data->getExtra()); $version->setBinaries($data->getBinaries()); $version->setIncludePaths($data->getIncludePaths()); $version->setSupport($data->getSupport()); if ($data->getKeywords()) { $keywords = array(); foreach ($data->getKeywords() as $keyword) { $keywords[mb_strtolower($keyword, 'UTF-8')] = $keyword; } $existingTags = []; foreach ($version->getTags() as $tag) { $existingTags[mb_strtolower($tag->getName(), 'UTF-8')] = $tag; } foreach ($keywords as $tagKey => $keyword) { if (isset($existingTags[$tagKey])) { unset($existingTags[$tagKey]); continue; } $tag = Tag::getByName($em, $keyword, true); if (!$version->getTags()->contains($tag)) { $version->addTag($tag); } } foreach ($existingTags as $tag) { $version->getTags()->removeElement($tag); } } elseif (count($version->getTags())) { $version->getTags()->clear(); } $authorRepository = $this->doctrine->getRepository('PackagistWebBundle:Author'); $version->getAuthors()->clear(); if ($data->getAuthors()) { foreach ($data->getAuthors() as $authorData) { $author = null; foreach (array('email', 'name', 'homepage', 'role') as $field) { if (isset($authorData[$field])) { $authorData[$field] = trim($authorData[$field]); if ('' === $authorData[$field]) { $authorData[$field] = null; } } else { $authorData[$field] = null; } } // skip authors with no information if (!isset($authorData['email']) && !isset($authorData['name'])) { continue; } $author = $authorRepository->findOneBy(array('email' => $authorData['email'], 'name' => $authorData['name'], 'homepage' => $authorData['homepage'], 'role' => $authorData['role'])); 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]); } } // only update the author timestamp once a month at most as the value is kinda unused if ($author->getUpdatedAt() === null || $author->getUpdatedAt()->getTimestamp() < time() - 86400 * 30) { $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, ',') && 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); } } elseif (count($version->getSuggest())) { // clear existing suggests if present foreach ($version->getSuggest() as $link) { $em->remove($link); } $version->getSuggest()->clear(); } if (!$package->getVersions()->contains($version)) { $package->addVersions($version); } return true; }