Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Big refactoring:

- refactor code of Updater,
- introduce activities instead of texts,
- removed useless exception,
- refatored creation of bundle into one BundleManager,
- fixed and simplified creation of owners for background processes,
- removed unused tags from bundle
- fixed incomplete tests!
  • Loading branch information...
commit 9378f4638c7f7596da4d5ae87e7ba3be728f897b 1 parent ed464e7
@stloyd stloyd authored
Showing with 1,597 additions and 830 deletions.
  1. +17 −0 CHANGELOG.markdown
  2. +34 −0 app/DoctrineMigrations/Version20121010101749.php
  3. +1 −6 src/Knp/Bundle/KnpBundlesBundle/Command/KbAddBundleCommand.php
  4. +0 −1  src/Knp/Bundle/KnpBundlesBundle/Command/KbAddSearchedBundlesCommand.php
  5. +1 −3 src/Knp/Bundle/KnpBundlesBundle/Command/KbPopulateCommand.php
  6. +1 −3 src/Knp/Bundle/KnpBundlesBundle/Command/KbUpdateBundlesCommand.php
  7. +3 −8 src/Knp/Bundle/KnpBundlesBundle/Command/KbUpdateTrendsCommand.php
  8. +66 −0 src/Knp/Bundle/KnpBundlesBundle/Command/MigrateCommitsCommand.php
  9. +6 −7 src/Knp/Bundle/KnpBundlesBundle/Consumer/UpdateBundleConsumer.php
  10. +19 −39 src/Knp/Bundle/KnpBundlesBundle/Controller/BundleController.php
  11. +41 −41 src/Knp/Bundle/KnpBundlesBundle/DataFixtures/ORM/Data.php
  12. +315 −0 src/Knp/Bundle/KnpBundlesBundle/Entity/Activity.php
  13. +85 −147 src/Knp/Bundle/KnpBundlesBundle/Entity/Bundle.php
  14. +58 −110 src/Knp/Bundle/KnpBundlesBundle/Entity/Developer.php
  15. +49 −7 src/Knp/Bundle/KnpBundlesBundle/Entity/Owner.php
  16. +15 −16 src/Knp/Bundle/KnpBundlesBundle/Github/Organization.php
  17. +20 −19 src/Knp/Bundle/KnpBundlesBundle/Github/Owner.php
  18. +68 −59 src/Knp/Bundle/KnpBundlesBundle/Github/Repo.php
  19. +167 −0 src/Knp/Bundle/KnpBundlesBundle/Manager/BundleManager.php
  20. +24 −17 src/Knp/Bundle/KnpBundlesBundle/{Entity → Manager}/OwnerManager.php
  21. +82 −0 src/Knp/Bundle/KnpBundlesBundle/Repository/ActivityRepository.php
  22. +0 −15 src/Knp/Bundle/KnpBundlesBundle/Repository/BundleRepository.php
  23. +37 −5 src/Knp/Bundle/KnpBundlesBundle/Repository/OwnerRepository.php
  24. +11 −2 src/Knp/Bundle/KnpBundlesBundle/Resources/config/services.yml
  25. +0 −7 src/Knp/Bundle/KnpBundlesBundle/Resources/doc/api.markdown
  26. +27 −2 src/Knp/Bundle/KnpBundlesBundle/Resources/public/css/styles.css
  27. +2 −2 src/Knp/Bundle/KnpBundlesBundle/Resources/views/Bundle/add.html.twig
  28. +1 −1  src/Knp/Bundle/KnpBundlesBundle/Resources/views/Bundle/bigList.html.twig
  29. +24 −0 src/Knp/Bundle/KnpBundlesBundle/Resources/views/Bundle/list.html.twig
  30. +10 −9 src/Knp/Bundle/KnpBundlesBundle/Resources/views/Bundle/show.html.twig
  31. +20 −0 src/Knp/Bundle/KnpBundlesBundle/Resources/views/Developer/show.html.twig
  32. +8 −13 src/Knp/Bundle/KnpBundlesBundle/Security/Core/User/UserProvider.php
  33. +23 −5 src/Knp/Bundle/KnpBundlesBundle/Tests/Commands/KbUpdateTrendsCommandTest.php
  34. +87 −72 src/Knp/Bundle/KnpBundlesBundle/Tests/Github/RepoTest.php
  35. +1 −0  src/Knp/Bundle/KnpBundlesBundle/Tests/Github/fixtures/encoded-composer.json
  36. +1 −1  src/Knp/Bundle/KnpBundlesBundle/Tests/Security/Core/User/UserProviderTest.php
  37. +43 −65 src/Knp/Bundle/KnpBundlesBundle/Tests/Updater/UpdaterTest.php
  38. +18 −7 src/Knp/Bundle/KnpBundlesBundle/Travis/Travis.php
  39. +63 −0 src/Knp/Bundle/KnpBundlesBundle/Twig/Extension/BundleUtilsExtension.php
  40. +12 −3 src/Knp/Bundle/KnpBundlesBundle/Twitterer/TrendingBundleTwitterer.php
  41. +0 −8 src/Knp/Bundle/KnpBundlesBundle/Updater/Exception/UserNotFoundException.php
  42. +137 −130 src/Knp/Bundle/KnpBundlesBundle/Updater/Updater.php
View
17 CHANGELOG.markdown
@@ -1,3 +1,20 @@
+* 2012-10-08
+ * Added `Activity` entity and replace all text based ones with new approach
+ in `Bundle` and `Developer` entities,
+ * Added `OwnerRepository#findOneByUniqueFields()` to lookup for users in database,
+ * Added new methods to `BundleUtilsExtension`: `#bundleActivityIcon`
+ and `#bundleActivityMessage`,
+ * Added `BundleManager` for easier creation of bundles,
+ * Moved `OwnerManager` into own namespace,
+ * Moved methods `#getGithubId()`, `#getSensioId()` from `Developer` entity
+ to `Owner` entity
+ * Replace dependency of `Github\Organization` from `OrganizationRepository`
+ to `OwnerManager`,
+ * Replaced dependency of `Update` from `OwnerManager` to `BundleManager`,
+ * Removed `Updater#setUp` method, bundles are now loaded via `Pagerfanta`,
+ * `UpdateBundleConsumer` no longer removes bundle on API failure,
+ * Removed unused exception `UserNotFoundException`
+
* 2012-10-03
* Removed `js` format from web API, we still support: `json` and `html`,
* Moved code related to web API into controllers and removed all view templates
View
34 app/DoctrineMigrations/Version20121010101749.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Application\Migrations;
+
+use Doctrine\DBAL\Migrations\AbstractMigration,
+ Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Auto-generated Migration: Please modify to your need!
+ */
+class Version20121010101749 extends AbstractMigration
+{
+ public function up(Schema $schema)
+ {
+ // this up() migration is autogenerated, please modify it to your needs
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");
+
+ $this->addSql("CREATE TABLE activities (id INT AUTO_INCREMENT NOT NULL, bundle_id INT DEFAULT NULL, developer_id INT DEFAULT NULL, type INT NOT NULL, state INT NOT NULL, createdAt DATETIME NOT NULL, message VARCHAR(255) DEFAULT NULL, author VARCHAR(255) DEFAULT NULL, bundleName VARCHAR(255) DEFAULT NULL, bundleOwnerName VARCHAR(255) DEFAULT NULL, INDEX IDX_B5F1AFE5F1FAD9D3 (bundle_id), INDEX IDX_B5F1AFE564DD9267 (developer_id), INDEX type_state (type, state), INDEX created_at (createdAt), PRIMARY KEY(id)) ENGINE = InnoDB");
+ $this->addSql("ALTER TABLE activities ADD CONSTRAINT FK_B5F1AFE5F1FAD9D3 FOREIGN KEY (bundle_id) REFERENCES bundle (id)");
+ $this->addSql("ALTER TABLE activities ADD CONSTRAINT FK_B5F1AFE564DD9267 FOREIGN KEY (developer_id) REFERENCES owner (id)");
+ $this->addSql("ALTER TABLE owner ADD lastCommitAt DATE DEFAULT NULL");
+ $this->addSql("ALTER TABLE bundle DROP lastCommits, DROP tags");
+ }
+
+ public function down(Schema $schema)
+ {
+ // this down() migration is autogenerated, please modify it to your needs
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");
+
+ $this->addSql("DROP TABLE activities");
+ $this->addSql("ALTER TABLE bundle ADD lastCommits LONGTEXT NOT NULL, ADD tags LONGTEXT NOT NULL");
+ $this->addSql("ALTER TABLE owner DROP lastCommitAt");
+ }
+}
View
7 src/Knp/Bundle/KnpBundlesBundle/Command/KbAddBundleCommand.php
@@ -34,18 +34,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
/* @var $updater Updater */
$updater = $container->get('knp_bundles.updater');
+ $updater->setOutput($output);
if (!$input->getOption('no-publish')) {
// manually set RabbitMQ producer
$updater->setBundleUpdateProducer($container->get('old_sound_rabbit_mq.update_bundle_producer'));
}
- $updater->setOutput($output);
- $updater->setUp();
-
$updater->addBundle($input->getArgument('bundleName'));
-
- $em = $this->getContainer()->get('knp_bundles.entity_manager');
- $em->flush();
}
}
View
1  src/Knp/Bundle/KnpBundlesBundle/Command/KbAddSearchedBundlesCommand.php
@@ -34,7 +34,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
/* @var $updater Updater */
$updater = $this->getContainer()->get('knp_bundles.updater');
$updater->setOutput($output);
- $updater->setUp();
$bundles = $updater->searchNewBundles();
$updater->createMissingBundles($bundles);
View
4 src/Knp/Bundle/KnpBundlesBundle/Command/KbPopulateCommand.php
@@ -36,15 +36,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
/* @var $updater Updater */
$updater = $container->get('knp_bundles.updater');
+ $updater->setOutput($output);
if (!$input->getOption('no-publish')) {
// manually set RabbitMQ producer
$updater->setBundleUpdateProducer($container->get('old_sound_rabbit_mq.update_bundle_producer'));
}
- $updater->setOutput($output);
- $updater->setUp();
-
$bundles = $updater->searchNewBundles();
$updater->createMissingBundles($bundles);
$updater->updateBundlesData();
View
4 src/Knp/Bundle/KnpBundlesBundle/Command/KbUpdateBundlesCommand.php
@@ -33,15 +33,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
/* @var $updater Updater */
$updater = $container->get('knp_bundles.updater');
+ $updater->setOutput($output);
if (!$input->getOption('no-publish')) {
// manually set RabbitMQ producer
$updater->setBundleUpdateProducer($container->get('old_sound_rabbit_mq.update_bundle_producer'));
}
- $updater->setOutput($output);
- $updater->setUp();
-
$updater->updateBundlesData();
$em = $container->get('knp_bundles.entity_manager');
View
11 src/Knp/Bundle/KnpBundlesBundle/Command/KbUpdateTrendsCommand.php
@@ -30,7 +30,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$em = $this->getContainer()->get('knp_bundles.entity_manager');
if ($em->getConnection()->getDatabasePlatform()->getName() == 'sqlite') {
- $output->writeln(sprintf('[%s] This command can\'t be executed on <error>SQLite</error>!', $this->currentTime()));
+ $output->writeln(sprintf('[%s] This command can\'t be executed on <error>SQLite</error>!', date('d-m-y H:i:s')));
return 1;
}
@@ -38,11 +38,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
$em->getConnection()->beginTransaction();
try {
$nbRows = $this->updateTrends();
- $output->writeln(sprintf('[%s] <info>%s</info> rows updated', $this->currentTime(), $nbRows));
+ $output->writeln(sprintf('[%s] <info>%s</info> rows updated', date('d-m-y H:i:s'), $nbRows));
$em->getConnection()->commit();
} catch (\Exception $e) {
- $output->writeln(sprintf('[%s] <error>Rollbacking</error> because of %s', $this->currentTime(), $e));
+ $output->writeln(sprintf('[%s] <error>Rollbacking</error> because of %s', date('d-m-y H:i:s'), $e));
$em->getConnection()->rollback();
$em->close();
@@ -89,9 +89,4 @@ private function updateTrends()
return $nbRows;
}
-
- private function currentTime()
- {
- return date('d-m-y H:i:s');
- }
}
View
66 src/Knp/Bundle/KnpBundlesBundle/Command/MigrateCommitsCommand.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Knp\Bundle\KnpBundlesBundle\Command;
+
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
+
+use Pagerfanta\Pagerfanta;
+use Pagerfanta\Adapter\DoctrineORMAdapter;
+
+use Knp\Bundle\KnpBundlesBundle\Entity\Bundle;
+use Knp\Bundle\KnpBundlesBundle\Github\Repo;
+
+/**
+ * @todo Remove this command on next week or so
+ */
+class MigrateCommitsCommand extends ContainerAwareCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setDefinition(array())
+ ->setName('kb:migrate:commits')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ /** @var $repo Repo */
+ $em = $this->getContainer()->get('doctrine.orm.entity_manager');
+ $repo = $this->getContainer()->get('knp_bundles.github_repository_api');
+
+ $page = 1;
+ $pager = new Pagerfanta(new DoctrineORMAdapter($em->getRepository('KnpBundlesBundle:Bundle')->queryAllSortedBy('updatedAt'), false));
+ $pager
+ ->setMaxPerPage(100)
+ ->setCurrentPage($page, false, true)
+ ;
+
+ if (1 === $page) {
+ $this->output->writeln(sprintf('[%s] Loaded <comment>%d</comment> bundles from the DB', date('d-m-y H:i:s'), $pager->getNbResults()));
+ }
+
+ do {
+ /** @var $bundle Bundle */
+ foreach ($pager as $bundle) {
+ // Check that API not failed
+ if (!$repo->updateCommits($bundle)) {
+ // Sleep a while, and check again
+ sleep(60);
+
+ $repo->updateCommits($bundle);
+ }
+ }
+
+ $this->output->writeln(sprintf('[%s] Migrated %d from %d bundles', date('d-m-y H:i:s'), $page * 100, $pager->getNbResults()));
+
+ ++$page;
+ } while ($pager->haveToPaginate() && $pager->setCurrentPage($page, false, true));
+
+ return 0;
+ }
+}
View
13 src/Knp/Bundle/KnpBundlesBundle/Consumer/UpdateBundleConsumer.php
@@ -7,8 +7,8 @@
use Knp\Bundle\KnpBundlesBundle\Entity\Bundle;
use Knp\Bundle\KnpBundlesBundle\Entity\Score;
use Knp\Bundle\KnpBundlesBundle\Entity\Owner;
-use Knp\Bundle\KnpBundlesBundle\Entity\OwnerManager;
use Knp\Bundle\KnpBundlesBundle\Indexer\SolrIndexer;
+use Knp\Bundle\KnpBundlesBundle\Manager\OwnerManager;
use Knp\Bundle\KnpBundlesBundle\Travis\Travis;
use OldSound\RabbitMqBundle\RabbitMq\ConsumerInterface;
@@ -43,22 +43,22 @@ class UpdateBundleConsumer implements ConsumerInterface
private $em;
/**
- * @var Knp\Bundle\KnpBundlesBundle\Entity\OwnerManager
+ * @var OwnerManager
*/
private $ownerManager;
/**
- * @var Knp\Bundle\KnpBundlesBundle\Indexer\SolrIndexer
+ * @var SolrIndexer
*/
private $indexer;
/**
- * @var Knp\Bundle\KnpBundlesBundle\Github\Repo
+ * @var Repo
*/
private $githubRepoApi;
/**
- * @var Knp\Bundle\KnpBundlesBundle\Travis\Travis
+ * @var Travis
*/
private $travis;
@@ -137,9 +137,8 @@ public function execute(AMQPMessage $msg)
try {
if (!$this->githubRepoApi->update($bundle)) {
if ($this->logger) {
- $this->logger->warn(sprintf('Update failed, bundle "%s" will be removed', $bundle->getName()));
+ $this->logger->warn(sprintf('Update of "%s" failed', $bundle->getName()));
}
- $this->removeBundle($bundle);
return;
}
View
58 src/Knp/Bundle/KnpBundlesBundle/Controller/BundleController.php
@@ -8,9 +8,9 @@
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Pagerfanta\Pagerfanta;
use Pagerfanta\Adapter\SolariumAdapter;
+use Knp\Bundle\KnpBundlesBundle\Entity\Activity;
use Knp\Bundle\KnpBundlesBundle\Entity\Bundle;
use Knp\Bundle\KnpBundlesBundle\Entity\Developer;
-use Knp\Bundle\KnpBundlesBundle\Updater\Exception\UserNotFoundException;
class BundleController extends BaseController
{
@@ -44,10 +44,9 @@ public function searchAction(Request $request)
}
// Skip search if query matches exactly one bundle name, and such was found in database
- if (!$request->isXmlHttpRequest() && preg_match('/^[a-z0-9-]+\/[a-z0-9-\.]+$/i', $query)) {
+ if (!$request->isXmlHttpRequest() && preg_match('/^[a-z0-9-]+\/[a-z0-9-]+$/i', $query)) {
list($ownerName, $name) = explode('/', $query);
- /* @var $bundle Bundle */
$bundle = $this->getRepository('Bundle')->findOneBy(array('ownerName' => $ownerName, 'name' => $name));
if ($bundle) {
return $this->redirect($this->generateUrl('bundle_show', array('ownerName' => $ownerName, 'name' => $name, '_format' => $format)));
@@ -223,7 +222,8 @@ public function listAction(Request $request, $sort)
$this->highlightMenu('bundles');
- $owners = $this->getRepository('Developer')->findAllSortedBy('createdAt', 20);
+ $developers = $this->getRepository('Developer')->findAllSortedBy('createdAt', 20);
+ $activities = $this->getRepository('Activity')->findAllSortedBy('createdAt', 10);
$graphPeriod = $this->container->getParameter('knp_bundles.bundle.graph.main_page.period');
@@ -235,7 +235,8 @@ public function listAction(Request $request, $sort)
)
),
'bundles' => $paginator,
- 'developers' => $owners,
+ 'developers' => $developers,
+ 'activities' => $activities,
'sort' => $sort,
'sortLegends' => $this->sortLegends
));
@@ -301,7 +302,7 @@ public function addAction(Request $request)
if (!$error && ($request->isXmlHttpRequest() || 'POST' === $request->getMethod())) {
$bundle = trim(str_replace(array('http://github.com', 'https://github.com', '.git'), '', $bundle), '/');
- if (preg_match('/^[a-z0-9-]+\/[a-z0-9-\.]+$/i', $bundle)) {
+ if (preg_match('/^[a-z0-9-]+\/[a-z0-9-]+$/i', $bundle)) {
list($ownerName, $name) = explode('/', $bundle);
$url = $this->generateUrl('bundle_show', array('ownerName' => $ownerName, 'name' => $name));
@@ -317,22 +318,14 @@ public function addAction(Request $request)
if (!$error) {
/** @var $updater \Knp\Bundle\KnpBundlesBundle\Updater\Updater */
$updater = $this->get('knp_bundles.updater');
- $updater->setUp();
- try {
- $valid = $updater->addBundle($bundle, false, true);
-
- if ($valid) {
- if (!$request->isXmlHttpRequest()) {
- return $this->redirect($url);
- }
- $message = '<strong>Hey, friend!</strong> Thanks for adding <a href="'.$url.'">your bundle</a> to our database!';
- } else {
- $error = true;
- $message = 'Specified repo is not valid Symfony2 bundle!';
+ if ($updater->addBundle($bundle)) {
+ if (!$request->isXmlHttpRequest()) {
+ return $this->redirect($url);
}
- } catch (UserNotFoundException $e) {
+ $message = '<strong>Hey, friend!</strong> Thanks for adding <a href="'.$url.'">your bundle</a> to our database!';
+ } else {
$error = true;
- $message = 'Specified user was not found on GitHub.';
+ $message = 'Specified repository is not valid Symfony2 bundle!';
}
}
} else {
@@ -360,32 +353,19 @@ public function addAction(Request $request)
public function changeUsageStatusAction($ownerName, $name)
{
/* @var $bundle Bundle */
- $bundle = $this->getRepository('Bundle')->findOneByOwnerNameAndName($ownerName, $name);
+ $bundle = $this->getRepository('Bundle')->findOneBy(array('ownerName' => $ownerName, 'name' => $name));
if (!$bundle) {
throw new NotFoundHttpException(sprintf('The bundle "%s/%s" does not exist', $ownerName, $name));
}
- $params = array('ownerName' => $ownerName, 'name' => $name);
-
- if (!$owner = $this->get('security.context')->getToken()->getUser()) {
- return $this->redirect($this->generateUrl('bundle_show', $params));
- }
- $em = $this->get('doctrine')->getEntityManager();
-
- if ($owner->isUsingBundle($bundle)) {
- $bundle->updateScore(-5);
-
- $bundle->removeRecommender($owner);
- } else {
- $bundle->updateScore(5);
-
- $bundle->addRecommender($owner);
+ $url = $this->generateUrl('bundle_show', array('ownerName' => $ownerName, 'name' => $name));
+ if (!$developer = $this->get('security.context')->getToken()->getUser()) {
+ return $this->redirect($url);
}
- $em->persist($bundle);
- $em->flush();
+ $this->get('knp_bundles.bundle.manager')->manageBundleRecommendation($bundle, $developer);
- return $this->redirect($this->generateUrl('bundle_show', $params));
+ return $this->redirect($url);
}
public function searchByKeywordAction(Request $request, $slug)
View
82 src/Knp/Bundle/KnpBundlesBundle/DataFixtures/ORM/Data.php
@@ -225,7 +225,7 @@ public function load(ObjectManager $manager)
/* @var $contributor Entity\Developer */
$contributor = array_pop($contributors);
- $bundle = $this->makeBundle($developer, $i, $contributor);
+ $bundle = $this->makeBundle($manager, $developer, $i, $contributor);
if ($i%5 == 0) {
$bundle->setLastTweetedAt(new \DateTime());
@@ -279,26 +279,23 @@ public function load(ObjectManager $manager)
foreach ($organizations as $organization) {
for ($i = 1; $i < rand(2, 7); $i++) {
- $manager->persist($this->makeBundle($organization, $i));
+ $manager->persist($this->makeBundle($manager, $organization, $i));
}
}
$manager->flush();
}
- protected function makeBundle(Entity\Owner $owner, $i, $contributor = null)
+ protected function makeBundle($manager, Entity\Owner $owner, $i, $contributor = null)
{
$trilean = array(true, false, null);
$bundle = new Entity\Bundle();
$bundle->fromArray(array(
'name' => ucfirst($owner->getName()).$i.'FooBundle',
- 'ownerName' => $owner->getName(),
- 'owner' => $owner,
'description' => $this->descriptions[mt_rand(0, 4)],
'homepage' => ($i%2) ? 'Bundle'.$i.'.com' : null,
'readme' => str_replace('__BUNDLE__', "the bundle number: {$i}", $this->readme),
- 'tags' => ($i%2) ? array('1.0', '1.1') : array(),
'usesTravisCi' => ($i%2) ? false : true,
'composerName' => ($i%2) ? null : 'knplabs/knp-menu-bundle',
'symfonyVersions' => array(
@@ -310,47 +307,50 @@ protected function makeBundle(Entity\Owner $owner, $i, $contributor = null)
'travisCiBuildStatus' => ($i%2 == 0) ? $trilean[$i%3] : null,
'nbFollowers' => $i*10,
'nbForks' => $i,
- 'lastCommitAt' => \DateTime::createFromFormat('Y-m-d', sprintf('2012-07-%d', $i)),
- 'lastCommits' => array(
- array(
- 'commit' => array(
- 'author' => array(
- 'date' => '2010-05-16T09:58:32-09:00',
- 'name' => $owner->getFullName(),
- 'email' => $owner->getEmail()
- ),
- 'committer' => array(
- 'date' => '2010-05-16T09:58:32-09:00',
- 'name' => $owner->getFullName(),
- 'login' => $owner->getName()
- ),
- 'url' => 'http://github.com',
- 'message' => 'Fix something on this Bundle',
- ),
- ),
- array(
- 'commit' => array(
- 'author' => array(
- 'date' => '2010-05-16T09:58:32-07:00',
- 'name' => $owner->getFullName(),
- 'email' => $owner->getEmail()
- ),
- 'committer' => array(
- 'date' => '2010-05-16T09:58:32-07:00',
- 'name' => $owner->getFullName(),
- 'email' => $owner->getEmail()
- ),
- 'url' => 'http://github.com',
- 'message' => 'Commit something on this bundle',
- ),
- ),
- ),
'isFork' => false,
'contributors' => $contributor ? array($contributor) : array(),
'canonicalConfig' => ($i%2 == 0) ? $this->canonicalConfigDump : null,
'nbRecommenders' => rand(0, 90),
));
+ $commits = array(
+ array(
+ 'date' => '2010-05-16T09:58:32-09:00',
+ 'author' => $owner instanceof Entity\Developer ? $owner->getName() : 'Random Person',
+ 'message' => 'Fix something on this Bundle',
+ ),
+ array(
+ 'date' => '2010-05-16T09:58:32-07:00',
+ 'author' => 'Fake Name',
+ 'message' => 'Commit something on this bundle',
+ ),
+ );
+
+ foreach ($commits as $commit) {
+ $lastCommitAt = new \DateTime();
+ $lastCommitAt->setTimestamp(strtotime($commit['date']));
+
+ $bundle->setLastCommitAt($lastCommitAt);
+
+ $activity = new Entity\Activity();
+ $activity->setType(Entity\Activity::ACTIVITY_TYPE_COMMIT);
+ $activity->setMessage(strtok($commit['message'], "\n\r"));
+ $activity->setCreatedAt($lastCommitAt);
+ $activity->setBundle($bundle);
+
+ if ($owner->getName() == $commit['author']) {
+ $owner->setLastCommitAt($lastCommitAt);
+
+ $activity->setDeveloper($owner);
+ } else {
+ $activity->setAuthor($commit['author']);
+ }
+
+ $manager->persist($activity);
+ }
+
+ $owner->addBundle($bundle);
+
return $bundle;
}
}
View
315 src/Knp/Bundle/KnpBundlesBundle/Entity/Activity.php
@@ -0,0 +1,315 @@
+<?php
+
+namespace Knp\Bundle\KnpBundlesBundle\Entity;
+
+use Doctrine\ORM\Mapping as ORM;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+
+/**
+ * @ORM\Entity(repositoryClass="Knp\Bundle\KnpBundlesBundle\Repository\ActivityRepository", readOnly=true)
+ * @ORM\Table(
+ * name="activities",
+ * indexes={
+ * @ORM\Index(name="type_state", columns={"type", "state"}),
+ * @ORM\Index(name="created_at", columns={"createdAt"})
+ * }
+ * )
+ */
+class Activity
+{
+ const ACTIVITY_TYPE_COMMIT = 1;
+ const ACTIVITY_TYPE_WATCH = 2;
+ const ACTIVITY_TYPE_STAR = 3;
+ const ACTIVITY_TYPE_ISSUE = 5;
+ const ACTIVITY_TYPE_PR = 6;
+ const ACTIVITY_TYPE_FORK = 7;
+ const ACTIVITY_TYPE_DOWNLOAD = 8;
+
+ const ACTIVITY_TYPE_TRAVIS_BUILD = 10;
+ const ACTIVITY_TYPE_RECOMMEND = 15;
+// const ACTIVITY_TYPE_FAVOR = 16;
+
+// const ACTIVITY_TYPE_ASKED = 20;
+// const ACTIVITY_TYPE_ANSWERED = 21;
+// const ACTIVITY_TYPE_VOTED = 22;
+
+ const ACTIVITY_TYPE_TWEETED = 30;
+
+ const STATE_UNKNOWN = 0;
+ const STATE_OPEN = 1;
+ const STATE_CLOSED = 2;
+ const STATE_FIXED = 3;
+
+ /**
+ * @ORM\Column(name="id", type="integer")
+ * @ORM\Id
+ * @ORM\GeneratedValue(strategy="AUTO")
+ *
+ * @var integer
+ */
+ private $id;
+
+ /**
+ * @ORM\Column(type="integer")
+ *
+ * @var integer
+ */
+ private $type;
+
+ /**
+ * @ORM\Column(type="integer")
+ *
+ * @var integer
+ */
+ private $state = self::STATE_UNKNOWN;
+
+ /**
+ * @ORM\Column(type="datetime")
+ *
+ * @var \DateTime
+ */
+ private $createdAt;
+
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ *
+ * @var string
+ */
+ private $message;
+
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ *
+ * @var string
+ */
+ private $author;
+
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ *
+ * @var string
+ */
+ private $bundleName;
+
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ *
+ * @var string
+ */
+ private $bundleOwnerName;
+
+ /**
+ * Bundle
+ *
+ * @ORM\ManyToOne(targetEntity="Bundle", inversedBy="activities")
+ *
+ * @var Bundle
+ */
+ private $bundle;
+
+ /**
+ * Developer
+ *
+ * @ORM\ManyToOne(targetEntity="Developer", inversedBy="activities")
+ *
+ * @var Developer
+ */
+ private $developer;
+
+ public function __construct()
+ {
+ $this->createdAt = new \DateTime();
+ }
+
+ /**
+ * @return integer
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return integer
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * @param integer $type
+ */
+ public function setType($type)
+ {
+ $this->type = (int) $type;
+ }
+
+ /**
+ * @return integer
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ /**
+ * @param integer $state
+ */
+ public function setState($state)
+ {
+ $this->state = (int) $state;
+ }
+
+ /**
+ * @return \DateTime
+ */
+ public function getCreatedAt()
+ {
+ return $this->createdAt;
+ }
+
+ /**
+ * @param \DateTime $createdAt
+ */
+ public function setCreatedAt(\DateTime $createdAt)
+ {
+ $this->createdAt = $createdAt;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * @param string $message
+ */
+ public function setMessage($message)
+ {
+ $this->message = $message;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getAuthor()
+ {
+ return $this->author;
+ }
+
+ /**
+ * @param string $author
+ */
+ public function setAuthor($author)
+ {
+ $this->author = $author;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBundleName()
+ {
+ return $this->bundleName;
+ }
+
+ /**
+ * @param string $bundleName
+ */
+ public function setBundleName($bundleName)
+ {
+ $this->bundleName = $bundleName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBundleOwnerName()
+ {
+ return $this->bundleOwnerName;
+ }
+
+ /**
+ * @param string $bundleOwnerName
+ */
+ public function setBundleOwnerName($bundleOwnerName)
+ {
+ $this->bundleOwnerName = $bundleOwnerName;
+ }
+
+ /**
+ * @return null|Bundle
+ */
+ public function getBundle()
+ {
+ return $this->bundle;
+ }
+
+ /**
+ * @param Bundle $bundle
+ */
+ public function setBundle(Bundle $bundle)
+ {
+ $this->bundle = $bundle;
+ $this->bundleName = $bundle->getName();
+ $this->bundleOwnerName = $bundle->getOwnerName();
+
+ $bundle->addActivity($this);
+ }
+
+ /**
+ * @return null|Developer
+ */
+ public function getDeveloper()
+ {
+ return $this->developer;
+ }
+
+ /**
+ * @param Developer $developer
+ */
+ public function setDeveloper(Developer $developer)
+ {
+ $this->developer = $developer;
+ $this->author = $developer->getName();
+
+ $developer->addActivity($this);
+ }
+
+ /**
+ * @param Activity $activity
+ *
+ * @return boolean
+ */
+ public function isEqualTo(Activity $activity)
+ {
+ if ($activity->getBundle()->getId() !== $this->bundle->getId()) {
+ return false;
+ }
+
+ // Compare developers only if actual activity has one
+ if (null !== $this->developer && $activity->getDeveloper()->getId() !== $this->developer->getId()) {
+ return false;
+ }
+
+ if ($activity->getType() !== $this->type) {
+ return false;
+ }
+
+ if ($activity->getState() !== $this->state) {
+ return false;
+ }
+
+ // Compare dates only when state of activity allows it
+ if (self::STATE_FIXED !== $this->state && $activity->getCreatedAt()->getTimestamp() !== $this->createdAt->getTimestamp()) {
+ return false;
+ }
+
+ return true;
+ }
+}
View
232 src/Knp/Bundle/KnpBundlesBundle/Entity/Bundle.php
@@ -72,6 +72,8 @@ class Bundle
*
* @ORM\ManyToOne(targetEntity="Owner", inversedBy="bundles")
* @ORM\JoinColumn(name="owner_id", referencedColumnName="id", nullable=false)
+ *
+ * @var Collection
*/
protected $owner;
@@ -83,6 +85,8 @@ class Bundle
* joinColumns={@ORM\JoinColumn(name="bundle_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="knpbundles_owner_id", referencedColumnName="id")}
* )
+ *
+ * @var Collection
*/
protected $recommenders;
@@ -133,6 +137,8 @@ class Bundle
* Internal scores
*
* @ORM\OneToMany(targetEntity="Score", mappedBy="bundle", fetch="EXTRA_LAZY")
+ *
+ * @var Collection
*/
protected $scores;
@@ -140,6 +146,7 @@ class Bundle
* Latest score's details
*
* @ORM\Column(type="array", nullable=true)
+ *
* @var array
*/
protected $scoreDetails = array();
@@ -166,21 +173,7 @@ class Bundle
protected $lastCommitAt;
/**
- * The last commits on this bundle repo
- *
- * @ORM\Column(type="text")
- */
- protected $lastCommits;
-
- /**
- * Released tags are Git tags
- *
- * @ORM\Column(type="text")
- */
- protected $tags;
-
- /**
- * Date of the last succesful GitHub check
+ * Date of the last successful GitHub check
*
* @ORM\Column(type="date", nullable=true)
*/
@@ -262,6 +255,8 @@ class Bundle
* joinColumns={@ORM\JoinColumn(name="bundle_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="keyword_id", referencedColumnName="id")}
* )
+ *
+ * @var Collection
*/
protected $keywords;
@@ -282,7 +277,7 @@ class Bundle
/**
* @ORM\Column(type="integer")
*/
- protected $nbRecommenders;
+ protected $nbRecommenders = 0;
/**
* Date when bundle was tweeted from knplabs account.
@@ -292,53 +287,46 @@ class Bundle
protected $lastTweetedAt;
/**
- * Not saved variable, it's used to simplify validation when updating bundles
+ * @ORM\OneToMany(targetEntity="Activity", mappedBy="bundle", fetch="EXTRA_LAZY", cascade={"persist"}, orphanRemoval=true)
*
- * @var boolean
+ * @var Collection
*/
- protected $valid = false;
+ protected $activities;
+ /**
+ * @param null|string $fullName
+ */
public function __construct($fullName = null)
{
if ($fullName) {
list($this->ownerName, $this->name) = explode('/', $fullName);
}
- $this->createdAt = new \DateTime();
- $this->updatedAt = new \DateTime();
+ $this->createdAt = new \DateTime();
+ $this->updatedAt = new \DateTime();
$this->lastCommitAt = new \DateTime('2010-01-01');
- $this->lastCommits = serialize(array());
- $this->tags = serialize(array());
-
+ $this->activities = new ArrayCollection();
$this->contributors = new ArrayCollection();
- $this->scores = new ArrayCollection();
- $this->keywords = new ArrayCollection();
- $this->state = self::STATE_UNKNOWN;
- $this->nbRecommenders = 0;
+ $this->scores = new ArrayCollection();
+ $this->keywords = new ArrayCollection();
}
- /**
- * @return boolean
- */
- public function isValid()
+ public function isInitialized()
{
- return $this->valid;
+ // Using the fact that a repo should have at least one declared fork:
+ // itself
+ return $this->nbForks > 0;
}
/**
- * @param boolean $state
+ * Get id
+ *
+ * @return string
*/
- public function setIsValid($state)
- {
- $this->valid = (bool) $state;
- }
-
- public function isInitialized()
+ public function getId()
{
- // Using the fact that a repo should have at least one declared fork:
- // itself
- return $this->nbForks > 0;
+ return $this->id;
}
/**
@@ -442,73 +430,6 @@ public function setComposerName($name)
}
/**
- * Get tags
- *
- * @return array
- */
- public function getTags()
- {
- return unserialize($this->tags);
- }
-
- /**
- * Set tags
- *
- * @param array $tags
- */
- public function setTags(array $tags)
- {
- $this->tags = serialize($tags);
- }
-
- public function getLastTagName()
- {
- $tags = $this->getTags();
- if (empty($tags)) {
- return null;
- }
-
- return reset($tags);
- }
-
- /**
- * Get lastCommits
- *
- * @param integer $nb
- *
- * @return array
- */
- public function getLastCommits($nb = 10)
- {
- $lastCommits = array_slice(unserialize($this->lastCommits), 0, $nb);
- foreach ($lastCommits as $i => $commitInfo) {
- $lastCommits[$i]['message_first_line'] = strtok($commitInfo['commit']['message'], "\n\r");
- $lastCommits[$i]['author'] = $commitInfo['commit']['committer']['name'];
- $lastCommits[$i]['date'] = $commitInfo['commit']['committer']['date'];
- }
-
- return $lastCommits;
- }
-
- /**
- * Set lastCommits
- *
- * @param array $lastCommits
- */
- public function setLastCommits(array $lastCommits)
- {
- foreach($lastCommits as $index => $commit) {
- $lastCommits[$index]['bundle_name'] = $this->getName();
- $lastCommits[$index]['bundle_ownerName'] = $this->getOwnerName();
- }
- $this->lastCommits = serialize($lastCommits);
-
- $lastCommitAt = new \DateTime();
- $lastCommitAt->setTimestamp(strtotime($lastCommits[0]['commit']['committer']['date']));
- $this->setLastCommitAt($lastCommitAt);
- }
-
- /**
* Get readme
*
* @return string
@@ -528,7 +449,6 @@ public function setReadme($readme)
$this->readme = $readme;
}
-
/**
* Get license
*
@@ -572,6 +492,8 @@ public function setScore($score)
/**
* Get all historical scores indexed by date
*
+ * @param integer $limit
+ *
* @return array
*/
public function getScores($limit = null)
@@ -642,8 +564,7 @@ public function getLastCommitAt()
/**
* Set lastCommitAt
*
- * @param \DateTime
- * @return null
+ * @param \DateTime $lastCommitAt
*/
public function setLastCommitAt(\DateTime $lastCommitAt)
{
@@ -771,16 +692,6 @@ public function setName($name)
}
/**
- * Get id
- *
- * @return string
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
* Get ownername
*
* @return string
@@ -809,11 +720,12 @@ public function getOwner()
}
/**
- * @param null|Owner $owner
+ * @param Owner $owner
*/
- public function setOwner(Owner $owner = null)
+ public function setOwner(Owner $owner)
{
$this->owner = $owner;
+ $this->ownerName = $owner->getName();
$this->ownerType = $owner instanceof Organization ? 'organization' : 'developer';
}
@@ -988,18 +900,6 @@ public function getContributorNames()
return $names;
}
- /** @ORM\PreUpdate */
- public function markAsUpdated()
- {
- $this->updatedAt = new \DateTime();
- }
-
- /** @ORM\PrePersist */
- public function markAsCreated()
- {
- $this->createdAt = $this->updatedAt = new \DateTime();
- }
-
/**
* Get the first part of the name, without Bundle
*
@@ -1018,7 +918,6 @@ public function getShortName()
public function toBigArray()
{
return $this->toSmallArray() + array(
- 'lastCommits' => $this->getLastCommits(),
'readme' => $this->getReadme()
);
}
@@ -1036,7 +935,6 @@ public function toSmallArray()
'nbForks' => $this->getNbForks(),
'createdAt' => $this->getCreatedAt()->getTimestamp(),
'lastCommitAt' => $this->getLastCommitAt()->getTimestamp(),
- 'tags' => $this->getTags(),
'contributors' => $this->getContributorNames()
);
}
@@ -1093,6 +991,8 @@ public function addRecommender(Developer $developer)
$this->recommenders[] = $developer;
$this->nbRecommenders++;
+
+ $this->updateScore(5);
}
public function removeRecommender(Developer $developer)
@@ -1101,6 +1001,16 @@ public function removeRecommender(Developer $developer)
$this->recommenders->removeElement($developer);
$this->nbRecommenders--;
+
+ $this->updateScore(-5);
+ }
+
+ /**
+ * @param integer $nbRecommenders
+ */
+ public function setNbRecommenders($nbRecommenders)
+ {
+ $this->nbRecommenders = $nbRecommenders;
}
/**
@@ -1133,11 +1043,19 @@ public function countKeywords()
return count($this->keywords);
}
+ /**
+ * @param Keyword $keyword
+ *
+ * @return boolean
+ */
public function hasKeyword(Keyword $keyword)
{
return $this->keywords->contains($keyword);
}
+ /**
+ * @param Keyword $keyword
+ */
public function addKeyword(Keyword $keyword)
{
if (!$this->hasKeyword($keyword)) {
@@ -1146,6 +1064,22 @@ public function addKeyword(Keyword $keyword)
}
/**
+ * @return Collection
+ */
+ public function getActivities()
+ {
+ return $this->activities;
+ }
+
+ /**
+ * @param Activity $activity
+ */
+ public function addActivity(Activity $activity)
+ {
+ $this->activities[] = $activity;
+ }
+
+ /**
* Get required versions of Symfony
*
* @return array
@@ -1206,14 +1140,6 @@ public function setCanonicalConfig($canonicalConfig)
}
/**
- * @param integer $nbRecommenders
- */
- public function setNbRecommenders($nbRecommenders)
- {
- $this->nbRecommenders = $nbRecommenders;
- }
-
- /**
* Set lastTweetedAt
*
* @param \DateTime $lastTweetedAt
@@ -1232,4 +1158,16 @@ public function getLastTweetedAt()
{
return $this->lastTweetedAt;
}
+
+ /** @ORM\PreUpdate */
+ public function markAsUpdated()
+ {
+ $this->updatedAt = new \DateTime();
+ }
+
+ /** @ORM\PrePersist */
+ public function markAsCreated()
+ {
+ $this->createdAt = $this->updatedAt = new \DateTime();
+ }
}
View
168 src/Knp/Bundle/KnpBundlesBundle/Entity/Developer.php
@@ -21,48 +21,51 @@ class Developer extends Owner implements UserInterface
private $company;
/**
- * @ORM\Column(type="string", length=255, nullable=true)
- */
- private $githubId;
-
- /**
- * @ORM\Column(type="string", length=255, nullable=true)
+ * Date of the last Git commit
+ *
+ * @ORM\Column(type="date")
*/
- private $sensioId;
+ private $lastCommitAt;
/**
- * Organizations where developer part of
+ * Organizations where developer belongs to
*
- * @var ArrayCollection
* @ORM\ManyToMany(targetEntity="Organization", mappedBy="members")
+ *
+ * @var Collection
*/
private $organizations;
/**
- * Bundles this User recommended to
+ * Bundles recommended by this user
*
- * @var ArrayCollection
* @ORM\ManyToMany(targetEntity="Bundle", mappedBy="recommenders")
+ *
+ * @var Collection
*/
private $recommendedBundles;
/**
* Bundles this User contributed to
*
- * @var ArrayCollection
* @ORM\ManyToMany(targetEntity="Bundle", mappedBy="contributors")
+ *
+ * @var Collection
*/
private $contributionBundles;
/**
- * local cache, not persisted
+ * @ORM\OneToMany(targetEntity="Activity", mappedBy="developer", fetch="EXTRA_LAZY", cascade={"persist"})
+ *
+ * @var Collection
*/
- private $lastCommitsCache;
+ private $activities;
public function __construct()
{
- $this->organizations = new ArrayCollection();
- $this->recommendedBundles = new ArrayCollection();
+ $this->activities = new ArrayCollection();
+ $this->organizations = new ArrayCollection();
+ $this->recommendedBundles = new ArrayCollection();
$this->contributionBundles = new ArrayCollection();
parent::__construct();
@@ -85,35 +88,23 @@ public function getCompany()
}
/**
- * @param $githubId
- */
- public function setGithubId($githubId)
- {
- $this->githubId = $githubId;
- }
-
- /**
- * @return mixed
- */
- public function getGithubId()
- {
- return $this->githubId;
- }
-
- /**
- * @param $sensioId
+ * Get the date of the last commit
+ *
+ * @return \DateTime
*/
- public function setSensioId($sensioId)
+ public function getLastCommitAt()
{
- $this->sensioId = $sensioId;
+ return $this->lastCommitAt;
}
/**
- * @return mixed
+ * Set lastCommitAt
+ *
+ * @param \DateTime $lastCommitAt
*/
- public function getSensioId()
+ public function setLastCommitAt(\DateTime $lastCommitAt)
{
- return $this->sensioId;
+ $this->lastCommitAt = $lastCommitAt;
}
/**
@@ -143,7 +134,7 @@ public function removeOrganization(Organization $organization)
/**
* Get organizations
*
- * @return ArrayCollection
+ * @return Collection
*/
public function getOrganizations()
{
@@ -151,29 +142,29 @@ public function getOrganizations()
}
/**
- * Add recommendedBundles
+ * Add recommended Bundle
*
- * @param Bundle $recommendedBundles
+ * @param Bundle $recommendedBundle
*/
- public function addRecommendedBundle(Bundle $recommendedBundles)
+ public function addRecommendedBundle(Bundle $recommendedBundle)
{
- $this->recommendedBundles[] = $recommendedBundles;
+ $this->recommendedBundles[] = $recommendedBundle;
}
/**
- * Remove recommendedBundles
+ * Remove recommended Bundle
*
- * @param Bundle $recommendedBundles
+ * @param Bundle $recommendedBundle
*/
- public function removeRecommendedBundle(Bundle $recommendedBundles)
+ public function removeRecommendedBundle(Bundle $recommendedBundle)
{
- $this->recommendedBundles->removeElement($recommendedBundles);
+ $this->recommendedBundles->removeElement($recommendedBundle);
}
/**
- * Get recommendedBundles
+ * Get recommended Bundles
*
- * @return ArrayCollection
+ * @return Collection
*/
public function getRecommendedBundles()
{
@@ -193,29 +184,29 @@ public function isUsingBundle(Bundle $bundle)
}
/**
- * Add contributionBundles
+ * Add contribution Bundle
*
- * @param Bundle $contributionBundles
+ * @param Bundle $contributionBundle
*/
- public function addContributionBundle(Bundle $contributionBundles)
+ public function addContributionBundle(Bundle $contributionBundle)
{
- $this->contributionBundles[] = $contributionBundles;
+ $this->contributionBundles[] = $contributionBundle;
}
/**
- * Remove contributionBundles
+ * Remove contribution Bundle
*
- * @param Bundle $contributionBundles
+ * @param Bundle $contributionBundle
*/
- public function removeContributionBundle(Bundle $contributionBundles)
+ public function removeContributionBundle(Bundle $contributionBundle)
{
- $this->contributionBundles->removeElement($contributionBundles);
+ $this->contributionBundles->removeElement($contributionBundle);
}
/**
* Get contributionBundles
*
- * @return ArrayCollection
+ * @return Collection
*/
public function getContributionBundles()
{
@@ -223,63 +214,27 @@ public function getContributionBundles()
}
/**
- * @param $lastCommitsCache
+ * @return Collection
*/
- public function setLastCommitsCache($lastCommitsCache)
+ public function getActivities()
{
- $this->lastCommitsCache = $lastCommitsCache;
+ return $this->activities;
}
/**
- * @return mixed
+ * @param Activity $activity
*/
- public function getLastCommitsCache()
+ public function addActivity(Activity $activity)
{
- return $this->lastCommitsCache;
+ $this->activities[] = $activity;
}
/**
- * Get the date of the last commit
- *
- * @return \DateTime
+ * @param Activity $activity
*/
- public function getLastCommitAt()
+ public function removeActivity(Activity $activity)
{
- $lastCommits = $this->getLastCommits(1);
- if (empty($lastCommits)) {
- return null;
- }
- $lastCommit = $lastCommits[0];
- $date = new \DateTime($lastCommit['committed_date']);
-
- return $date;
- }
-
- /**
- * Get the more recent commits by this user
- *
- * @param integer $nb
- * @return array
- */
- public function getLastCommits($nb = 10)
- {
- if (null === $this->lastCommitsCache) {
- $commits = array();
- foreach ($this->getAllBundles() as $bundle) {
- foreach ($bundle->getLastCommits() as $commit) {
- if (isset($commit['author']['login']) && $commit['author']['login'] === $this->name) {
- $commits[] = $commit;
- }
- }
- }
- usort($commits, function($a, $b) {
- return strtotime($a['committed_date']) < strtotime($b['committed_date']);
- });
- $this->lastCommitsCache = $commits;
- }
- $commits = array_slice($this->lastCommitsCache, 0, $nb);
-
- return $commits;
+ $this->activities->removeElement($activity);
}
public function toSmallArray()
@@ -298,13 +253,6 @@ public function toSmallArray()
);
}
- public function toBigArray()
- {
- return $this->toSmallArray() + array(
- 'lastCommits' => $this->getLastCommits()
- );
- }
-
/**
* @return array
*/
View
56 src/Knp/Bundle/KnpBundlesBundle/Entity/Owner.php
@@ -68,13 +68,6 @@ class Owner
protected $location;
/**
- * Bundles the user owns
- *
- * @ORM\OneToMany(targetEntity="Bundle", mappedBy="owner")
- */
- protected $bundles;
-
- /**
* User creation date (on this website)
*
* @ORM\Column(type="datetime")
@@ -88,6 +81,23 @@ class Owner
*/
protected $score = 0;
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ */
+ protected $githubId;
+
+ /**
+ * @ORM\Column(type="string", length=255, nullable=true)
+ */
+ protected $sensioId;
+
+ /**
+ * Bundles the user owns
+ *
+ * @ORM\OneToMany(targetEntity="Bundle", mappedBy="owner")
+ */
+ protected $bundles;
+
public function __construct()
{
$this->bundles = new ArrayCollection();
@@ -265,6 +275,38 @@ public function getScore()
}
/**
+ * @param string $githubId
+ */
+ public function setGithubId($githubId)
+ {
+ $this->githubId = $githubId;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getGithubId()
+ {
+ return $this->githubId;
+ }
+
+ /**
+ * @param string $sensioId
+ */
+ public function setSensioId($sensioId)
+ {
+ $this->sensioId = $sensioId;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getSensioId()
+ {
+ return $this->sensioId;
+ }
+
+ /**
* Add bundles
*
* @param Bundle $bundle
View
31 src/Knp/Bundle/KnpBundlesBundle/Github/Organization.php
@@ -2,25 +2,25 @@
namespace Knp\Bundle\KnpBundlesBundle\Github;
-use Knp\Bundle\KnpBundlesBundle\Entity\Organization as EntityOrganization;
-use Knp\Bundle\KnpBundlesBundle\Repository\OwnerRepository;
-
use Github\HttpClient\ApiLimitExceedException;
use Symfony\Component\Console\Output\NullOutput;
+use Knp\Bundle\KnpBundlesBundle\Entity\Organization as EntityOrganization;
+use Knp\Bundle\KnpBundlesBundle\Manager\OwnerManager;
+
class Organization extends Owner
{
/**
- * @var OwnerRepository
+ * @var OwnerManager
*/
- private $repository;
+ private $manager;
/**
- * @param OwnerRepository $repository
+ * @param OwnerManager $manager
*/
- public function setRepository(OwnerRepository $repository)
+ public function setOwnerManager(OwnerManager $manager)
{
- $this->repository = $repository;
+ $this->manager = $manager;
}
/**
@@ -69,24 +69,23 @@ public function update(EntityOrganization $organization)
$this->updateOwner($organization, $data);
$membersData = $api->members()->all($organization->getName());
- if ($members = $this->updateMembers($membersData)) {
- $organization->setMembers($members);
+ // Can't access members info ? Skip it for now then.
+ if (empty($membersData) || isset($membersData['message'])) {
+ return true;
}
+ $organization->setMembers($this->updateMembers($membersData));
+
return true;
}
private function updateMembers($membersData)
{
$members = array();
- $api = new Developer($this->github, new NullOutput());
-
foreach ($membersData as $memberData) {
- if (!$member = $this->repository->findOneBy(array('name' => $memberData['login']))) {
- $member = $api->import($memberData['login']);
+ if ($member = $this->manager->createOwner($memberData['login'], 'developer')) {
+ $members[] = $member;
}
-
- $members[] = $member;
}
return $members;
View
39 src/Knp/Bundle/KnpBundlesBundle/Github/Owner.php
@@ -5,8 +5,8 @@
use Symfony\Component\Console\Output\OutputInterface;
use Github\Client;
-use Knp\Bundle\KnpBundlesBundle\Entity\Owner as EntityOwner;
use Knp\Bundle\KnpBundlesBundle\Entity\Developer as EntityDeveloper;
+use Knp\Bundle\KnpBundlesBundle\Entity\Owner as EntityOwner;
abstract class Owner implements OwnerInterface
{
@@ -25,7 +25,7 @@
protected $output;
/**
- * @param Client $github
+ * @param Client $github
* @param OutputInterface $output
*/
public function __construct(Client $github, OutputInterface $output)
@@ -75,23 +75,6 @@ public function setGithubClient($github)
}
/**
- * Fixes url.
- * Adds http protocol by default, when no protocol is specified.
- *
- * @param string $url
- * @return string
- */
- public function fixUrl($url)
- {
- $scheme = parse_url($url, PHP_URL_SCHEME);
- if (null === $scheme) {
- return 'http://'.$url;
- }
-
- return $url;
- }
-
- /**
* @param EntityOwner $owner
* @param array $data
*/
@@ -104,7 +87,25 @@ protected function updateOwner(EntityOwner $owner, array $data)
$owner->setUrl(isset($data['blog']) ? $this->fixUrl($data['blog']) : null);
if ($owner instanceof EntityDeveloper) {
+ $owner->setGithubId(isset($data['login']) ? $data['login'] : null);
$owner->setCompany(isset($data['company']) ? $data['company'] : null);
}
}
+
+ /**
+ * Fixes url.
+ * Adds http protocol by default, when no protocol is specified.
+ *
+ * @param string $url
+ * @return string
+ */
+ private function fixUrl($url)
+ {
+ $scheme = parse_url($url, PHP_URL_SCHEME);
+ if (null === $scheme) {
+ return 'http://'.$url;
+ }
+
+ return $url;
+ }
}
View
127 src/Knp/Bundle/KnpBundlesBundle/Github/Repo.php
@@ -3,44 +3,52 @@
namespace Knp\Bundle\KnpBundlesBundle\Github;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Process\PhpProcess;
use Github\Client;
+use Knp\Bundle\KnpBundlesBundle\Entity\Activity;
use Knp\Bundle\KnpBundlesBundle\Entity\Bundle;
-use Knp\Bundle\KnpBundlesBundle\Git;
+use Knp\Bundle\KnpBundlesBundle\Entity\Developer as EntityDeveloper;
use Knp\Bundle\KnpBundlesBundle\Event\BundleEvent;
+use Knp\Bundle\KnpBundlesBundle\Manager\OwnerManager;
+use Knp\Bundle\KnpBundlesBundle\Git;
class Repo
{
/**
* php-github-api instance used to request GitHub API
*
- * @var Client|null
+ * @var Client
*/
- protected $github = null;
+ private $github;
/**
- * @var Git\RepoManager|null
+ * @var Git\RepoManager
*/
- protected $gitRepoManager = null;
+ private $gitRepoManager;
/**
* Output buffer
*
- * @var null|OutputInterface
+ * @var OutputInterface
*/
- protected $output = null;
+ private $output;
/**
* @var EventDispatcherInterface
*/
- protected $dispatcher;
+ private $dispatcher;
+
+ /**
+ * @var OwnerManager
+ */
+ private $ownerManager;
/**
* @var string
@@ -52,15 +60,22 @@ class Repo
* @param OutputInterface $output
* @param Git\RepoManager $gitRepoManager
* @param EventDispatcherInterface $dispatcher
+ * @param OwnerManager $ownerManager
*/
- public function __construct(Client $github, OutputInterface $output, Git\RepoManager $gitRepoManager, EventDispatcherInterface $dispatcher)
+ public function __construct(Client $github, OutputInterface $output, Git\RepoManager $gitRepoManager, EventDispatcherInterface $dispatcher, OwnerManager $ownerManager)
{
$this->github = $github;
$this->output = $output;
$this->gitRepoManager = $gitRepoManager;
$this->dispatcher = $dispatcher;
+ $this->ownerManager = $ownerManager;
}
+ /**
+ * @param Bundle $bundle
+ *
+ * @return boolean|Bundle
+ */
public function update(Bundle $bundle)
{
try {
@@ -78,9 +93,6 @@ public function update(Bundle $bundle)
if (!$this->updateCommits($bundle)) {
return false;
}
- if (!$this->updateTags($bundle)) {
- return false;
- }
$event = new BundleEvent($bundle);
$this->dispatcher->dispatch(BundleEvent::UPDATE_SCORE, $event);
@@ -128,7 +140,22 @@ public function updateCommits(Bundle $bundle)
if (empty($commits) || isset($data['message'])) {
return false;
}
- $bundle->setLastCommits($commits);
+
+ /* @var $developer EntityDeveloper */
+ foreach ($commits as $commit) {
+ $lastCommitAt = new \DateTime();
+ $lastCommitAt->setTimestamp(strtotime($commit['commit']['committer']['date']));
+
+ $developer = $this->ownerManager->createOwner($commit['commiter']['login'], 'developer', false);
+ $developer->setLastCommitAt($lastCommitAt);
+
+ $activity = new Activity();
+ $activity->setType(Activity::ACTIVITY_TYPE_COMMIT);
+ $activity->setMessage(strtok($commit['commit']['message'], "\n\r"));
+ $activity->setCreatedAt($lastCommitAt);
+ $activity->setBundle($bundle);
+ $activity->setDeveloper($developer);
+ }
return true;
}
@@ -144,19 +171,6 @@ public function updateFiles(Bundle $bundle, array $onlyFiles = null)
return false;
}
foreach ($files as $data) {
- if (!$bundle->isValid() && false !== strpos($data['name'], 'Bundle.php')) {
- if (null !== $onlyFiles && !in_array('sf', $onlyFiles)) {
- continue;
- }
-
- $file = $api->show($bundle->getOwnerName(), $bundle->getName(), $data['name']);
- if (!isset($file['message']) && 'base64' == $file['encoding']) {
- $this->validateSymfonyBundle($bundle, $file['content']);
- }
-
- continue;
- }
-
switch ($data['name']) {
case 'LICENSE':
if (null !== $onlyFiles && !in_array('license', $onlyFiles)) {
@@ -267,23 +281,6 @@ public function updateSymfonyVersions(Bundle $bundle)
return true;
}
- public function updateTags(Bundle $bundle)
- {
- $this->output->write(' tags');
-
- $tags = array();
- $data = $this->github->api('repo')->tags($bundle->getOwnerName(), $bundle->getName());
- if ($data) {
- foreach ($data as $tag) {
- $tags[] = $tag['name'];
- }
- }
-
- $bundle->setTags($tags);
-
- return $bundle;
- }
-
public function fetchComposerKeywords(Bundle $bundle)
{
$file = $this->github->api('repo')->contents()->show($bundle->getOwnerName(), $bundle->getName(), 'composer.json');
@@ -315,6 +312,33 @@ public function getContributorNames(Bundle $bundle)
}
/**
+ * @param Bundle $bundle
+ *
+ * @return boolean
+ */
+ public function validate(Bundle $bundle)
+ {
+ $api = $this->github->api('repo')->contents();
+ $files = $api->show($bundle->getOwnerName(), $bundle->getName());
+ if (empty($files) || isset($files['message'])) {
+ return false;
+ }
+
+ foreach ($files as $data) {
+ if (false !== strpos($data['name'], 'Bundle.php')) {
+ $file = $api->show($bundle->getOwnerName(), $bundle->getName(), $data['name']);
+ if (!isset($file['message']) && 'base64' == $file['encoding']) {
+ return false !== strpos(base64_decode($file['content']), 'Symfony\\Component\\HttpKernel\\Bundle\\Bundle');
+ }
+
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Get output
*
* @return OutputInterface
@@ -441,21 +465,6 @@ public function setCanonicalConfiguration($canonicalConfiguration)
}
/**
- * Checks if '*Bundle.php' class use base class for Symfony bundle
- *
- * @param Bundle $bundle
- * @param string $content
- *
- * @return boolean
- */
- private function validateSymfonyBundle(Bundle $bundle, $content)
- {
- $bundle->setIsValid(false !== strpos(base64_decode($content), 'Symfony\\Component\\HttpKernel\\Bundle\\Bundle'));
-
- return $bundle->isValid();
- }
-
- /**
* Outputs a single config reference line
*
* @param string $text
View
167 src/Knp/Bundle/KnpBundlesBundle/Manager/BundleManager.php
@@ -0,0 +1,167 @@
+<?php
+
+namespace Knp\Bundle\KnpBundlesBundle\Manager;
+
+use Doctrine\Common\Persistence\ObjectManager;
+use Symfony\Component\Console\Output\NullOutput;
+
+use Github\Client;
+
+use Knp\Bundle\KnpBundlesBundle\Entity\Activity;
+use Knp\Bundle\KnpBundlesBundle\Entity\Bundle;
+use Knp\Bundle\KnpBundlesBundle\Entity\Developer;
+use Knp\Bundle\KnpBundlesBundle\Github\Repo;
+
+/**
+ * Manages bundle entities
+ *
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ */
+class BundleManager
+{
+ /**
+ * @var ObjectManager
+ */
+ private $entityManager;
+
+ /**
+ * @var Repo
+ */
+ private $repoApi;
+
+ /**
+ * @param ObjectManager $entityManager
+ * @param OwnerManager $ownerManager
+ * @param Repo $repoApi
+ */
+ public function __construct(ObjectManager $entityManager, OwnerManager $ownerManager, Repo $repoApi)
+ {
+ $this->entityManager = $entityManager;
+ $this->ownerManager = $ownerManager;
+ $this->repoApi = $repoApi;
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return null|Bundle
+ */
+ public function findBundleBy(array $data)
+ {
+ return $this->entityManager->getRepository('Knp\Bundle\KnpBundlesBundle\Entity\Bundle')->findOneBy($data);
+ }
+
+ /**
+ * @param Bundle $bundle
+ * @param Developer $developer
+ */
+ public function manageBundleRecommendation(Bundle $bundle, Developer $developer)
+ {
+ if ($developer->isUsingBundle($bundle)) {
+ $activity = $this->entityManager->getRepository('Knp\Bundle\KnpBundlesBundle\Entity\Activity')
+ ->findOneBy(array(
+ 'type' => Activity::ACTIVITY_TYPE_RECOMMEND,
+ 'bundle' => $bundle,
+ 'developer' => $developer
+ ))
+ ;
+
+ if ($activity) {
+ $this->entityManager->remove($activity);
+ }
+
+ $bundle->removeRecommender($developer);
+ } else {
+ $activity = new Activity();
+ $activity->setType(Activity::ACTIVITY_TYPE_RECOMMEND);
+ $activity->setBundle($bundle);
+ $activity->setDeveloper($developer);
+
+ $this->entityManager->persist($activity);
+
+ $bundle->addRecommender($developer);
+ }
+
+ $this->entityManager->persist($bundle);
+ $this->entityManager->flush();
+ }