├── .gitignore ├── Tests ├── bootstrap.php ├── autoload.php.dist ├── Entity │ ├── TermTest.php │ ├── OptionTest.php │ ├── PostMetaTest.php │ ├── TermRelationshipsTest.php │ ├── UserMetaTest.php │ ├── CommentMetaTest.php │ ├── TermTaxonomyTest.php │ ├── LinkTest.php │ ├── CommentTest.php │ ├── UserTest.php │ └── PostTest.php ├── Event │ ├── WordpressEventTest.php │ ├── Hook │ │ └── UserHookListenerTest.php │ └── Subscriber │ │ ├── WordpressResponseSubscriberTest.php │ │ └── I18n │ │ └── I18nSubscriberTest.php ├── Manager │ ├── OptionManagerTest.php │ ├── PostManagerTest.php │ └── PostMetaManagerTest.php ├── Security │ └── WordPressEntryPointTest.php ├── Twig │ └── Extension │ │ ├── OptionExtensionTest.php │ │ ├── PostMetaExtensionTest.php │ │ ├── ThemeExtensionTest.php │ │ └── PostExtensionTest.php ├── Controller │ └── WordpressControllerTest.php └── Wordpress │ └── WordpressTest.php ├── Resources └── config │ ├── routing.xml │ ├── doctrine-model │ ├── PostMeta.orm.xml │ ├── CommentMeta.orm.xml │ ├── UserMeta.orm.xml │ ├── TermRelationships.orm.xml │ ├── Option.orm.xml │ ├── TermTaxonomy.orm.xml │ ├── Term.orm.xml │ ├── User.orm.xml │ ├── Link.orm.xml │ ├── Comment.orm.xml │ └── Post.orm.xml │ ├── listener.xml │ ├── i18n.xml │ ├── doctrine │ ├── Option.orm.xml │ ├── Term.orm.xml │ ├── Link.orm.xml │ ├── User.orm.xml │ ├── UserMeta.orm.xml │ ├── PostMeta.orm.xml │ ├── CommentMeta.orm.xml │ ├── TermRelationships.orm.xml │ ├── Comment.orm.xml │ ├── Post.orm.xml │ └── TermTaxonomy.orm.xml │ ├── services.xml │ ├── hooks.xml │ ├── twig.xml │ └── manager.xml ├── Manager ├── LinkManager.php ├── TermManager.php ├── UserManager.php ├── CommentManager.php ├── UserMetaManager.php ├── CommentMetaManager.php ├── TermTaxonomyManager.php ├── TermRelationshipsManager.php ├── OptionManager.php ├── PostMetaManager.php ├── PostManager.php └── BaseManager.php ├── Model ├── WordpressContentInterface.php ├── WordpressEntityInterface.php ├── TermRelationships.php ├── PostMeta.php ├── UserMeta.php ├── Option.php ├── CommentMeta.php ├── Term.php └── TermTaxonomy.php ├── Entity ├── Link.php ├── Post.php ├── Term.php ├── User.php ├── Option.php ├── Comment.php ├── PostMeta.php ├── UserMeta.php ├── CommentMeta.php ├── TermTaxonomy.php └── TermRelationships.php ├── Wordpress ├── WordpressResponse.php └── Wordpress.php ├── Repository ├── LinkRepository.php ├── TermRepository.php ├── UserRepository.php ├── CommentRepository.php ├── OptionRepository.php ├── UserMetaRepository.php ├── CommentMetaRepository.php ├── TermTaxonomyRepository.php ├── TermRelationshipsRepository.php ├── PostMetaRepository.php └── PostRepository.php ├── phpunit.xml.dist ├── composer.json ├── Controller └── WordpressController.php ├── .travis.yml ├── EkinoWordpressBundle.php ├── Event ├── WordpressEvent.php ├── Subscriber │ ├── WordpressResponseSubscriber.php │ ├── I18n │ │ └── I18nSubscriber.php │ └── LoadMetadataSubscriber.php └── Hook │ └── UserHookListener.php ├── Twig └── Extension │ ├── OptionExtension.php │ ├── PostMetaExtension.php │ ├── TermTaxonomyExtension.php │ ├── CommentExtension.php │ ├── ThemeExtension.php │ └── PostExtension.php ├── Subscriber └── TablePrefixSubscriber.php ├── Security └── WordpressEntryPoint.php ├── Listener └── WordpressRequestListener.php └── DependencyInjection └── Compiler └── RegisterMappingsPass.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | -------------------------------------------------------------------------------- /Tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | EkinoWordpressBundle:Wordpress:catchAll 8 | .* 9 | 10 | 11 | -------------------------------------------------------------------------------- /Manager/LinkManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class LinkManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Manager/TermManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class TermManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Manager/UserManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class UserManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Model/WordpressContentInterface.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class CommentManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Manager/UserMetaManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class UserMetaManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Manager/CommentMetaManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class CommentMetaManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Entity/Link.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Link extends LinkModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/Post.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Post extends PostModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/Term.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Term extends TermModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/User.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class User extends UserModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Manager/TermTaxonomyManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class TermTaxonomyManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Wordpress/WordpressResponse.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class WordpressResponse extends Response 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Model/WordpressEntityInterface.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | interface WordpressEntityInterface 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /Entity/Option.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Option extends OptionModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/Comment.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class Comment extends CommentModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Manager/TermRelationshipsManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class TermRelationshipsManager extends BaseManager 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Entity/PostMeta.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class PostMeta extends PostMetaModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/UserMeta.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class UserMeta extends UserMetaModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/CommentMeta.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class CommentMeta extends CommentMetaModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/LinkRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class LinkRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/TermRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/UserRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class UserRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Entity/TermTaxonomy.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermTaxonomy extends TermTaxonomyModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/CommentRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class CommentRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/OptionRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class OptionRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/UserMetaRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class UserMetaRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/CommentMetaRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class CommentMetaRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/TermTaxonomyRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermTaxonomyRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Repository/TermRelationshipsRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermRelationshipsRepository extends EntityRepository 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/PostMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Entity/TermRelationships.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermRelationships extends TermRelationshipsModel 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/CommentMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/UserMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/TermRelationships.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Resources/config/listener.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/autoload.php.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Ekino\WordpressBundle\Event\Subscriber\I18n\I18nSubscriber 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | %kernel.default_locale% 17 | %ekino.wordpress.i18n_cookie_name% 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./Tests 17 | 18 | 19 | 20 | 21 | 22 | ./ 23 | 24 | vendor 25 | Tests 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/Option.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/TermTaxonomy.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Resources/config/doctrine/Option.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/Term.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Tests/Entity/TermTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class TermTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * Test entity getters & setters. 26 | */ 27 | public function testGettersSetters() 28 | { 29 | $entity = new Term(); 30 | 31 | $entity->setGroup(3); 32 | $entity->setName('term name'); 33 | $entity->setSlug('term-slug'); 34 | 35 | $this->assertEquals(3, $entity->getGroup()); 36 | $this->assertEquals('term name', $entity->getName()); 37 | $this->assertEquals('term-slug', $entity->getSlug()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ekino/wordpress-bundle", 3 | "type": "symfony-bundle", 4 | "description": "A Symfony bundle to link Symfony with Wordpress", 5 | "keywords": ["ekino", "bundle", "symfony", "wordpress"], 6 | "homepage": "http://github.com/ekino/EkinoWordpressBundle", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Vincent Composieux", 11 | "email": "composieux@ekino.com" 12 | } 13 | ], 14 | "require": { 15 | "php": "^5.4|^7.0", 16 | "symfony/framework-bundle": "^2.6|^3.0|^4.0", 17 | "symfony/security-bundle": "^2.6|^3.0|^4.0", 18 | "symfony/monolog-bundle": "^2.2|^3.0|^4.0", 19 | "doctrine/doctrine-bundle": "^1.0", 20 | "doctrine/orm": "^2.2", 21 | "hautelook/phpass": "0.3" 22 | }, 23 | "suggest": { 24 | "twig/twig": "" 25 | }, 26 | "autoload": { 27 | "psr-4": { "Ekino\\WordpressBundle\\": "" } 28 | }, 29 | "extra": { 30 | "branch-alias": { 31 | "dev-master": "1.0.x-dev" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/Entity/OptionTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class OptionTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * Test entity getters & setters. 26 | */ 27 | public function testGettersSetters() 28 | { 29 | $entity = new Option(); 30 | 31 | $entity->setAutoload('autoloaded'); 32 | $entity->setName('option name'); 33 | $entity->setValue('option value'); 34 | 35 | $this->assertEquals('autoloaded', $entity->getAutoload()); 36 | $this->assertEquals('option name', $entity->getName()); 37 | $this->assertEquals('option value', $entity->getValue()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Repository/PostMetaRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class PostMetaRepository extends EntityRepository 23 | { 24 | /** 25 | * @param int $postId 26 | * @param string $metaName 27 | * 28 | * @return \Doctrine\ORM\Query 29 | */ 30 | public function getPostMetaQuery($postId, $metaName) 31 | { 32 | return $this->createQueryBuilder('m') 33 | ->innerJoin('m.post', 'p') 34 | ->where('m.key = :metaName') 35 | ->andWhere('p.id = :postId') 36 | ->setParameter('postId', $postId) 37 | ->setParameter('metaName', $metaName) 38 | ->getQuery(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Controller/WordpressController.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class WordpressController extends Controller 23 | { 24 | /** 25 | * Wordpress catch-all route action. 26 | * 27 | * @return \Ekino\WordpressBundle\Wordpress\WordpressResponse 28 | */ 29 | public function catchAllAction() 30 | { 31 | return $this->getWordpress()->initialize()->getResponse(); 32 | } 33 | 34 | /** 35 | * Returns Wordpress service. 36 | * 37 | * @return \Ekino\WordpressBundle\Wordpress\Wordpress 38 | */ 39 | protected function getWordpress() 40 | { 41 | return $this->get('ekino.wordpress.wordpress'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Resources/config/doctrine/Term.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Resources/config/doctrine/Link.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Resources/config/doctrine/User.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.5 5 | - 5.6 6 | - 7.0 7 | - 7.1 8 | - hhvm 9 | 10 | cache: 11 | directories: 12 | - $HOME/.composer/cache/files 13 | 14 | matrix: 15 | fast_finish: true 16 | include: 17 | - php: 5.6 18 | env: SYMFONY_VERSION=2.7.* 19 | - php: 5.6 20 | env: SYMFONY_VERSION=2.8.* 21 | - php: 5.6 22 | env: SYMFONY_VERSION=3.0.* 23 | - php: 5.6 24 | env: SYMFONY_VERSION=3.1.*@dev 25 | - php: 5.6 26 | env: SYMFONY_VERSION=3.2.*@dev 27 | allow_failures: 28 | - php: hhvm 29 | 30 | before_install: 31 | - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then echo "memory_limit=3072M" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi; 32 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; else composer require "symfony/symfony:dev-master"; fi; 33 | - if [ "$SYMFONY_VERSION" = "3.1.*@dev" ] || [ "$SYMFONY_VERSION" = "3.2.*@dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi; 34 | 35 | install: 36 | - composer update --dev --prefer-source 37 | 38 | script: phpunit 39 | 40 | notifications: 41 | email: 42 | - composieux@ekino.com 43 | -------------------------------------------------------------------------------- /Resources/config/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | %ekino.wordpress.install_directory% 13 | %ekino.wordpress.globals% 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | %ekino.wordpress.login_url% 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests/Entity/PostMetaTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class PostMetaTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * Test entity getters & setters. 27 | */ 28 | public function testGettersSetters() 29 | { 30 | $entity = new PostMeta(); 31 | 32 | $post = new Post(); 33 | $post->setTitle('post title'); 34 | $entity->setPost($post); 35 | 36 | $entity->setKey('fake key'); 37 | $entity->setValue('fake value'); 38 | 39 | $this->assertEquals('post title', $entity->getPost()->getTitle()); 40 | $this->assertEquals('fake key', $entity->getKey()); 41 | $this->assertEquals('fake value', $entity->getValue()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/Entity/TermRelationshipsTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class TermRelationshipsTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * Test entity getters & setters. 27 | */ 28 | public function testGettersSetters() 29 | { 30 | $entity = new TermRelationships(); 31 | 32 | $taxonomy = new TermTaxonomy(); 33 | $taxonomy->setDescription('taxonomy description'); 34 | $entity->setTaxonomy($taxonomy); 35 | 36 | $entity->setTermOrder(4); 37 | 38 | $this->assertEquals('taxonomy description', $entity->getTaxonomy()->getDescription()); 39 | $this->assertEquals(4, $entity->getTermOrder()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Tests/Entity/UserMetaTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class UserMetaTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * Test entity getters & setters. 27 | */ 28 | public function testGettersSetters() 29 | { 30 | $entity = new UserMeta(); 31 | 32 | $user = new User(); 33 | $user->setDisplayName('display name'); 34 | $entity->setUser($user); 35 | 36 | $entity->setKey('fake key'); 37 | $entity->setValue('fake value'); 38 | 39 | $this->assertEquals('display name', $entity->getUser()->getDisplayName()); 40 | $this->assertEquals('fake key', $entity->getKey()); 41 | $this->assertEquals('fake value', $entity->getValue()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Manager/OptionManager.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class OptionManager extends BaseManager 21 | { 22 | /** 23 | * @param string $optionName 24 | * 25 | * @return mixed 26 | */ 27 | public function findOneByOptionName($optionName) 28 | { 29 | return $this->findOneBy(['name' => $optionName]); 30 | } 31 | 32 | /** 33 | * @param string $sidebarName 34 | * 35 | * @return bool 36 | */ 37 | public function isActiveSidebar($sidebarName) 38 | { 39 | if (!$sidebarOption = $this->findOneByOptionName('sidebars_widgets')) { 40 | return false; 41 | } 42 | 43 | if (false === ($sidebarOption = unserialize($sidebarOption->getValue()))) { 44 | return false; 45 | } 46 | 47 | return isset($sidebarOption[$sidebarName]); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/Entity/CommentMetaTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class CommentMetaTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * Test entity getters & setters. 27 | */ 28 | public function testGettersSetters() 29 | { 30 | $entity = new CommentMeta(); 31 | 32 | $comment = new Comment(); 33 | $comment->setContent('comment message'); 34 | $entity->setComment($comment); 35 | 36 | $entity->setKey('fake key'); 37 | $entity->setValue('fake value'); 38 | 39 | $this->assertEquals('comment message', $entity->getComment()->getContent()); 40 | $this->assertEquals('fake key', $entity->getKey()); 41 | $this->assertEquals('fake value', $entity->getValue()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Resources/config/doctrine/UserMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Resources/config/doctrine/PostMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Resources/config/doctrine/CommentMeta.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Resources/config/doctrine/TermRelationships.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /EkinoWordpressBundle.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class EkinoWordpressBundle extends Bundle 25 | { 26 | /** 27 | * @param ContainerBuilder $container 28 | */ 29 | public function build(ContainerBuilder $container) 30 | { 31 | parent::build($container); 32 | 33 | $this->addRegisterMappingPass($container); 34 | } 35 | 36 | /** 37 | * @param ContainerBuilder $containerBuilder 38 | */ 39 | public function addRegisterMappingPass(ContainerBuilder $containerBuilder) 40 | { 41 | $mappings = [ 42 | realpath(__DIR__.'/Resources/config/doctrine-model') => 'Ekino\WordpressBundle\Model', 43 | ]; 44 | 45 | $containerBuilder->addCompilerPass(RegisterMappingsPass::createOrmMappingDriver($mappings)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Resources/config/doctrine/Comment.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Manager/PostMetaManager.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class PostMetaManager extends BaseManager 25 | { 26 | /** 27 | * @var PostMetaRepository 28 | */ 29 | protected $repository; 30 | 31 | /** 32 | * @param int $postId A post identifier 33 | * @param string $metaName A meta name 34 | * @param bool $fetchOneResult Use fetchOneOrNullResult() method instead of getResult()? 35 | * 36 | * @return array|\Ekino\WordpressBundle\Entity\PostMeta 37 | */ 38 | public function getPostMeta($postId, $metaName, $fetchOneResult = false) 39 | { 40 | $query = $this->repository->getPostMetaQuery($postId, $metaName); 41 | 42 | return $fetchOneResult ? $query->getOneOrNullResult() : $query->getResult(); 43 | } 44 | 45 | /** 46 | * @param Post $post 47 | * 48 | * @return PostMeta|null 49 | */ 50 | public function getThumbnailPostId(Post $post) 51 | { 52 | return $this->getPostMeta($post->getId(), '_thumbnail_id', true); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Tests/Entity/TermTaxonomyTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class TermTaxonomyTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * Test entity getters & setters. 27 | */ 28 | public function testGettersSetters() 29 | { 30 | $entity = new TermTaxonomy(); 31 | 32 | $entity->setCount(5); 33 | $entity->setDescription('term description'); 34 | 35 | $parent = new TermTaxonomy(); 36 | $parent->setDescription('parent term description'); 37 | $entity->setParent($parent); 38 | 39 | $entity->setTaxonomy('term taxonomy'); 40 | 41 | $term = new Term(); 42 | $term->setName('term name'); 43 | $entity->setTerm($term); 44 | 45 | $this->assertEquals(5, $entity->getCount()); 46 | $this->assertEquals('term description', $entity->getDescription()); 47 | $this->assertEquals('parent term description', $entity->getParent()->getDescription()); 48 | $this->assertEquals('term taxonomy', $entity->getTaxonomy()); 49 | $this->assertEquals('term name', $entity->getTerm()->getName()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Resources/config/doctrine/Post.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Resources/config/doctrine/TermTaxonomy.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Tests/Event/WordpressEventTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class WordpressEventTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * Tests WordpressEvent constructor parameters. 26 | * 27 | * Should return correct parameters 28 | */ 29 | public function testConstructorParameters() 30 | { 31 | $event = new WordpressEvent(['my-key' => 'my-value']); 32 | 33 | $this->assertTrue($event->hasParameter('my-key'), 'Should return true because my-key value exists'); 34 | $this->assertFalse($event->hasParameter(1), 'Should return false because only my-key value was added'); 35 | $this->assertEquals('my-value', $event->getParameter('my-key')); 36 | } 37 | 38 | /** 39 | * Tests WordpressEvent addParameter() method. 40 | * 41 | * Should return correct parameters 42 | */ 43 | public function testAddParameter() 44 | { 45 | $event = new WordpressEvent(); 46 | $event->addParameter('my-other-value'); 47 | 48 | $this->assertTrue($event->hasParameter(0), 'Should return true because one parameter was added'); 49 | $this->assertFalse($event->hasParameter(1), 'Should return false because only one parameter was added'); 50 | $this->assertEquals('my-other-value', $event->getParameter(0)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Repository/PostRepository.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class PostRepository extends EntityRepository 23 | { 24 | /** 25 | * @param \DateTime|null $date 26 | * 27 | * @return array 28 | * 29 | * @author Elvis Morales & Leroy Ley 30 | */ 31 | public function findByDate(\DateTime $date = null) 32 | { 33 | $qb = $this->createQueryBuilder('p') 34 | ->where('p.date LIKE :date') 35 | ->addOrderBy('p.date', 'DESC') 36 | ->addOrderBy('p.id', 'DESC') 37 | ->setParameter('date', $date->format('Y-m-d').'%'); 38 | 39 | return $qb->getQuery()->getResult(); 40 | } 41 | 42 | /** 43 | * @param string $category 44 | * 45 | * @return array 46 | * 47 | * @author Guillaume Leclercq 48 | */ 49 | public function findByCategory($category) 50 | { 51 | return $this->createQueryBuilder('p') 52 | ->leftJoin('Ekino\WordpressBundle\Entity\TermRelationships', 'tr', 'WITH', 'p.id = tr.post') 53 | ->leftJoin('Ekino\WordpressBundle\Entity\Term', 't', 'WITH', 't.id = tr.taxonomy') 54 | ->where('t.name = :category') 55 | ->setParameter('category', $category) 56 | ->getQuery()->getResult(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Resources/config/hooks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Ekino\WordpressBundle\Event\Subscriber\WordpressResponseSubscriber 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | %ekino.wordpress.firewall_name% 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | %ekino.wordpress.repositories% 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Event/WordpressEvent.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class WordpressEvent extends Event 23 | { 24 | /** 25 | * @var array 26 | */ 27 | protected $parameters; 28 | 29 | /** 30 | * Constructor. 31 | * 32 | * @param array $parameters 33 | */ 34 | public function __construct(array $parameters = []) 35 | { 36 | $this->parameters = $parameters; 37 | } 38 | 39 | /** 40 | * Returns if parameter gor given index position exists. 41 | * 42 | * @param mixed $index 43 | * 44 | * @return bool 45 | */ 46 | public function hasParameter($index) 47 | { 48 | return isset($this->parameters[$index]); 49 | } 50 | 51 | /** 52 | * Returns a parameter of given index position. 53 | * 54 | * @param mixed $index 55 | * 56 | * @throws \InvalidArgumentException 57 | * 58 | * @return mixed 59 | */ 60 | public function getParameter($index) 61 | { 62 | if (!$this->hasParameter($index)) { 63 | throw new \InvalidArgumentException(sprintf('Cannot retrieve parameter "%s"', $index)); 64 | } 65 | 66 | return $this->parameters[$index]; 67 | } 68 | 69 | /** 70 | * Adds a parameter. 71 | * 72 | * @param mixed $value 73 | * 74 | * @return $this 75 | */ 76 | public function addParameter($value) 77 | { 78 | $this->parameters[] = $value; 79 | 80 | return $this; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Twig/Extension/OptionExtension.php: -------------------------------------------------------------------------------- 1 | optionManager = $optionManager; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function getFunctions() 47 | { 48 | return [ 49 | new \Twig_SimpleFunction('wp_get_option', [$this, 'getOption']), 50 | new \Twig_SimpleFunction('wp_is_active_sidebar', [$this, 'isActiveSidebar']), 51 | ]; 52 | } 53 | 54 | /** 55 | * @param string $optionName 56 | * @param mixed $defaultValue 57 | * 58 | * @return mixed 59 | */ 60 | public function getOption($optionName, $defaultValue = null) 61 | { 62 | $option = $this->optionManager->findOneByOptionName($optionName); 63 | 64 | return $option ?: $defaultValue; 65 | } 66 | 67 | /** 68 | * @param string $sidebarName 69 | * 70 | * @return bool 71 | */ 72 | public function isActiveSidebar($sidebarName) 73 | { 74 | return $this->optionManager->isActiveSidebar($sidebarName); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Tests/Manager/OptionManagerTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class OptionManagerTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * @var EntityManager 26 | */ 27 | protected $entityManager; 28 | 29 | /** 30 | * @var OptionRepository 31 | */ 32 | protected $repository; 33 | 34 | /** 35 | * @var OptionManager 36 | */ 37 | protected $manager; 38 | 39 | /** 40 | * Sets up a OptionManager instance. 41 | */ 42 | protected function setUp() 43 | { 44 | $this->entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock(); 45 | $this->repository = $this->getMockBuilder('Ekino\WordpressBundle\Repository\OptionRepository')->disableOriginalConstructor()->getMock(); 46 | $this->entityManager->expects($this->any()) 47 | ->method('getRepository') 48 | ->will($this->returnValue($this->repository)); 49 | 50 | $this->manager = new OptionManager($this->entityManager, 'Ekino\WordpressBundle\Entity\Option'); 51 | } 52 | 53 | /** 54 | * Test that the repository is called with the correct argument. 55 | */ 56 | public function testFindOneByName() 57 | { 58 | $this->repository->expects($this->once()) 59 | ->method('findOneBy') 60 | ->with($this->equalTo(['name' => 'test'])); 61 | 62 | $this->manager->findOneByOptionName('test'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Event/Subscriber/WordpressResponseSubscriber.php: -------------------------------------------------------------------------------- 1 | wordpress = $wordpress; 38 | } 39 | 40 | /** 41 | * @param FilterResponseEvent $event 42 | */ 43 | public function onKernelResponse(FilterResponseEvent $event) 44 | { 45 | $response = $event->getResponse(); 46 | 47 | if (!$response instanceof WordpressResponse || $event->getRequestType() != HttpKernelInterface::MASTER_REQUEST) { 48 | return; 49 | } 50 | 51 | if (!$wp_query = $this->wordpress->getWpQuery()) { 52 | return; 53 | } 54 | 55 | if ($wp_query->is_404()) { 56 | $response->setStatusCode(404); 57 | } 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public static function getSubscribedEvents() 64 | { 65 | return [ 66 | KernelEvents::RESPONSE => ['onKernelResponse'], 67 | ]; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Model/TermRelationships.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class TermRelationships implements WordpressEntityInterface 21 | { 22 | /** 23 | * @var TermTaxonomy 24 | */ 25 | protected $taxonomy; 26 | 27 | /** 28 | * @var int 29 | */ 30 | protected $termOrder; 31 | 32 | /** 33 | * @var Post 34 | */ 35 | protected $post; 36 | 37 | /** 38 | * @param Post $post 39 | * 40 | * @return TermRelationships 41 | */ 42 | public function setPost(Post $post) 43 | { 44 | $this->post = $post; 45 | 46 | return $this; 47 | } 48 | 49 | /** 50 | * @return Post 51 | */ 52 | public function getPost() 53 | { 54 | return $this->post; 55 | } 56 | 57 | /** 58 | * @param int $termOrder 59 | * 60 | * @return TermRelationships 61 | */ 62 | public function setTermOrder($termOrder) 63 | { 64 | $this->termOrder = $termOrder; 65 | 66 | return $this; 67 | } 68 | 69 | /** 70 | * @return int 71 | */ 72 | public function getTermOrder() 73 | { 74 | return $this->termOrder; 75 | } 76 | 77 | /** 78 | * @param TermTaxonomy $taxonomy 79 | * 80 | * @return TermRelationships 81 | */ 82 | public function setTaxonomy(TermTaxonomy $taxonomy) 83 | { 84 | $this->taxonomy = $taxonomy; 85 | 86 | return $this; 87 | } 88 | 89 | /** 90 | * @return TermTaxonomy 91 | */ 92 | public function getTaxonomy() 93 | { 94 | return $this->taxonomy; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Tests/Security/WordPressEntryPointTest.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class WordPressEntryPointTest extends \PHPUnit_Framework_TestCase 26 | { 27 | public function testEntryPoint() 28 | { 29 | $entryPoint = new WordpressEntryPoint(); 30 | 31 | $request = Request::create('/private'); 32 | 33 | $response = $entryPoint->start($request, new AuthenticationException()); 34 | 35 | $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); 36 | $this->assertEquals(302, $response->getStatusCode()); 37 | $this->assertEquals('/wp-login.php?redirect_to=http%3A%2F%2Flocalhost%2Fprivate&reauth=0', $response->getTargetUrl()); 38 | } 39 | 40 | public function testAccessDeniedHandler() 41 | { 42 | $entryPoint = new WordpressEntryPoint('/wordpress/wp-login.php'); 43 | 44 | $request = Request::create('/denied'); 45 | 46 | $response = $entryPoint->handle($request, new AccessDeniedException()); 47 | 48 | $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); 49 | $this->assertEquals(302, $response->getStatusCode()); 50 | $this->assertEquals('/wordpress/wp-login.php?redirect_to=http%3A%2F%2Flocalhost%2Fdenied&reauth=0', $response->getTargetUrl()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Event/Subscriber/I18n/I18nSubscriber.php: -------------------------------------------------------------------------------- 1 | defaultLocale = $defaultLocale; 43 | $this->wordpressI18nCookieName = $wordpressI18nCookieName; 44 | } 45 | 46 | /** 47 | * @param GetResponseEvent $event 48 | */ 49 | public function onKernelRequest(GetResponseEvent $event) 50 | { 51 | $request = $event->getRequest(); 52 | $session = $request->getSession(); 53 | $locale = $request->cookies->get($this->wordpressI18nCookieName, $session->get('_locale', $this->defaultLocale)); 54 | 55 | $session->set('_locale', $locale); 56 | $request->setLocale($locale); 57 | } 58 | 59 | /** 60 | * @return array 61 | */ 62 | public static function getSubscribedEvents() 63 | { 64 | return [ 65 | // must be registered before the default Locale listener 66 | KernelEvents::REQUEST => [['onKernelRequest', 17]], 67 | ]; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Tests/Entity/LinkTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class LinkTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * Test entity getters & setters. 26 | */ 27 | public function testGettersSetters() 28 | { 29 | $entity = new Link(); 30 | 31 | $entity->setDescription('link description'); 32 | $entity->setImage('link image'); 33 | $entity->setName('link name'); 34 | $entity->setNotes('link notes'); 35 | $entity->setOwner('link owner'); 36 | $entity->setRating('link rating'); 37 | $entity->setRel('link rel'); 38 | $entity->setRss('link rss'); 39 | $entity->setTarget('link target'); 40 | 41 | $date = new \DateTime(); 42 | $entity->setUpdated($date); 43 | 44 | $entity->setUrl('link url'); 45 | $entity->setVisible('link visible'); 46 | 47 | $this->assertEquals('link description', $entity->getDescription()); 48 | $this->assertEquals('link image', $entity->getImage()); 49 | $this->assertEquals('link name', $entity->getName()); 50 | $this->assertEquals('link notes', $entity->getNotes()); 51 | $this->assertEquals('link owner', $entity->getOwner()); 52 | $this->assertEquals('link rating', $entity->getRating()); 53 | $this->assertEquals('link rel', $entity->getRel()); 54 | $this->assertEquals('link rss', $entity->getRss()); 55 | $this->assertEquals('link target', $entity->getTarget()); 56 | $this->assertEquals($date, $entity->getUpdated()); 57 | $this->assertEquals('link url', $entity->getUrl()); 58 | $this->assertEquals('link visible', $entity->getVisible()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Twig/Extension/PostMetaExtension.php: -------------------------------------------------------------------------------- 1 | postMetaManager = $postMetaManager; 33 | } 34 | 35 | /** 36 | * Returns the name of the extension. 37 | * 38 | * @return string The extension name 39 | */ 40 | public function getName() 41 | { 42 | return 'ekino_wordpress_post_meta'; 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function getFunctions() 49 | { 50 | return [ 51 | new \Twig_SimpleFunction('wp_get_post_meta', [$this, 'getPostMeta']), 52 | new \Twig_SimpleFunction('wp_get_image_url_from_id', [$this, 'getImageUrlFromId']), 53 | ]; 54 | } 55 | 56 | /** 57 | * @param int $postId A post identifier 58 | * @param string $metaName A meta name 59 | * @param bool $fetchOneResult Use fetchOneOrNullResult() method instead of getResult()? 60 | * 61 | * @return array|\Ekino\WordpressBundle\Entity\PostMeta 62 | */ 63 | public function getPostMeta($postId, $metaName, $fetchOneResult = false) 64 | { 65 | return $this->postMetaManager->getPostMeta($postId, $metaName, $fetchOneResult); 66 | } 67 | 68 | /** 69 | * @param int $imgId An image identifier 70 | */ 71 | public function getImageUrlFromId($imgId) 72 | { 73 | return \wp_get_attachment_url($imgId); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Model/PostMeta.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class PostMeta implements WordpressEntityInterface 21 | { 22 | /** 23 | * @var int 24 | */ 25 | protected $id; 26 | 27 | /** 28 | * @var Post 29 | */ 30 | protected $post; 31 | 32 | /** 33 | * @var string 34 | */ 35 | protected $key; 36 | 37 | /** 38 | * @var string 39 | */ 40 | protected $value; 41 | 42 | /** 43 | * @return int 44 | */ 45 | public function getId() 46 | { 47 | return $this->id; 48 | } 49 | 50 | /** 51 | * @param string $key 52 | * 53 | * @return PostMeta 54 | */ 55 | public function setKey($key) 56 | { 57 | $this->key = $key; 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getKey() 66 | { 67 | return $this->key; 68 | } 69 | 70 | /** 71 | * @param Post $post 72 | * 73 | * @return PostMeta 74 | */ 75 | public function setPost(Post $post) 76 | { 77 | $this->post = $post; 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return Post 84 | */ 85 | public function getPost() 86 | { 87 | return $this->post; 88 | } 89 | 90 | /** 91 | * @param string $value 92 | * 93 | * @return PostMeta 94 | */ 95 | public function setValue($value) 96 | { 97 | $this->value = $value; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getValue() 106 | { 107 | return $this->value; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Model/UserMeta.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class UserMeta implements WordpressEntityInterface 21 | { 22 | /** 23 | * @var int 24 | */ 25 | protected $id; 26 | 27 | /** 28 | * @var User 29 | */ 30 | protected $user; 31 | 32 | /** 33 | * @var string 34 | */ 35 | protected $key; 36 | 37 | /** 38 | * @var string 39 | */ 40 | protected $value; 41 | 42 | /** 43 | * @return int 44 | */ 45 | public function getId() 46 | { 47 | return $this->id; 48 | } 49 | 50 | /** 51 | * @param string $key 52 | * 53 | * @return UserMeta 54 | */ 55 | public function setKey($key) 56 | { 57 | $this->key = $key; 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getKey() 66 | { 67 | return $this->key; 68 | } 69 | 70 | /** 71 | * @param User $user 72 | * 73 | * @return UserMeta 74 | */ 75 | public function setUser(User $user) 76 | { 77 | $this->user = $user; 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return User 84 | */ 85 | public function getUser() 86 | { 87 | return $this->user; 88 | } 89 | 90 | /** 91 | * @param string $value 92 | * 93 | * @return UserMeta 94 | */ 95 | public function setValue($value) 96 | { 97 | $this->value = $value; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getValue() 106 | { 107 | return $this->value; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Tests/Manager/PostManagerTest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class PostManagerTest extends \PHPUnit_Framework_TestCase 25 | { 26 | /** 27 | * @var EntityManager 28 | */ 29 | protected $entityManager; 30 | 31 | /** 32 | * @var PostRepository 33 | */ 34 | protected $repository; 35 | 36 | /** 37 | * @var PostManager 38 | */ 39 | protected $manager; 40 | 41 | /** 42 | * @var PostMetaManager 43 | */ 44 | protected $postMetaManager; 45 | 46 | /** 47 | * Sets up a PostManager instance 48 | */ 49 | protected function setUp() 50 | { 51 | $this->entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock(); 52 | $this->repository = $this->getMockBuilder('Ekino\WordpressBundle\Repository\PostRepository')->disableOriginalConstructor()->getMock(); 53 | $this->entityManager->expects($this->any()) 54 | ->method('getRepository') 55 | ->will($this->returnValue($this->repository)); 56 | 57 | $this->postMetaManager = new PostMetaManager($this->entityManager, 'Ekino\WordpressBundle\Entity\PostMeta'); 58 | $this->manager = new PostManager($this->entityManager, 'Ekino\WordpressBundle\Entity\Post', $this->postMetaManager); 59 | } 60 | 61 | public function testFindByCategory() 62 | { 63 | $this->repository->expects($this->once()) 64 | ->method('findByCategory') 65 | ->will($this->returnValue('test')); 66 | 67 | $this->manager->findByCategory('test'); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Model/Option.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class Option implements WordpressEntityInterface 21 | { 22 | /** 23 | * @var int 24 | */ 25 | protected $id; 26 | 27 | /** 28 | * @var string 29 | */ 30 | protected $name; 31 | 32 | /** 33 | * @var string 34 | */ 35 | protected $value; 36 | 37 | /** 38 | * @var string 39 | */ 40 | protected $autoload; 41 | 42 | /** 43 | * @return int 44 | */ 45 | public function getId() 46 | { 47 | return $this->id; 48 | } 49 | 50 | /** 51 | * @param string $autoload 52 | * 53 | * @return Option 54 | */ 55 | public function setAutoload($autoload) 56 | { 57 | $this->autoload = $autoload; 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getAutoload() 66 | { 67 | return $this->autoload; 68 | } 69 | 70 | /** 71 | * @param string $name 72 | * 73 | * @return Option 74 | */ 75 | public function setName($name) 76 | { 77 | $this->name = $name; 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | public function getName() 86 | { 87 | return $this->name; 88 | } 89 | 90 | /** 91 | * @param string $value 92 | * 93 | * @return Option 94 | */ 95 | public function setValue($value) 96 | { 97 | $this->value = $value; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getValue() 106 | { 107 | return $this->value; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Model/CommentMeta.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class CommentMeta implements WordpressEntityInterface 21 | { 22 | /** 23 | * @var int 24 | */ 25 | protected $id; 26 | 27 | /** 28 | * @var Comment 29 | */ 30 | protected $comment; 31 | 32 | /** 33 | * @var string 34 | */ 35 | protected $key; 36 | 37 | /** 38 | * @var string 39 | */ 40 | protected $value; 41 | 42 | /** 43 | * @return int 44 | */ 45 | public function getId() 46 | { 47 | return $this->id; 48 | } 49 | 50 | /** 51 | * @param Comment $comment 52 | * 53 | * @return CommentMeta 54 | */ 55 | public function setComment(Comment $comment) 56 | { 57 | $this->comment = $comment; 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return Comment 64 | */ 65 | public function getComment() 66 | { 67 | return $this->comment; 68 | } 69 | 70 | /** 71 | * @param string $key 72 | * 73 | * @return CommentMeta 74 | */ 75 | public function setKey($key) 76 | { 77 | $this->key = $key; 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | public function getKey() 86 | { 87 | return $this->key; 88 | } 89 | 90 | /** 91 | * @param string $value 92 | * 93 | * @return CommentMeta 94 | */ 95 | public function setValue($value) 96 | { 97 | $this->value = $value; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getValue() 106 | { 107 | return $this->value; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Twig/Extension/TermTaxonomyExtension.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class TermTaxonomyExtension extends \Twig_Extension 24 | { 25 | /** 26 | * @var OptionManager 27 | */ 28 | protected $optionManager; 29 | 30 | /** 31 | * @param OptionManager $optionManager 32 | */ 33 | public function __construct(OptionManager $optionManager) 34 | { 35 | $this->optionManager = $optionManager; 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function getFunctions() 42 | { 43 | return [ 44 | new \Twig_SimpleFunction('wp_get_term_link', [$this, 'getTermLink']), 45 | ]; 46 | } 47 | 48 | /** 49 | * @param TermTaxonomy $termTaxonomy A term taxonomy instance 50 | * @param string $type The link type. Can be "category" or "tag" 51 | * 52 | * @return string 53 | */ 54 | public function getTermLink(TermTaxonomy $termTaxonomy, $type = 'category') 55 | { 56 | $prefix = ($prefix = $this->optionManager->findOneByOptionName($type.'_base')) ? $prefix->getValue() : null; 57 | $output = [$termTaxonomy->getTerm()->getSlug()]; 58 | 59 | while ($parent = $termTaxonomy->getParent()) { 60 | $output[] = $parent->getTerm()->getSlug(); 61 | $termTaxonomy = $parent; 62 | } 63 | 64 | return ($prefix ? $prefix : '').'/'.implode('/', array_reverse($output)).(count($output) ? '/' : ''); 65 | } 66 | 67 | /** 68 | * Returns the name of the extension. 69 | * 70 | * @return string The extension name 71 | */ 72 | public function getName() 73 | { 74 | return 'ekino_wordpress_term_taxonomy'; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/User.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Twig/Extension/CommentExtension.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class CommentExtension extends \Twig_Extension 24 | { 25 | /** 26 | * @var CommentManager 27 | */ 28 | protected $commentManager; 29 | 30 | /** 31 | * @param CommentManager $commentManager 32 | */ 33 | public function __construct(CommentManager $commentManager) 34 | { 35 | $this->commentManager = $commentManager; 36 | } 37 | 38 | /** 39 | * Returns the name of the extension. 40 | * 41 | * @return string The extension name 42 | */ 43 | public function getName() 44 | { 45 | return 'ekino_wordpress_comment'; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function getFunctions() 52 | { 53 | return [ 54 | new \Twig_SimpleFunction('wp_get_comment_author_link', [$this, 'getCommentAuthorLink'], ['is_safe' => ['html']]), 55 | ]; 56 | } 57 | 58 | /** 59 | * @param Comment $comment 60 | * 61 | * @return string 62 | */ 63 | public function getCommentAuthorLink(Comment $comment) 64 | { 65 | if (!$user = $comment->getUser()) { 66 | if ((!$authorUrl = $comment->getAuthorUrl()) || !preg_match('/^http(s)?:\/\/.+$/', $authorUrl)) { 67 | return $comment->getAuthor(); 68 | } 69 | 70 | return sprintf('%s', $authorUrl, $comment->getAuthor()); 71 | } 72 | 73 | if ((!$userUrl = $user->getUrl()) || !preg_match('/^http(s)?:\/\/.+$/', $userUrl)) { 74 | return $user->getDisplayName(); 75 | } 76 | 77 | return sprintf('%s', $userUrl, $user->getDisplayName()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Subscriber/TablePrefixSubscriber.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class TablePrefixSubscriber implements EventSubscriber 25 | { 26 | /** 27 | * Prefix value. 28 | * 29 | * @var string 30 | */ 31 | protected $prefix = ''; 32 | 33 | /** 34 | * Constructor. 35 | * 36 | * @param string $prefix 37 | */ 38 | public function __construct($prefix) 39 | { 40 | $this->prefix = $prefix; 41 | } 42 | 43 | /** 44 | * Returns subscribed events. 45 | * 46 | * @return array 47 | */ 48 | public function getSubscribedEvents() 49 | { 50 | return ['loadClassMetadata']; 51 | } 52 | 53 | /** 54 | * Loads class metadata and updates table prefix name. 55 | * 56 | * @param LoadClassMetadataEventArgs $args 57 | */ 58 | public function loadClassMetadata(LoadClassMetadataEventArgs $args) 59 | { 60 | $classMetadata = $args->getClassMetadata(); 61 | 62 | if ($classMetadata->isInheritanceTypeSingleTable() && !$classMetadata->isRootEntity()) { 63 | return; 64 | } 65 | 66 | if ($classMetadata->getReflectionClass() && $classMetadata->getReflectionClass()->implementsInterface('Ekino\\WordpressBundle\\Model\\WordpressEntityInterface')) { 67 | $classMetadata->setPrimaryTable(['name' => $this->prefix.$classMetadata->getTableName()]); 68 | 69 | foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { 70 | if ($mapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { 71 | $mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name']; 72 | $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix.$mappedTableName; 73 | } 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Twig/Extension/ThemeExtension.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class ThemeExtension extends \Twig_Extension 21 | { 22 | /** 23 | * Returns the name of the extension. 24 | * 25 | * @return string 26 | */ 27 | public function getName() 28 | { 29 | return 'ekino_wordpress_theme'; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function getFunctions() 36 | { 37 | return [ 38 | new \Twig_SimpleFunction('wp_get_header', [$this, 'getHeader'], ['is_safe' => ['html']]), 39 | new \Twig_SimpleFunction('wp_get_sidebar', [$this, 'getSidebar'], ['is_safe' => ['html']]), 40 | new \Twig_SimpleFunction('wp_get_footer', [$this, 'getFooter'], ['is_safe' => ['html']]), 41 | new \Twig_SimpleFunction('wp_get_template_part', [$this, 'getTemplatePart'], ['is_safe' => ['html']]), 42 | ]; 43 | } 44 | 45 | /** 46 | * Displays Wordpress theme header (and administration menu bar if available). 47 | * 48 | * @param string|null $name 49 | */ 50 | public function getHeader($name = null) 51 | { 52 | \get_header($name); 53 | 54 | \_wp_admin_bar_init(); 55 | \wp_admin_bar_render(); 56 | } 57 | 58 | /** 59 | * Displays Wordpress theme sidebar. 60 | * 61 | * @param string|null $name 62 | */ 63 | public function getSidebar($name = null) 64 | { 65 | \get_sidebar($name); 66 | } 67 | 68 | /** 69 | * Displays Wordpress theme footer. 70 | * 71 | * @param string|null $name 72 | */ 73 | public function getFooter($name = null) 74 | { 75 | \get_footer($name); 76 | } 77 | 78 | /** 79 | * Displays a Wordpress theme template part. 80 | * 81 | * @param string $slug 82 | * @param string|null $name 83 | */ 84 | public function getTemplatePart($slug, $name = null) 85 | { 86 | \get_template_part($slug, $name); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Security/WordpressEntryPoint.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | use Symfony\Component\HttpFoundation\RedirectResponse; 22 | use Symfony\Component\HttpFoundation\Request; 23 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; 24 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 25 | use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface; 26 | use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; 27 | 28 | /** 29 | * Class WordpressEntryPoint. 30 | * 31 | * This is a Symfony security component entry point to manage Wordpress login. 32 | */ 33 | class WordpressEntryPoint implements AccessDeniedHandlerInterface, AuthenticationEntryPointInterface 34 | { 35 | /** 36 | * @var string URL to wp-login.php 37 | */ 38 | private $loginUrl; 39 | 40 | /** 41 | * @param string $loginUrl URL to wp-login.php 42 | */ 43 | public function __construct($loginUrl = '/wp-login.php') 44 | { 45 | $this->loginUrl = $loginUrl; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function start(Request $request, AuthenticationException $authException = null) 52 | { 53 | return $this->createRedirectResponse($request); 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function handle(Request $request, AccessDeniedException $accessDeniedException) 60 | { 61 | return $this->createRedirectResponse($request); 62 | } 63 | 64 | /** 65 | * Creates a redirect response from the given request. 66 | * 67 | * @param Request $request 68 | * 69 | * @return \Symfony\Component\HttpFoundation\Response|static 70 | */ 71 | private function createRedirectResponse(Request $request) 72 | { 73 | $url = $this->loginUrl.'?'.http_build_query([ 74 | 'redirect_to' => $request->getUri(), 75 | 'reauth' => 0, 76 | ]); 77 | 78 | return RedirectResponse::create($url, 302); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/Link.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Listener/WordpressRequestListener.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class WordpressRequestListener 26 | { 27 | /** 28 | * @var Wordpress 29 | */ 30 | protected $wordpress; 31 | 32 | /** 33 | * @var TokenStorageInterface 34 | */ 35 | protected $tokenStorage; 36 | 37 | /** 38 | * Constructor. 39 | * 40 | * @param Wordpress $wordpress A Wordpress service instance. 41 | * @param TokenStorageInterface $tokenStorage Symfony security token storage 42 | */ 43 | public function __construct(Wordpress $wordpress, TokenStorageInterface $tokenStorage) 44 | { 45 | $this->wordpress = $wordpress; 46 | $this->tokenStorage = $tokenStorage; 47 | } 48 | 49 | /** 50 | * On kernel request method. 51 | * 52 | * @param GetResponseEvent $event 53 | */ 54 | public function onKernelRequest(GetResponseEvent $event) 55 | { 56 | $request = $event->getRequest(); 57 | 58 | // Loads Wordpress source code in order to allow use of WordPress functions in Symfony. 59 | if ('ekino_wordpress_catchall' !== $request->attributes->get('_route')) { 60 | $this->wordpress->loadWordpress(); 61 | } 62 | 63 | $this->checkAuthentication($request); 64 | } 65 | 66 | /** 67 | * Checks if a Wordpress user is authenticated and authenticate him into Symfony security context. 68 | * 69 | * @param Request $request 70 | */ 71 | protected function checkAuthentication(Request $request) 72 | { 73 | if (!$request->hasPreviousSession()) { 74 | return; 75 | } 76 | 77 | $session = $request->getSession(); 78 | 79 | if ($session->has('token')) { 80 | $token = $session->get('token'); 81 | $this->tokenStorage->setToken($token); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Tests/Twig/Extension/OptionExtensionTest.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class OptionExtensionTest extends \PHPUnit_Framework_TestCase 21 | { 22 | /** 23 | * @var \PHPUnit_Framework_MockObject_MockObject 24 | */ 25 | protected $optionManager; 26 | 27 | /** 28 | * @var OptionExtension 29 | */ 30 | protected $extension; 31 | 32 | protected function setUp() 33 | { 34 | if (!class_exists('\Twig_Extension')) { 35 | $this->markTestSkipped('Twig is not enabled'); 36 | } 37 | 38 | $this->optionManager = $this->getMockBuilder('Ekino\WordpressBundle\Manager\OptionManager')->disableOriginalConstructor()->getMock(); 39 | $this->extension = new OptionExtension($this->optionManager); 40 | } 41 | 42 | public function testGetName() 43 | { 44 | $this->assertEquals('ekino_wordpress_option', $this->extension->getName()); 45 | } 46 | 47 | public function testGetFunctions() 48 | { 49 | $this->assertContainsOnly('\Twig_SimpleFunction', $this->extension->getFunctions()); 50 | } 51 | 52 | /** 53 | * Check the correct result for an existing option. 54 | */ 55 | public function testGetOption() 56 | { 57 | $optionMock = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Option')->getMock(); 58 | 59 | $this->optionManager->expects($this->once()) 60 | ->method('findOneByOptionName') 61 | ->with($this->equalTo('test')) 62 | ->will($this->returnValue($optionMock)); 63 | 64 | $result = $this->extension->getOption('test'); 65 | $this->assertEquals($optionMock, $result); 66 | } 67 | 68 | /** 69 | * Check the usage of default return value for a non existing option. 70 | */ 71 | public function testGetOptionUndefined() 72 | { 73 | $this->optionManager->expects($this->once()) 74 | ->method('findOneByOptionName') 75 | ->with($this->equalTo('test')) 76 | ->will($this->returnValue(null)); 77 | 78 | $result = $this->extension->getOption('test', 'poney'); 79 | $this->assertEquals('poney', $result); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/Entity/CommentTest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class CommentTest extends \PHPUnit_Framework_TestCase 25 | { 26 | /** 27 | * Test entity getters & setters. 28 | */ 29 | public function testGettersSetters() 30 | { 31 | $entity = new Comment(); 32 | 33 | $entity->setAgent('agent'); 34 | $entity->setApproved('approved'); 35 | $entity->setAuthor('author'); 36 | $entity->setAuthorEmail('author@email.com'); 37 | $entity->setAuthorIp('1.2.3.4'); 38 | $entity->setAuthorUrl('http://author.com'); 39 | $entity->setContent('content'); 40 | 41 | $date = new \DateTime(); 42 | $entity->setDate($date); 43 | $entity->setDateGmt($date); 44 | 45 | $entity->setKarma(2); 46 | 47 | $parent = new Comment(); 48 | $parent->setContent('parent content'); 49 | $entity->setParent($parent); 50 | 51 | $post = new Post(); 52 | $post->setTitle('post title'); 53 | $entity->setPost($post); 54 | 55 | $entity->setType('type'); 56 | 57 | $user = new User(); 58 | $user->setDisplayName('author name'); 59 | $entity->setUser($user); 60 | 61 | $this->assertEquals('agent', $entity->getAgent()); 62 | $this->assertEquals('approved', $entity->getApproved()); 63 | $this->assertEquals('author', $entity->getAuthor()); 64 | $this->assertEquals('author@email.com', $entity->getAuthorEmail()); 65 | $this->assertEquals('1.2.3.4', $entity->getAuthorIp()); 66 | $this->assertEquals('http://author.com', $entity->getAuthorUrl()); 67 | $this->assertEquals('content', $entity->getContent()); 68 | $this->assertEquals($date, $entity->getDate()); 69 | $this->assertEquals($date, $entity->getDateGmt()); 70 | $this->assertEquals(2, $entity->getKarma()); 71 | $this->assertEquals('parent content', $entity->getParent()->getContent()); 72 | $this->assertEquals('post title', $entity->getPost()->getTitle()); 73 | $this->assertEquals('type', $entity->getType()); 74 | $this->assertEquals('author name', $entity->getUser()->getDisplayName()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Tests/Controller/WordpressControllerTest.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class WordpressControllerTest extends \PHPUnit_Framework_TestCase 21 | { 22 | protected $wp_query; 23 | 24 | /** 25 | * @var \Ekino\WordpressBundle\Wordpress\Wordpress 26 | */ 27 | protected $wordpress; 28 | 29 | /** 30 | * Set up required mocks for Wordpress controller class. 31 | */ 32 | protected function setUp() 33 | { 34 | // Set up Wordpress instance mock 35 | $this->wordpress = $this->getWordpressMock(); 36 | 37 | $this->wordpress->expects($this->any()) 38 | ->method('getContent') 39 | ->will($this->returnValue('My fake Wordpress content')); 40 | 41 | $this->wordpress->initialize(); 42 | } 43 | 44 | /** 45 | * Test catchAllAction() method. 46 | */ 47 | public function testCatchAllAction() 48 | { 49 | $controller = $this->getMockBuilder('\Ekino\WordpressBundle\Controller\WordpressController') 50 | ->setMethods(['getWordpress']) 51 | ->getMock(); 52 | $controller->expects($this->any())->method('getWordpress')->will($this->returnValue($this->wordpress)); 53 | 54 | $response = $controller->catchAllAction(); 55 | 56 | $this->assertInstanceOf('\Ekino\WordpressBundle\Wordpress\WordpressResponse', $response, 'Should returns a WordpressResponse instance'); 57 | } 58 | 59 | /** 60 | * Returns a mock of Wordpress class. 61 | * 62 | * @return \Ekino\WordpressBundle\Wordpress\Wordpress 63 | */ 64 | protected function getWordpressMock() 65 | { 66 | $kernel = $this->getKernelMock(); 67 | 68 | return $this->getMockBuilder('\Ekino\WordpressBundle\Wordpress\Wordpress') 69 | ->setMethods(['getContent']) 70 | ->setConstructorArgs([$kernel, ['wp_test_global1', 'wp_test_global2']]) 71 | ->getMock(); 72 | } 73 | 74 | /** 75 | * Returns a mock of Symfony kernel. 76 | * 77 | * @return \Symfony\Component\HttpKernel\Kernel 78 | */ 79 | protected function getKernelMock() 80 | { 81 | return $this->getMockBuilder('\Symfony\Component\HttpKernel\Kernel') 82 | ->disableOriginalConstructor() 83 | ->getMock(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Tests/Manager/PostMetaManagerTest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class PostMetaManagerTest extends \PHPUnit_Framework_TestCase 24 | { 25 | /** 26 | * @var EntityManager 27 | */ 28 | protected $entityManager; 29 | 30 | /** 31 | * @var PostMetaRepository 32 | */ 33 | protected $repository; 34 | 35 | /** 36 | * @var PostMetaManager 37 | */ 38 | protected $manager; 39 | 40 | /** 41 | * Sets up a PostMetaManager instance. 42 | */ 43 | protected function setUp() 44 | { 45 | $this->entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock(); 46 | $this->repository = $this->getMockBuilder('Ekino\WordpressBundle\Repository\PostMetaRepository')->disableOriginalConstructor()->getMock(); 47 | $this->entityManager->expects($this->any()) 48 | ->method('getRepository') 49 | ->will($this->returnValue($this->repository)); 50 | 51 | $this->manager = new PostMetaManager($this->entityManager, 'Ekino\WordpressBundle\Entity\PostMeta'); 52 | } 53 | 54 | public function testGetPostMetaCollection() 55 | { 56 | $query = $this->getMockBuilder('Ekino\WordpressBundle\Tests\Manager\QueryMock')->disableOriginalConstructor()->getMock(); 57 | $this->repository->expects($this->once()) 58 | ->method('getPostMetaQuery') 59 | ->will($this->returnValue($query)); 60 | 61 | $query->expects($this->once()) 62 | ->method('getResult'); 63 | 64 | $this->manager->getPostMeta(22, 'test', false); 65 | } 66 | } 67 | 68 | class QueryMock extends AbstractQuery 69 | { 70 | /** 71 | * Gets the SQL query that corresponds to this query object. 72 | * The returned SQL syntax depends on the connection driver that is used 73 | * by this query object at the time of this method call. 74 | * 75 | * @return string SQL query 76 | */ 77 | public function getSQL() 78 | { 79 | return ''; 80 | } 81 | 82 | /** 83 | * Executes the query and returns a the resulting Statement object. 84 | * 85 | * @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results. 86 | */ 87 | protected function _doExecute() 88 | { 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/Comment.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Tests/Twig/Extension/PostMetaExtensionTest.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class PostMetaExtensionTest extends \PHPUnit_Framework_TestCase 28 | { 29 | /** 30 | * @var \PHPUnit_Framework_MockObject_MockObject 31 | */ 32 | protected $postMetaManager; 33 | 34 | /** 35 | * @var PostMetaExtension 36 | */ 37 | protected $extension; 38 | 39 | protected function setUp() 40 | { 41 | if (!class_exists('\Twig_Extension')) { 42 | $this->markTestSkipped('Twig is not enabled'); 43 | } 44 | 45 | $this->postMetaManager = $this->getMockBuilder('Ekino\WordpressBundle\Manager\PostMetaManager')->disableOriginalConstructor()->getMock(); 46 | $this->extension = new PostMetaExtension($this->postMetaManager); 47 | } 48 | 49 | /** 50 | * Get test name. 51 | */ 52 | public function testGetName() 53 | { 54 | $this->assertEquals('ekino_wordpress_post_meta', $this->extension->getName()); 55 | } 56 | 57 | /** 58 | * Get test functions. 59 | */ 60 | public function testGetFunctions() 61 | { 62 | $this->assertContainsOnly('\Twig_SimpleFunction', $this->extension->getFunctions()); 63 | } 64 | 65 | /** 66 | * Check the correct result for an existing option. 67 | */ 68 | public function testGetPostMeta() 69 | { 70 | $postMeta = $this->getMockBuilder('Ekino\WordpressBundle\Entity\PostMeta')->getMock(); 71 | $this->postMetaManager->expects($this->once()) 72 | ->method('getPostMeta') 73 | ->with($this->equalTo(12), $this->equalTo('meta-test'), $this->equalTo(true)) 74 | ->will($this->returnValue($postMeta)); 75 | 76 | $result = $this->extension->getPostMeta(12, 'meta-test', true); 77 | $this->assertEquals($postMeta, $result); 78 | } 79 | 80 | /** 81 | * Check getImageUrlFromId method. 82 | */ 83 | public function testGetImageUrlFromId() 84 | { 85 | $this->assertEquals('http://www.exemple.com/image.jpg', $this->extension->getImageUrlFromId(1)); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Resources/config/twig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Ekino\WordpressBundle\Twig\Extension\CommentExtension 9 | Ekino\WordpressBundle\Twig\Extension\OptionExtension 10 | Ekino\WordpressBundle\Twig\Extension\PostExtension 11 | Ekino\WordpressBundle\Twig\Extension\PostMetaExtension 12 | Ekino\WordpressBundle\Twig\Extension\TermTaxonomyExtension 13 | Ekino\WordpressBundle\Twig\Extension\ThemeExtension 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | %ekino.wordpress.cookie_hash% 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Tests/Entity/UserTest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class UserTest extends \PHPUnit_Framework_TestCase 25 | { 26 | /** 27 | * Test entity getters & setters. 28 | */ 29 | public function testGettersSetters() 30 | { 31 | $entity = new User(); 32 | 33 | $entity->setActivationKey('activation-key'); 34 | $entity->setDisplayName('display name'); 35 | $entity->setEmail('user@email.com'); 36 | $entity->setLogin('login'); 37 | 38 | $collection = new ArrayCollection(); 39 | $meta1 = new UserMeta(); 40 | $meta1->setKey('meta-key'); 41 | $meta1->setValue('meta-value'); 42 | $meta1->setUser($entity); 43 | $collection->add($entity); 44 | $entity->setMetas($collection); 45 | 46 | $entity->setNicename('nice name'); 47 | $entity->setPass('pass'); 48 | 49 | $date = new \DateTime(); 50 | $entity->setRegistered($date); 51 | 52 | $entity->setStatus(2); 53 | $entity->setUrl('http://www.url.com'); 54 | 55 | $this->assertEquals('activation-key', $entity->getActivationKey()); 56 | $this->assertEquals('display name', $entity->getDisplayName()); 57 | $this->assertEquals('user@email.com', $entity->getEmail()); 58 | $this->assertEquals('login', $entity->getLogin()); 59 | $this->assertEquals($collection, $entity->getMetas()); 60 | $this->assertEquals('nice name', $entity->getNicename()); 61 | $this->assertEquals('pass', $entity->getPass()); 62 | $this->assertEquals($date, $entity->getRegistered()); 63 | $this->assertEquals(2, $entity->getStatus()); 64 | $this->assertEquals('http://www.url.com', $entity->getUrl()); 65 | } 66 | 67 | /** 68 | * Test setting classic Symfony roles. 69 | */ 70 | public function testSymfonyRoles() 71 | { 72 | $roles = ['ROLE_ADMINISTRATOR']; 73 | 74 | $user = new User(); 75 | $user->setRoles($roles); 76 | 77 | $this->assertEquals(['ROLE_ADMINISTRATOR'], $user->getRoles()); 78 | } 79 | 80 | /** 81 | * Test setting Wordpress roles and should return Symfony roles. 82 | */ 83 | public function testWordpressRoles() 84 | { 85 | $wordpressRoles = ['author']; 86 | 87 | $user = new User(); 88 | $user->setWordpressRoles($wordpressRoles); 89 | 90 | $this->assertEquals(['ROLE_WP_AUTHOR'], $user->getRoles()); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Event/Hook/UserHookListener.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class UserHookListener 28 | { 29 | /** 30 | * @var UserManager 31 | */ 32 | protected $userManager; 33 | 34 | /** 35 | * @var LoggerInterface 36 | */ 37 | protected $logger; 38 | 39 | /** 40 | * @var TokenStorageInterface 41 | */ 42 | protected $tokenStorage; 43 | 44 | /** 45 | * @var SessionInterface 46 | */ 47 | protected $session; 48 | 49 | /** 50 | * @var string 51 | */ 52 | protected $firewall; 53 | 54 | /** 55 | * Constructor. 56 | * 57 | * @param UserManager $userManager Wordpress bundle user manager 58 | * @param LoggerInterface $logger Symfony PSR logger 59 | * @param TokenStorageInterface $tokenStorage Symfony security token storage 60 | * @param SessionInterface $session Symfony session service 61 | * @param string $firewall EkinoWordpressBundle firewall name 62 | */ 63 | public function __construct(UserManager $userManager, LoggerInterface $logger, TokenStorageInterface $tokenStorage, SessionInterface $session, $firewall) 64 | { 65 | $this->userManager = $userManager; 66 | $this->logger = $logger; 67 | $this->tokenStorage = $tokenStorage; 68 | $this->session = $session; 69 | $this->firewall = $firewall; 70 | } 71 | 72 | /** 73 | * Wordpress user login hook method. 74 | * 75 | * @param WordpressEvent $event 76 | * 77 | * @see http://codex.wordpress.org/Plugin_API/Action_Reference/wp_login 78 | */ 79 | public function onLogin(WordpressEvent $event) 80 | { 81 | $wpUser = $event->getParameter('user'); 82 | 83 | $user = $this->userManager->find($wpUser->data->ID); 84 | $user->setWordpressRoles($wpUser->roles); 85 | 86 | $token = new UsernamePasswordToken($user, $user->getPass(), $this->firewall, $user->getRoles()); 87 | $this->tokenStorage->setToken($token); 88 | 89 | $this->session->set('_security_'.$this->firewall, serialize($token)); 90 | } 91 | 92 | /** 93 | * Wordpress user log out hook method. 94 | * 95 | * @param WordpressEvent $event 96 | * 97 | * @see http://codex.wordpress.org/Plugin_API/Action_Reference/wp_logout 98 | */ 99 | public function onLogout(WordpressEvent $event) 100 | { 101 | $this->session->clear(); 102 | $this->tokenStorage->setToken(null); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Model/Term.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | abstract class Term implements WordpressEntityInterface 23 | { 24 | /** 25 | * @var int 26 | */ 27 | protected $id; 28 | 29 | /** 30 | * @var string 31 | */ 32 | protected $name; 33 | 34 | /** 35 | * @var string 36 | */ 37 | protected $slug; 38 | 39 | /** 40 | * @var int 41 | */ 42 | protected $group; 43 | 44 | /** 45 | * @var ArrayCollection 46 | */ 47 | protected $taxonomies; 48 | 49 | /** 50 | * Constructor. 51 | */ 52 | public function __construct() 53 | { 54 | $this->taxonomies = new ArrayCollection(); 55 | } 56 | 57 | /** 58 | * @return int 59 | */ 60 | public function getId() 61 | { 62 | return $this->id; 63 | } 64 | 65 | /** 66 | * @param int $group 67 | * 68 | * @return Term 69 | */ 70 | public function setGroup($group) 71 | { 72 | $this->group = $group; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * @return int 79 | */ 80 | public function getGroup() 81 | { 82 | return $this->group; 83 | } 84 | 85 | /** 86 | * @param string $slug 87 | * 88 | * @return Term 89 | */ 90 | public function setSlug($slug) 91 | { 92 | $this->slug = $slug; 93 | 94 | return $this; 95 | } 96 | 97 | /** 98 | * @return string 99 | */ 100 | public function getSlug() 101 | { 102 | return $this->slug; 103 | } 104 | 105 | /** 106 | * @param string $name 107 | * 108 | * @return Term 109 | */ 110 | public function setName($name) 111 | { 112 | $this->name = $name; 113 | 114 | return $this; 115 | } 116 | 117 | /** 118 | * @return string 119 | */ 120 | public function getName() 121 | { 122 | return $this->name; 123 | } 124 | 125 | /** 126 | * @param array $taxonomies 127 | * 128 | * @return Term 129 | */ 130 | public function setTaxonomies($taxonomies) 131 | { 132 | $this->taxonomies = $taxonomies; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * @return ArrayCollection 139 | */ 140 | public function getTaxonomies() 141 | { 142 | return $this->taxonomies; 143 | } 144 | 145 | /** 146 | * @param TermTaxonomy $taxonomy 147 | * 148 | * @return Term 149 | */ 150 | public function addTaxonomy(TermTaxonomy $taxonomy) 151 | { 152 | if (!$this->taxonomies->contains($taxonomy)) { 153 | $this->taxonomies[] = $taxonomy; 154 | } 155 | 156 | return $this; 157 | } 158 | 159 | /** 160 | * @param TermTaxonomy $taxonomy 161 | * 162 | * @return Term 163 | */ 164 | public function removeTaxonomy(TermTaxonomy $taxonomy) 165 | { 166 | if ($this->taxonomies->contains($taxonomy)) { 167 | $this->taxonomies->remove($taxonomy); 168 | } 169 | 170 | return $this; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /Tests/Wordpress/WordpressTest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class WordpressTest extends \PHPUnit_Framework_TestCase 23 | { 24 | /** 25 | * @var \Ekino\WordpressBundle\Wordpress\Wordpress 26 | */ 27 | protected $wordpress; 28 | 29 | /** 30 | * This is the fake content returned by Wordpress class. 31 | * 32 | * @var string 33 | */ 34 | protected $content; 35 | 36 | /** 37 | * Set up Wordpress class. 38 | */ 39 | protected function setUp() 40 | { 41 | $this->wordpress = $this->getWordpressMock(); 42 | $this->content = 'My fake Wordpress content'; 43 | 44 | $this->wordpress 45 | ->expects($this->any()) 46 | ->method('getContent') 47 | ->will($this->returnValue($this->content)); 48 | } 49 | 50 | /** 51 | * Tests Wordpress initialize() method. 52 | * 53 | * Should return content of Wordpress 54 | */ 55 | public function testInitialize() 56 | { 57 | $this->wordpress->initialize(); 58 | 59 | $this->assertEquals($this->content, $this->wordpress->getContent(), 'Wordpress content should be returned after initialize()'); 60 | } 61 | 62 | /** 63 | * Tests Wordpress getResponse() method. 64 | * 65 | * Should return a WordpressResponse instance and fake content initialized 66 | */ 67 | public function testGetResponse() 68 | { 69 | $this->wordpress->initialize(); 70 | 71 | $response = $this->wordpress->getResponse(); 72 | 73 | $this->assertInstanceOf('\Ekino\WordpressBundle\Wordpress\WordpressResponse', $response, 'Should return a WordpressResponse instance'); 74 | $this->assertEquals($this->content, $response->getContent(), 'Wordpress content should be returned'); 75 | } 76 | 77 | /** 78 | * Returns an exception when specified Wordpress directory is not found. 79 | */ 80 | public function testExceptionWhenDirectoryNotFound() 81 | { 82 | $this->setExpectedException('InvalidArgumentException'); 83 | 84 | $wordpress = new Wordpress('/a/path/that/does/not/exists', ['wp_test_global1', 'wp_test_global2']); 85 | $wordpress->initialize(); 86 | } 87 | 88 | public function testGlobalVariables() 89 | { 90 | // When 91 | $this->wordpress->initialize(); 92 | 93 | // Then 94 | $this->assertArrayHasKey('wp_test_global1', $GLOBALS); 95 | $this->assertArrayHasKey('wp_test_global2', $GLOBALS); 96 | 97 | $this->assertFalse(array_key_exists('wp_test_global3', $GLOBALS)); 98 | } 99 | 100 | /** 101 | * Returns a mock of Wordpress class. 102 | * 103 | * @return \Ekino\WordpressBundle\Wordpress\Wordpress 104 | */ 105 | protected function getWordpressMock() 106 | { 107 | return $this->getMockBuilder('\Ekino\WordpressBundle\Wordpress\Wordpress') 108 | ->setMethods(['getContent']) 109 | ->setConstructorArgs([__DIR__, ['wp_test_global1', 'wp_test_global2']]) 110 | ->getMock(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Resources/config/manager.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | %ekino.wordpress.entity.comment.class% 11 | 12 | 13 | 14 | 15 | %ekino.wordpress.entity.comment_meta.class% 16 | 17 | 18 | 19 | 20 | %ekino.wordpress.entity.link.class% 21 | 22 | 23 | 24 | 25 | %ekino.wordpress.entity.option.class% 26 | 27 | 28 | 29 | 30 | %ekino.wordpress.entity.post.class% 31 | 32 | 33 | 34 | 35 | 36 | %ekino.wordpress.entity.post_meta.class% 37 | 38 | 39 | 40 | 41 | %ekino.wordpress.entity.term.class% 42 | 43 | 44 | 45 | 46 | %ekino.wordpress.entity.term_relationships.class% 47 | 48 | 49 | 50 | 51 | %ekino.wordpress.entity.term_taxonomy.class% 52 | 53 | 54 | 55 | 56 | %ekino.wordpress.entity.user.class% 57 | 58 | 59 | 60 | 61 | %ekino.wordpress.entity.user_meta.class% 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Manager/PostManager.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class PostManager extends BaseManager 27 | { 28 | /** 29 | * @var PostRepository 30 | */ 31 | protected $repository; 32 | 33 | /** 34 | * @var PostMetaManager 35 | */ 36 | protected $postMetaManager; 37 | 38 | /** 39 | * @param EntityManager $em 40 | * @param string $class 41 | * @param PostMetaManager $postMetaManager 42 | */ 43 | public function __construct(EntityManager $em, $class, PostMetaManager $postMetaManager) 44 | { 45 | parent::__construct($em, $class); 46 | 47 | $this->postMetaManager = $postMetaManager; 48 | } 49 | 50 | /** 51 | * @param Post $post 52 | * 53 | * @return bool 54 | */ 55 | public function isCommentingOpened(Post $post) 56 | { 57 | return Post::COMMENT_STATUS_OPEN == $post->getCommentStatus(); 58 | } 59 | 60 | /** 61 | * @param Post $post 62 | * 63 | * @return bool 64 | */ 65 | public function hasComments(Post $post) 66 | { 67 | return 0 < $post->getCommentCount(); 68 | } 69 | 70 | /** 71 | * @param Post $post 72 | * @param Request $request 73 | * @param string $cookieHash 74 | * 75 | * @return bool 76 | */ 77 | public function isPasswordRequired(Post $post, Request $request, $cookieHash) 78 | { 79 | if (!$post->getPassword()) { 80 | return false; 81 | } 82 | 83 | $cookies = $request->cookies; 84 | 85 | if (!$cookies->has('wp-postpass_'.$cookieHash)) { 86 | return true; 87 | } 88 | 89 | $hash = stripslashes($cookies->get('wp-postpass_'.$cookieHash)); 90 | 91 | if (0 !== strpos($hash, '$P$B')) { 92 | return true; 93 | } 94 | 95 | $wpHasher = new PasswordHash(8, true); 96 | 97 | return !$wpHasher->CheckPassword($post->getPassword(), $hash); 98 | } 99 | 100 | /** 101 | * @param Post $post 102 | * 103 | * @return string 104 | */ 105 | public function getThumbnailPath(Post $post) 106 | { 107 | if (!$thumbnailPostMeta = $this->postMetaManager->getThumbnailPostId($post)) { 108 | return ''; 109 | } 110 | 111 | /** @var $post Post */ 112 | if (!$post = $this->find($thumbnailPostMeta->getValue())) { 113 | return ''; 114 | } 115 | 116 | return $post->getGuid(); 117 | } 118 | 119 | /** 120 | * Returns posts for current date or a specified date. 121 | * 122 | * @param \DateTime|null $date 123 | * 124 | * @return array 125 | */ 126 | public function findByDate(\DateTime $date = null) 127 | { 128 | $date = $date ?: new \DateTime(); 129 | 130 | return $this->repository->findByDate($date); 131 | } 132 | 133 | /** 134 | * Returns posts for a specified category. 135 | * 136 | * @param string $category 137 | * 138 | * @return array 139 | */ 140 | public function findByCategory($category) 141 | { 142 | return $this->repository->findByCategory($category); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /Tests/Event/Hook/UserHookListenerTest.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class UserHookListenerTest extends \PHPUnit_Framework_TestCase 21 | { 22 | /** 23 | * @var \Ekino\WordpressBundle\Manager\UserManager 24 | */ 25 | protected $userManager; 26 | 27 | /** 28 | * @var \Psr\Log\LoggerInterface 29 | */ 30 | protected $logger; 31 | 32 | /** 33 | * @var \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface 34 | */ 35 | protected $tokenStorage; 36 | 37 | /** 38 | * @var \Symfony\Component\HttpFoundation\Session\SessionInterface 39 | */ 40 | protected $session; 41 | 42 | /** 43 | * @var string 44 | */ 45 | protected $firewall; 46 | 47 | /** 48 | * @var UserHookListener 49 | */ 50 | protected $listener; 51 | 52 | /** 53 | * Sets up a UserHookListener instance. 54 | */ 55 | protected function setUp() 56 | { 57 | $this->userManager = $this->getMockBuilder('Ekino\WordpressBundle\Manager\UserManager') 58 | ->disableOriginalConstructor() 59 | ->getMock(); 60 | 61 | $this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); 62 | 63 | $this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); 64 | 65 | $this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock(); 66 | 67 | $this->firewall = 'secured_area'; 68 | 69 | $this->listener = new UserHookListener($this->userManager, $this->logger, $this->tokenStorage, $this->session, $this->firewall); 70 | } 71 | 72 | /** 73 | * Tests onLogin() method. 74 | */ 75 | public function testOnLogin() 76 | { 77 | // Given 78 | $wpUserData = new \stdClass(); 79 | $wpUserData->ID = 1; 80 | 81 | $wpUser = new \stdClass(); 82 | $wpUser->data = $wpUserData; 83 | $wpUser->roles = ['administrator']; 84 | 85 | $event = $this->getMockBuilder('Ekino\WordpressBundle\Event\WordpressEvent')->getMock(); 86 | $event->expects($this->once())->method('getParameter')->will($this->returnValue($wpUser)); 87 | 88 | $user = $this->getMockBuilder('Ekino\WordpressBundle\Entity\User')->getMock(); 89 | $user->expects($this->once())->method('setWordpressRoles')->with($wpUser->roles); 90 | $user->expects($this->once())->method('getPass')->will($this->returnValue(1234)); 91 | $user->expects($this->once())->method('getRoles')->will($this->returnValue(['ROLE_WP_ADMINISTRATOR'])); 92 | 93 | $this->userManager->expects($this->once())->method('find')->will($this->returnValue($user)); 94 | 95 | $this->tokenStorage->expects($this->once())->method('setToken'); 96 | 97 | // When - Then 98 | $this->listener->onLogin($event); 99 | } 100 | 101 | /** 102 | * Tests onLogout() method. 103 | */ 104 | public function testOnLogout() 105 | { 106 | // Given 107 | $event = $this->getMockBuilder('Ekino\WordpressBundle\Event\WordpressEvent')->getMock(); 108 | 109 | // When - Then 110 | $this->session->expects($this->once())->method('clear'); 111 | $this->tokenStorage->expects($this->once())->method('setToken')->with(null); 112 | 113 | $this->listener->onLogout($event); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Resources/config/doctrine-model/Post.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Wordpress/Wordpress.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class Wordpress 22 | { 23 | /** 24 | * @var string 25 | */ 26 | protected $wordpressDirectory; 27 | 28 | /** 29 | * @var array 30 | */ 31 | protected $globals; 32 | 33 | /** 34 | * @var WordpressResponse 35 | */ 36 | protected $response; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | protected $alreadyInitialized = false; 42 | 43 | /** 44 | * @param string $wordpressDirectory The wordpress directory installation 45 | * @param array $globals A Wordpress global variables array 46 | */ 47 | public function __construct($wordpressDirectory, array $globals) 48 | { 49 | $this->globals = $globals; 50 | $this->wordpressDirectory = $wordpressDirectory; 51 | } 52 | 53 | /** 54 | * Initializes Wordpress. 55 | * 56 | * @return $this 57 | */ 58 | public function initialize() 59 | { 60 | $content = $this->getContent(); 61 | $this->response = new WordpressResponse($content); 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * Returns Wordpress content. 68 | * 69 | * @throws \InvalidArgumentException if Wordpress loader cannot be found 70 | * 71 | * @return string 72 | */ 73 | public function getContent() 74 | { 75 | ob_start(); 76 | 77 | define('WP_USE_THEMES', true); 78 | 79 | $this->loadWordpress(); 80 | 81 | return ob_get_clean(); 82 | } 83 | 84 | /** 85 | * Loads Wordpress. 86 | */ 87 | public function loadWordpress() 88 | { 89 | if (!$this->alreadyInitialized) { 90 | foreach ($this->globals as $globalVariable) { 91 | global ${$globalVariable}; 92 | } 93 | 94 | $loader = $this->getWordpressDirectory().'wp-blog-header.php'; 95 | 96 | if (!file_exists($loader)) { 97 | throw new \InvalidArgumentException( 98 | sprintf('Unable to find Wordpress loader in: "%s".', $loader) 99 | ); 100 | } 101 | 102 | require_once $loader; 103 | 104 | $this->alreadyInitialized = true; 105 | } 106 | } 107 | 108 | /** 109 | * Returns Wordpress content response. 110 | * 111 | * @return WordpressResponse 112 | */ 113 | public function getResponse() 114 | { 115 | return $this->response; 116 | } 117 | 118 | /** 119 | * @return null|\WP_Query 120 | */ 121 | public function getWpQuery() 122 | { 123 | global $wp_query; 124 | 125 | if (null === $wp_query || !$wp_query instanceof \WP_Query) { 126 | return; 127 | } 128 | 129 | return $wp_query; 130 | } 131 | 132 | /** 133 | * Returns Wordpress directory if specified in configuration 134 | * otherwise returns default structure:. 135 | * 136 | * wordpress 137 | * |- symfony <-- Symfony application must be installed on Wordpress root directory by default 138 | * |- index.php 139 | * |- wp-content 140 | * |- ... 141 | * 142 | * @return string 143 | */ 144 | protected function getWordpressDirectory() 145 | { 146 | return '/' == substr($this->wordpressDirectory, -1) ? $this->wordpressDirectory : $this->wordpressDirectory.'/'; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Tests/Entity/PostTest.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class PostTest extends \PHPUnit_Framework_TestCase 26 | { 27 | /** 28 | * Test entity getters & setters. 29 | */ 30 | public function testGettersSetters() 31 | { 32 | $entity = new Post(); 33 | 34 | $user = new User(); 35 | $user->setDisplayName('author name'); 36 | $entity->setAuthor($user); 37 | 38 | $entity->setCommentCount(5); 39 | $entity->setCommentStatus('approved'); 40 | $entity->setContent('post content'); 41 | $entity->setContentFiltered('post content filtered'); 42 | 43 | $date = new \DateTime(); 44 | $entity->setDate($date); 45 | $entity->setDateGmt($date); 46 | 47 | $entity->setExcerpt('excerpt'); 48 | $entity->setGuid('guid'); 49 | $entity->setMenuOrder(2); 50 | 51 | $meta1 = new PostMeta(); 52 | $meta1->setKey('meta key'); 53 | $meta1->setValue('meta value'); 54 | $meta1->setPost($entity); 55 | 56 | $collection = new ArrayCollection(); 57 | $collection->add($meta1); 58 | 59 | $entity->setMetas($collection); 60 | $entity->setMimeType('text/html'); 61 | $entity->setModified($date); 62 | $entity->setModifiedGmt($date); 63 | $entity->setName('post name'); 64 | 65 | $parent = new Post(); 66 | $parent->setTitle('parent post title'); 67 | $entity->setParent($parent); 68 | 69 | $entity->setPassword('password'); 70 | $entity->setPinged('pinged'); 71 | $entity->setPingStatus('done'); 72 | $entity->setStatus('published'); 73 | $entity->setTitle('post title'); 74 | $entity->setToPing('to ping'); 75 | $entity->setType('post type'); 76 | 77 | $this->assertEquals('author name', $entity->getAuthor()->getDisplayName()); 78 | $this->assertEquals(5, $entity->getCommentCount()); 79 | $this->assertEquals('approved', $entity->getCommentStatus()); 80 | $this->assertEquals('post content', $entity->getContent()); 81 | $this->assertEquals('post content filtered', $entity->getContentFiltered()); 82 | $this->assertEquals($date, $entity->getDate()); 83 | $this->assertEquals($date, $entity->getDateGmt()); 84 | $this->assertEquals('excerpt', $entity->getExcerpt()); 85 | $this->assertEquals('guid', $entity->getGuid()); 86 | $this->assertEquals(2, $entity->getMenuOrder()); 87 | $this->assertEquals($collection, $entity->getMetas()); 88 | $this->assertEquals('text/html', $entity->getMimeType()); 89 | $this->assertEquals($date, $entity->getModified()); 90 | $this->assertEquals($date, $entity->getModifiedGmt()); 91 | $this->assertEquals('post name', $entity->getName()); 92 | $this->assertEquals('parent post title', $entity->getParent()->getTitle()); 93 | $this->assertEquals('password', $entity->getPassword()); 94 | $this->assertEquals('pinged', $entity->getPinged()); 95 | $this->assertEquals('done', $entity->getPingStatus()); 96 | $this->assertEquals('published', $entity->getStatus()); 97 | $this->assertEquals('post title', $entity->getTitle()); 98 | $this->assertEquals('to ping', $entity->getToPing()); 99 | $this->assertEquals('post type', $entity->getType()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/RegisterMappingsPass.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Ekino\WordpressBundle\DependencyInjection\Compiler; 13 | 14 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 15 | use Symfony\Component\DependencyInjection\ContainerBuilder; 16 | use Symfony\Component\DependencyInjection\Definition; 17 | use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; 18 | 19 | /** 20 | * Class RegisterMappingsPass. 21 | * 22 | * This compiler pass registers the bundle schema with the Doctrine one 23 | * 24 | * @author Xavier Coureau 25 | * @author David Buchmann 26 | */ 27 | class RegisterMappingsPass implements CompilerPassInterface 28 | { 29 | /** 30 | * @var \Symfony\Component\DependencyInjection\Definition 31 | */ 32 | private $driver; 33 | 34 | /** 35 | * @var string 36 | */ 37 | private $driverPattern; 38 | 39 | /** 40 | * @var array 41 | */ 42 | private $namespaces; 43 | 44 | /** 45 | * @var string 46 | */ 47 | private $enabledParameter; 48 | 49 | /** 50 | * @var string 51 | */ 52 | private $fallbackManagerParameter; 53 | 54 | /** 55 | * @param Definition $driver 56 | * @param string $driverPattern 57 | * @param array $namespaces 58 | * @param string $enabledParameter 59 | * @param string $fallbackManagerParameter 60 | */ 61 | public function __construct($driver, $driverPattern, $namespaces, $enabledParameter, $fallbackManagerParameter) 62 | { 63 | $this->driver = $driver; 64 | $this->driverPattern = $driverPattern; 65 | $this->namespaces = $namespaces; 66 | $this->enabledParameter = $enabledParameter; 67 | $this->fallbackManagerParameter = $fallbackManagerParameter; 68 | } 69 | 70 | /** 71 | * Register mappings with the metadata drivers. 72 | * 73 | * @param ContainerBuilder $container 74 | */ 75 | public function process(ContainerBuilder $container) 76 | { 77 | if (!$container->hasParameter($this->enabledParameter)) { 78 | return; 79 | } 80 | 81 | $chainDriverDefService = $this->getChainDriverServiceName($container); 82 | $chainDriverDef = $container->getDefinition($chainDriverDefService); 83 | 84 | foreach ($this->namespaces as $namespace) { 85 | $chainDriverDef->addMethodCall('addDriver', [$this->driver, $namespace]); 86 | } 87 | } 88 | 89 | /** 90 | * @param ContainerBuilder $container 91 | * 92 | * @throws \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException 93 | * 94 | * @return string 95 | */ 96 | protected function getChainDriverServiceName(ContainerBuilder $container) 97 | { 98 | foreach (['ekino_wordpress.model_manager_name', $this->fallbackManagerParameter] as $param) { 99 | if ($container->hasParameter($param)) { 100 | $name = $container->getParameter($param); 101 | if ($name) { 102 | return sprintf($this->driverPattern, $name); 103 | } 104 | } 105 | } 106 | 107 | throw new ParameterNotFoundException('None of the managerParameters resulted in a valid name'); 108 | } 109 | 110 | /** 111 | * @param array $mappings 112 | * 113 | * @return RegisterMappingsPass 114 | */ 115 | public static function createOrmMappingDriver(array $mappings) 116 | { 117 | $arguments = [$mappings, '.orm.xml']; 118 | $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator', $arguments); 119 | $driver = new Definition('Doctrine\ORM\Mapping\Driver\XmlDriver', [$locator]); 120 | 121 | return new self($driver, 'doctrine.orm.%s_metadata_driver', $mappings, 'ekino_wordpress.backend_type_orm', 'doctrine.default_entity_manager'); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Manager/BaseManager.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class BaseManager 23 | { 24 | /** 25 | * @var \Doctrine\ORM\EntityManager 26 | */ 27 | protected $em; 28 | 29 | /** 30 | * @var EntityRepository 31 | */ 32 | protected $repository; 33 | 34 | /** 35 | * @var string Class name 36 | */ 37 | protected $class; 38 | 39 | /** 40 | * Constructor. 41 | * 42 | * @param EntityManager $em Entity manager 43 | * @param string $class Class name 44 | */ 45 | public function __construct(EntityManager $em, $class) 46 | { 47 | $this->class = $class; 48 | $this->em = $em; 49 | $this->repository = $em->getRepository($this->class); 50 | } 51 | 52 | /** 53 | * Returns a new non-managed entity. 54 | * 55 | * @return mixed 56 | */ 57 | public function create() 58 | { 59 | return new $this->class(); 60 | } 61 | 62 | /** 63 | * Returns a "fresh" entity by identifier. 64 | * 65 | * @param int $id Entity identifier 66 | * 67 | * @return object 68 | */ 69 | public function find($id) 70 | { 71 | return $this->repository->findOneById($id); 72 | } 73 | 74 | /** 75 | * Returns an entity by id. 76 | * 77 | * @param int $id Entity id 78 | * 79 | * @return object 80 | */ 81 | public function findOneById($id) 82 | { 83 | return $this->repository->findOneById($id); 84 | } 85 | 86 | /** 87 | * Returns all entities of the child class. 88 | * 89 | * @return array 90 | */ 91 | public function findAll() 92 | { 93 | return $this->repository->findAll(); 94 | } 95 | 96 | /** 97 | * Returns entities found for given criteria. 98 | * 99 | * @param array $criteria 100 | * 101 | * @return object 102 | */ 103 | public function findBy(array $criteria) 104 | { 105 | return $this->repository->findBy($criteria); 106 | } 107 | 108 | /** 109 | * Returns entity found for given criteria. 110 | * 111 | * @param array $criteria 112 | * 113 | * @return object 114 | */ 115 | public function findOneBy(array $criteria) 116 | { 117 | return $this->repository->findOneBy($criteria); 118 | } 119 | 120 | /** 121 | * Flush persisted entities. 122 | */ 123 | public function flush() 124 | { 125 | $this->em->flush(); 126 | } 127 | 128 | /** 129 | * Refresh persisted entities. 130 | */ 131 | public function refresh($entity) 132 | { 133 | $this->em->refresh($entity); 134 | } 135 | 136 | /** 137 | * Clears the repository, causing all managed entities to become detached. 138 | */ 139 | public function clear() 140 | { 141 | $this->em->clear(); 142 | } 143 | 144 | /** 145 | * Persist the given entity. 146 | * 147 | * @param mixed $entity An entity instance 148 | * @param bool $doFlush Also flush entity manager? 149 | */ 150 | public function save($entity, $doFlush = true) 151 | { 152 | $this->em->persist($entity); 153 | 154 | if ($doFlush) { 155 | $this->em->flush(); 156 | } 157 | } 158 | 159 | /** 160 | * Delete the given entity. 161 | * 162 | * @param object $entity An entity instance 163 | */ 164 | public function remove($entity) 165 | { 166 | $this->em->remove($entity); 167 | $this->em->flush(); 168 | } 169 | 170 | /** 171 | * Returns entity repository. 172 | * 173 | * @return \Doctrine\ORM\EntityRepository|EntityRepository 174 | */ 175 | public function getRepository() 176 | { 177 | return $this->repository; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /Event/Subscriber/LoadMetadataSubscriber.php: -------------------------------------------------------------------------------- 1 | classes = $classes; 34 | } 35 | 36 | /** 37 | * @return array 38 | */ 39 | public function getSubscribedEvents() 40 | { 41 | return [ 42 | 'loadClassMetadata', 43 | ]; 44 | } 45 | 46 | /** 47 | * @param LoadClassMetadataEventArgs $eventArgs 48 | */ 49 | public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) 50 | { 51 | /** @var ClassMetadata $metadata */ 52 | $metadata = $eventArgs->getClassMetadata(); 53 | 54 | $this->toEntity($metadata); 55 | 56 | if (!$metadata->isMappedSuperclass) { 57 | $this->setAssociationMappings($metadata, $eventArgs->getEntityManager()->getConfiguration()); 58 | } else { 59 | $this->unsetAssociationMappings($metadata); 60 | } 61 | } 62 | 63 | /** 64 | * Transform a mapped superclass into entity if needed. 65 | * 66 | * @param ClassMetadataInfo $metadata 67 | */ 68 | private function toEntity(ClassMetadataInfo $metadata) 69 | { 70 | foreach ($this->classes as $name => $class) { 71 | if (!is_array($class) || $class['class'] != $metadata->getName()) { 72 | continue; 73 | } 74 | 75 | if (isset($class['class'])) { 76 | $metadata->isMappedSuperclass = false; 77 | } 78 | 79 | if (isset($class['repository_class'])) { 80 | $metadata->setCustomRepositoryClass($class['repository_class']); 81 | } 82 | } 83 | } 84 | 85 | /** 86 | * @param ClassMetadataInfo $metadata 87 | * @param \Doctrine\ORM\Configuration $configuration 88 | */ 89 | private function setAssociationMappings(ClassMetadataInfo $metadata, $configuration) 90 | { 91 | foreach (class_parents($metadata->getName()) as $parent) { 92 | $parentMetadata = new ClassMetadata( 93 | $parent, 94 | $configuration->getNamingStrategy() 95 | ); 96 | 97 | if (in_array($parent, $configuration->getMetadataDriverImpl()->getAllClassNames())) { 98 | $configuration->getMetadataDriverImpl()->loadMetadataForClass($parent, $parentMetadata); 99 | 100 | if ($parentMetadata->isMappedSuperclass) { 101 | foreach ($parentMetadata->getAssociationMappings() as $key => $value) { 102 | if ($this->hasRelation($value['type'])) { 103 | $metadata->associationMappings[$key] = $value; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | 111 | /** 112 | * @param ClassMetadataInfo $metadata 113 | */ 114 | private function unsetAssociationMappings(ClassMetadataInfo $metadata) 115 | { 116 | foreach ($metadata->getAssociationMappings() as $key => $value) { 117 | if ($this->hasRelation($value['type'])) { 118 | unset($metadata->associationMappings[$key]); 119 | } 120 | } 121 | } 122 | 123 | /** 124 | * @param int $type 125 | * 126 | * @return bool 127 | */ 128 | private function hasRelation($type) 129 | { 130 | return in_array( 131 | $type, 132 | [ 133 | ClassMetadataInfo::MANY_TO_MANY, 134 | ClassMetadataInfo::ONE_TO_MANY, 135 | ClassMetadataInfo::ONE_TO_ONE, 136 | ], 137 | true 138 | ); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Tests/Twig/Extension/ThemeExtensionTest.php: -------------------------------------------------------------------------------- 1 | 72 | */ 73 | class ThemeExtensionTest extends \PHPUnit_Framework_TestCase 74 | { 75 | /** 76 | * @var ThemeExtension 77 | */ 78 | protected $extension; 79 | 80 | /** 81 | * Sets up a Twig Theme extension instance. 82 | */ 83 | protected function setUp() 84 | { 85 | if (!class_exists('\Twig_Extension')) { 86 | $this->markTestSkipped('Twig is not enabled'); 87 | } 88 | 89 | $this->extension = new ThemeExtension(); 90 | } 91 | 92 | /** 93 | * Tests the getName() method. 94 | */ 95 | public function testGetName() 96 | { 97 | $this->assertEquals('ekino_wordpress_theme', $this->extension->getName()); 98 | } 99 | 100 | /** 101 | * Tests the getFunctions() method. 102 | */ 103 | public function testGetFunctions() 104 | { 105 | $this->assertContainsOnly('\Twig_SimpleFunction', $this->extension->getFunctions()); 106 | } 107 | 108 | /** 109 | * Tests the getHeader() method (Twig function: wp_get_header()). 110 | */ 111 | public function testGetHeader() 112 | { 113 | ob_start(); 114 | $this->extension->getHeader(); 115 | $content = ob_get_clean(); 116 | 117 | $this->assertEquals('wordpress headerwordpress admin bar initwordpress admin bar render', $content); 118 | } 119 | 120 | /** 121 | * Tests the getSidebar() method (Twig function: wp_get_sidebar()). 122 | */ 123 | public function testGetSidebar() 124 | { 125 | ob_start(); 126 | $this->extension->getSidebar(); 127 | $content = ob_get_clean(); 128 | 129 | $this->assertEquals('wordpress sidebar', $content); 130 | } 131 | 132 | /** 133 | * Tests the getFooter() method (Twig function: wp_get_footer()). 134 | */ 135 | public function testGetFooter() 136 | { 137 | ob_start(); 138 | $this->extension->getFooter(); 139 | $content = ob_get_clean(); 140 | 141 | $this->assertEquals('wordpress footer', $content); 142 | } 143 | 144 | /** 145 | * Tests the getTemplatePart() method (Twig function: wp_get_template_part()). 146 | */ 147 | public function testGetTemplatePart() 148 | { 149 | ob_start(); 150 | $this->extension->getTemplatePart('content', 'page'); 151 | $content = ob_get_clean(); 152 | 153 | $this->assertEquals('wordpress template part content-page', $content); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Model/TermTaxonomy.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | abstract class TermTaxonomy implements WordpressEntityInterface 23 | { 24 | /** 25 | * @var int 26 | */ 27 | protected $id; 28 | 29 | /** 30 | * @var Term 31 | */ 32 | protected $term; 33 | 34 | /** 35 | * @var string 36 | */ 37 | protected $taxonomy; 38 | 39 | /** 40 | * @var string 41 | */ 42 | protected $description; 43 | 44 | /** 45 | * @var TermTaxonomy 46 | */ 47 | protected $parent; 48 | 49 | /** 50 | * @var ArrayCollection 51 | */ 52 | protected $relationships; 53 | 54 | /** 55 | * @var int 56 | */ 57 | protected $count; 58 | 59 | /** 60 | * Constructor. 61 | */ 62 | public function __construct() 63 | { 64 | $this->relationships = new ArrayCollection(); 65 | } 66 | 67 | /** 68 | * @return int 69 | */ 70 | public function getId() 71 | { 72 | return $this->id; 73 | } 74 | 75 | /** 76 | * @param int $count 77 | * 78 | * @return TermTaxonomy 79 | */ 80 | public function setCount($count) 81 | { 82 | $this->count = $count; 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * @return int 89 | */ 90 | public function getCount() 91 | { 92 | return $this->count; 93 | } 94 | 95 | /** 96 | * @param string $description 97 | * 98 | * @return TermTaxonomy 99 | */ 100 | public function setDescription($description) 101 | { 102 | $this->description = $description; 103 | 104 | return $this; 105 | } 106 | 107 | /** 108 | * @return string 109 | */ 110 | public function getDescription() 111 | { 112 | return $this->description; 113 | } 114 | 115 | /** 116 | * @param int $parent 117 | * 118 | * @return TermTaxonomy 119 | */ 120 | public function setParent($parent) 121 | { 122 | $this->parent = $parent; 123 | 124 | return $this; 125 | } 126 | 127 | /** 128 | * @return int 129 | */ 130 | public function getParent() 131 | { 132 | return $this->parent; 133 | } 134 | 135 | /** 136 | * @param string $taxonomy 137 | * 138 | * @return TermTaxonomy 139 | */ 140 | public function setTaxonomy($taxonomy) 141 | { 142 | $this->taxonomy = $taxonomy; 143 | 144 | return $this; 145 | } 146 | 147 | /** 148 | * @return string 149 | */ 150 | public function getTaxonomy() 151 | { 152 | return $this->taxonomy; 153 | } 154 | 155 | /** 156 | * @param Term $term 157 | * 158 | * @return TermTaxonomy 159 | */ 160 | public function setTerm(Term $term) 161 | { 162 | $this->term = $term; 163 | 164 | return $this; 165 | } 166 | 167 | /** 168 | * @return Term 169 | */ 170 | public function getTerm() 171 | { 172 | return $this->term; 173 | } 174 | 175 | /** 176 | * @return ArrayCollection 177 | */ 178 | public function getRelationships() 179 | { 180 | return $this->relationships; 181 | } 182 | 183 | /** 184 | * @param TermRelationships $relationship 185 | * 186 | * @return Term 187 | */ 188 | public function addRelationship(TermRelationships $relationship) 189 | { 190 | if (!$this->relationships->contains($relationship)) { 191 | $this->relationships[] = $relationship; 192 | } 193 | 194 | return $this; 195 | } 196 | 197 | /** 198 | * @param TermRelationships $relationship 199 | * 200 | * @return Term 201 | */ 202 | public function removeRelationship(TermRelationships $relationship) 203 | { 204 | if ($this->relationships->contains($relationship)) { 205 | $this->relationships->remove($relationship); 206 | } 207 | 208 | return $this; 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /Tests/Event/Subscriber/WordpressResponseSubscriberTest.php: -------------------------------------------------------------------------------- 1 | event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')->disableOriginalConstructor()->getMock(); 31 | $this->response = $this->getMockBuilder('Ekino\WordpressBundle\Wordpress\WordpressResponse')->disableOriginalConstructor()->getMock(); 32 | $this->wordpress = $this->getMockBuilder('Ekino\WordpressBundle\Wordpress\Wordpress')->disableOriginalConstructor()->getMock(); 33 | 34 | $this->subscriber = new WordpressResponseSubscriber($this->wordpress); 35 | } 36 | 37 | public function testGetSubscribedEvents() 38 | { 39 | $expected = [ 40 | KernelEvents::RESPONSE => ['onKernelResponse'], 41 | ]; 42 | 43 | $this->assertEquals($expected, WordpressResponseSubscriber::getSubscribedEvents()); 44 | } 45 | 46 | public function testOnKernelResponseNoWordpressResponse() 47 | { 48 | $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')->disableOriginalConstructor()->getMock(); 49 | $response = $this->getMockBuilder('Symfony\Component\HttpFoundation\Response')->disableOriginalConstructor()->getMock(); 50 | 51 | $event->expects($this->once()) 52 | ->method('getResponse') 53 | ->will($this->returnValue($response)); 54 | 55 | $response->expects($this->never())->method('setStatusCode'); 56 | 57 | $this->subscriber->onKernelResponse($event); 58 | } 59 | 60 | public function testOnKernelResponseNoMasterRequest() 61 | { 62 | $this->event->expects($this->once()) 63 | ->method('getResponse') 64 | ->will($this->returnValue($this->response)); 65 | $this->event->expects($this->once()) 66 | ->method('getRequestType') 67 | ->will($this->returnValue(HttpKernelInterface::SUB_REQUEST)); 68 | 69 | $this->response->expects($this->never())->method('setStatusCode'); 70 | 71 | $this->subscriber->onKernelResponse($this->event); 72 | } 73 | 74 | public function testOnKernelResponseNoWpQuery() 75 | { 76 | $this->event->expects($this->once()) 77 | ->method('getResponse') 78 | ->will($this->returnValue($this->response)); 79 | $this->event->expects($this->once()) 80 | ->method('getRequestType') 81 | ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST)); 82 | $this->wordpress->expects($this->once()) 83 | ->method('getWpQuery') 84 | ->will($this->returnValue(null)); 85 | 86 | $this->subscriber->onKernelResponse($this->event); 87 | } 88 | 89 | public function testOnKernelResponse() 90 | { 91 | $this->event->expects($this->once()) 92 | ->method('getResponse') 93 | ->will($this->returnValue($this->response)); 94 | $this->event->expects($this->once()) 95 | ->method('getRequestType') 96 | ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST)); 97 | $this->wordpress->expects($this->once()) 98 | ->method('getWpQuery') 99 | ->will($this->returnValue(new WP_QueryMock(true))); 100 | 101 | $this->response->expects($this->once()) 102 | ->method('setStatusCode') 103 | ->with($this->equalTo(404)); 104 | 105 | $this->subscriber->onKernelResponse($this->event); 106 | } 107 | } 108 | 109 | class WP_QueryMock 110 | { 111 | /** 112 | * @var bool 113 | */ 114 | protected $is404; 115 | 116 | public function __construct($is404 = false) 117 | { 118 | $this->is404 = $is404; 119 | } 120 | 121 | public function is_404() 122 | { 123 | return $this->is404; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Tests/Event/Subscriber/I18n/I18nSubscriberTest.php: -------------------------------------------------------------------------------- 1 | defaultLanguage = 'fr'; 34 | $this->cookieName = 'my_wp_i18n_cookie'; 35 | 36 | $this->subscriber = new I18nSubscriber($this->defaultLanguage, $this->cookieName); 37 | } 38 | 39 | /** 40 | * Tests static getSubscribedEvents() method. 41 | */ 42 | public function testGetSubscribedEvents() 43 | { 44 | $this->assertInternalType('array', I18nSubscriber::getSubscribedEvents()); 45 | } 46 | 47 | /** 48 | * Tests onKernelRequest() method when no cookies are existing. 49 | */ 50 | public function testOnKernelRequestNoExisingCookie() 51 | { 52 | $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock(); 53 | $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->getMock(); 54 | $cookies = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag')->disableOriginalConstructor()->getMock(); 55 | $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')->disableOriginalConstructor()->getMock(); 56 | 57 | $request->cookies = $cookies; 58 | 59 | $session->expects($this->once()) 60 | ->method('get') 61 | ->with($this->equalTo('_locale')) 62 | ->will($this->returnValue($this->defaultLanguage)); 63 | 64 | $request->expects($this->once()) 65 | ->method('getSession') 66 | ->will($this->returnValue($session)); 67 | $event->expects($this->once()) 68 | ->method('getRequest') 69 | ->will($this->returnValue($request)); 70 | 71 | $cookies->expects($this->once()) 72 | ->method('get') 73 | ->with($this->equalTo($this->cookieName), $this->equalTo($this->defaultLanguage)) 74 | ->will($this->returnValue($this->defaultLanguage)); 75 | 76 | $session->expects($this->once()) 77 | ->method('set') 78 | ->with($this->equalTo('_locale'), $this->equalTo($this->defaultLanguage)); 79 | $request->expects($this->once()) 80 | ->method('setLocale') 81 | ->with($this->equalTo($this->defaultLanguage)); 82 | 83 | $this->subscriber->onKernelRequest($event); 84 | } 85 | 86 | /** 87 | * Tests onKernelRequest() method. 88 | */ 89 | public function testOnKernelRequest() 90 | { 91 | $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock(); 92 | $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->getMock(); 93 | $cookies = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag')->disableOriginalConstructor()->getMock(); 94 | $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')->disableOriginalConstructor()->getMock(); 95 | 96 | $request->cookies = $cookies; 97 | 98 | $request->expects($this->once()) 99 | ->method('getSession') 100 | ->will($this->returnValue($session)); 101 | $event->expects($this->once()) 102 | ->method('getRequest') 103 | ->will($this->returnValue($request)); 104 | 105 | $cookies->expects($this->once()) 106 | ->method('get') 107 | ->will($this->returnValue('en')); 108 | 109 | $session->expects($this->once()) 110 | ->method('set') 111 | ->with($this->equalTo('_locale'), $this->equalTo('en')); 112 | $request->expects($this->once()) 113 | ->method('setLocale') 114 | ->with($this->equalTo('en')); 115 | 116 | $this->subscriber->onKernelRequest($event); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Twig/Extension/PostExtension.php: -------------------------------------------------------------------------------- 1 | postManager = $postManager; 46 | $this->optionExtension = $optionExtension; 47 | $this->cookieHash = $cookieHash; 48 | } 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function getName() 54 | { 55 | return 'ekino_wordpress_post'; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function getFunctions() 62 | { 63 | return [ 64 | new \Twig_SimpleFunction('wp_comments_open', [$this, 'isCommentingOpened']), 65 | new \Twig_SimpleFunction('wp_get_permalink', [$this, 'getPermalink']), 66 | new \Twig_SimpleFunction('wp_get_the_post_thumbnail_url', [$this, 'getThumbnailUrl']), 67 | new \Twig_SimpleFunction('wp_have_comments', [$this, 'haveComments']), 68 | new \Twig_SimpleFunction('wp_post_password_required', [$this, 'isPostPasswordRequired'], ['needs_context' => true]), 69 | ]; 70 | } 71 | 72 | /** 73 | * @param int|Post $postId A Wordpress post identifier 74 | * @param bool $isAbsolute Determines if you want to retrieve an absolute URL 75 | * 76 | * @throws \UnexpectedValueException 77 | * 78 | * @return string 79 | */ 80 | public function getPermalink($postId, $isAbsolute = false) 81 | { 82 | $post = $postId instanceof Post ? $postId : $this->postManager->find($postId); 83 | 84 | if (!$post) { 85 | throw new \UnexpectedValueException(sprintf('No post with ID "%d"', $postId)); 86 | } 87 | 88 | $permalinkStructure = $this->optionExtension->getOption('permalink_structure', '')->getValue(); 89 | 90 | $relativeUrl = $this->replacePostArguments($permalinkStructure, $post); 91 | 92 | if ($isAbsolute) { 93 | $home = $this->optionExtension->getOption('home'); 94 | 95 | return rtrim($home->getValue(), '/').'/'.ltrim($relativeUrl, '/'); 96 | } 97 | 98 | return $relativeUrl; 99 | } 100 | 101 | /** 102 | * @param string $permalinkStructure 103 | * @param Post $post 104 | * 105 | * @return string 106 | */ 107 | public function replacePostArguments($permalinkStructure, Post $post) 108 | { 109 | $postDate = $post->getDate(); 110 | 111 | $permalinkStructure = str_replace('%year%', $postDate->format('Y'), $permalinkStructure); 112 | $permalinkStructure = str_replace('%monthnum%', $postDate->format('m'), $permalinkStructure); 113 | $permalinkStructure = str_replace('%day%', $postDate->format('d'), $permalinkStructure); 114 | $permalinkStructure = str_replace('%post_id%', $post->getId(), $permalinkStructure); 115 | $permalinkStructure = str_replace('%postname%', $post->getName(), $permalinkStructure); 116 | 117 | return $permalinkStructure; 118 | } 119 | 120 | /** 121 | * @param array $context 122 | * @param Post $post 123 | * 124 | * @return bool 125 | */ 126 | public function isPostPasswordRequired(array $context, Post $post) 127 | { 128 | if (null === $this->cookieHash) { 129 | $this->cookieHash = ''; 130 | 131 | if ($siteUrlOption = $this->optionExtension->getOption('siteurl')) { 132 | $this->cookieHash = md5($siteUrlOption->getValue()); 133 | } 134 | } 135 | 136 | return $this->postManager->isPasswordRequired($post, $context['app']->getRequest(), $this->cookieHash); 137 | } 138 | 139 | /** 140 | * @param Post $post 141 | * 142 | * @return bool 143 | */ 144 | public function isCommentingOpened(Post $post) 145 | { 146 | return $post->isCommentingOpened(); 147 | } 148 | 149 | /** 150 | * @param Post $post 151 | * 152 | * @return bool 153 | */ 154 | public function haveComments(Post $post) 155 | { 156 | return 0 < $post->getCommentCount(); 157 | } 158 | 159 | /** 160 | * @param Post $post 161 | * 162 | * @return string 163 | */ 164 | public function getThumbnailUrl(Post $post) 165 | { 166 | return $this->postManager->getThumbnailPath($post); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /Tests/Twig/Extension/PostExtensionTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Twig is not enabled'); 29 | } 30 | 31 | $this->postManager = $this->getMockBuilder('Ekino\WordpressBundle\Manager\PostManager')->disableOriginalConstructor()->getMock(); 32 | $this->optionExtension = $this->getMockBuilder('Ekino\WordpressBundle\Twig\Extension\OptionExtension')->disableOriginalConstructor()->getMock(); 33 | 34 | $this->postExtension = new PostExtension($this->postManager, $this->optionExtension); 35 | } 36 | 37 | public function testGetName() 38 | { 39 | $this->assertEquals('ekino_wordpress_post', $this->postExtension->getName()); 40 | } 41 | 42 | public function testGetFunctions() 43 | { 44 | $this->assertContainsOnly('\Twig_SimpleFunction', $this->postExtension->getFunctions()); 45 | } 46 | 47 | public function testReplacePostArguments() 48 | { 49 | $permalinkStructure = '/%year%/%monthnum%/%day%/%post_id%-%postname%'; 50 | $post = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Post')->getMock(); 51 | $post->expects($this->once()) 52 | ->method('getDate') 53 | ->will($this->returnValue(new \DateTime())); 54 | $post->expects($this->once()) 55 | ->method('getId') 56 | ->will($this->returnValue('12')); 57 | $post->expects($this->once()) 58 | ->method('getName') 59 | ->will($this->returnValue('sample-post')); 60 | 61 | $result = $this->postExtension->replacePostArguments($permalinkStructure, $post); 62 | 63 | $this->assertEquals(date('/Y/m/d').'/12-sample-post', $result); 64 | } 65 | 66 | public function testGetPermalinkNoPost() 67 | { 68 | $this->postManager->expects($this->once()) 69 | ->method('find') 70 | ->will($this->returnValue(false)); 71 | 72 | $this->setExpectedException('\UnexpectedValueException'); 73 | $this->postExtension->getPermalink(12); 74 | } 75 | 76 | public function testGetPermalink() 77 | { 78 | $post = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Post')->getMock(); 79 | $permalinkOption = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Option')->getMock(); 80 | 81 | $post->expects($this->once()) 82 | ->method('getDate') 83 | ->will($this->returnValue(new \DateTime())); 84 | $post->expects($this->once()) 85 | ->method('getId') 86 | ->will($this->returnValue('12')); 87 | $post->expects($this->once()) 88 | ->method('getName') 89 | ->will($this->returnValue('sample-post')); 90 | 91 | $permalinkOption->expects($this->once()) 92 | ->method('getValue') 93 | ->will($this->returnValue('/%year%/%monthnum%/%day%/%post_id%-%postname%')); 94 | $this->postManager->expects($this->once()) 95 | ->method('find') 96 | ->will($this->returnValue($post)); 97 | $this->optionExtension->expects($this->once()) 98 | ->method('getOption') 99 | ->will($this->returnValue($permalinkOption)); 100 | 101 | $result = $this->postExtension->getPermalink(12); 102 | $this->assertEquals(date('/Y/m/d').'/12-sample-post', $result); 103 | } 104 | 105 | public function testGetAbsolutePermalink() 106 | { 107 | $post = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Post')->getMock(); 108 | $permalinkOption = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Option')->getMock(); 109 | $homeOption = $this->getMockBuilder('Ekino\WordpressBundle\Entity\Option')->getMock(); 110 | 111 | $post->expects($this->once()) 112 | ->method('getDate') 113 | ->will($this->returnValue(new \DateTime())); 114 | $post->expects($this->once()) 115 | ->method('getId') 116 | ->will($this->returnValue('12')); 117 | $post->expects($this->once()) 118 | ->method('getName') 119 | ->will($this->returnValue('sample-post')); 120 | 121 | $permalinkOption->expects($this->once()) 122 | ->method('getValue') 123 | ->will($this->returnValue('/%year%/%monthnum%/%day%/%post_id%-%postname%')); 124 | $homeOption->expects($this->once()) 125 | ->method('getValue') 126 | ->will($this->returnValue('http://localhost/blog/')); 127 | $this->postManager->expects($this->once()) 128 | ->method('find') 129 | ->will($this->returnValue($post)); 130 | $this->optionExtension->expects($this->at(0)) 131 | ->method('getOption') 132 | ->will($this->returnValue($permalinkOption)); 133 | $this->optionExtension->expects($this->at(1)) 134 | ->method('getOption') 135 | ->will($this->returnValue($homeOption)); 136 | 137 | $result = $this->postExtension->getPermalink(12, true); 138 | $this->assertEquals('http://localhost/blog'.date('/Y/m/d').'/12-sample-post', $result); 139 | } 140 | } 141 | --------------------------------------------------------------------------------