From 6e5b259d446ad5ed8b526551e74cf4cdd74690b1 Mon Sep 17 00:00:00 2001 From: franck Date: Sat, 6 Jul 2013 10:18:19 +0200 Subject: [PATCH] Added Feed loop to retreive feeds using SimplePie --- core/lib/Thelia/Config/Resources/config.xml | 1 + core/lib/Thelia/Core/Security/Role/Role.php | 41 ++++++ .../Core/Security/Role/RoleInterface.php | 35 +++++ .../Core/Security/User/UserInterface.php | 14 ++ core/lib/Thelia/Core/Template/Loop/Feed.php | 127 ++++++++++++++++++ core/lib/Thelia/Model/Admin.php | 4 +- core/lib/Thelia/Model/Customer.php | 3 +- templates/admin/default/assets/css/admin.less | 90 ++++++++++++- .../admin/default/includes/footer.inc.html | 14 +- .../admin/default/includes/header.inc.html | 8 +- templates/admin/default/login.html | 44 +++--- 11 files changed, 339 insertions(+), 42 deletions(-) create mode 100644 core/lib/Thelia/Core/Security/Role/Role.php create mode 100644 core/lib/Thelia/Core/Security/Role/RoleInterface.php create mode 100644 core/lib/Thelia/Core/Template/Loop/Feed.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index d1e6569fa..8c1a76003 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -6,6 +6,7 @@ + diff --git a/core/lib/Thelia/Core/Security/Role/Role.php b/core/lib/Thelia/Core/Security/Role/Role.php new file mode 100644 index 000000000..b47e1c089 --- /dev/null +++ b/core/lib/Thelia/Core/Security/Role/Role.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace use Thelia\Core\Security\Role; + +/** + * Role is a simple implementation of a RoleInterface where the role is a + * string. + * + * @author Fabien Potencier + */ +class Role implements RoleInterface +{ + private $role; + + /** + * Constructor. + * + * @param string $role The role name + */ + public function __construct($role) + { + $this->role = (string) $role; + } + + /** + * {@inheritdoc} + */ + public function getRole() + { + return $this->role; + } +} diff --git a/core/lib/Thelia/Core/Security/Role/RoleInterface.php b/core/lib/Thelia/Core/Security/Role/RoleInterface.php new file mode 100644 index 000000000..1a27ae092 --- /dev/null +++ b/core/lib/Thelia/Core/Security/Role/RoleInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Thelia\Core\Security\Role; + +/** + * RoleInterface represents a role granted to a user. + * + * A role must either have a string representation or it needs to be explicitly + * supported by at least one AccessDecisionManager. + * + * @author Fabien Potencier + */ +interface RoleInterface +{ + /** + * Returns the role. + * + * This method returns a string representation whenever possible. + * + * When the role cannot be represented with sufficient precision by a + * string, it should return null. + * + * @return string|null A string representation of the role, or null + */ + public function getRole(); +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Security/User/UserInterface.php b/core/lib/Thelia/Core/Security/User/UserInterface.php index 9057504ca..be158e88c 100644 --- a/core/lib/Thelia/Core/Security/User/UserInterface.php +++ b/core/lib/Thelia/Core/Security/User/UserInterface.php @@ -30,6 +30,20 @@ interface UserInterface { */ public function getAlgo(); + /** + * Returns the roles granted to the user. + * + * + * public function getRoles() + * { + * return array('ROLE_USER'); + * } + * + * + * @return Role[] The user roles + */ + public function getRoles(); + /** * Removes sensitive data from the user. * diff --git a/core/lib/Thelia/Core/Template/Loop/Feed.php b/core/lib/Thelia/Core/Template/Loop/Feed.php new file mode 100644 index 000000000..2cd1a1649 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Feed.php @@ -0,0 +1,127 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Thelia\Core\Template\Element\BaseLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; + +use Thelia\Type\TypeCollection; +use Thelia\Type; + +/** + * + * @package Thelia\Core\Template\Loop + * + * @author Franck Allimant + */ +class Feed extends BaseLoop +{ + + public $url; + public $limit; + public $timeout; + + public function defineArgs() + { + return new ArgumentCollection( + new Argument( + 'url', + new TypeCollection(new Type\AnyType()) + ), + new Argument( + 'limit', + new TypeCollection( + new Type\IntType() + ), + 3 + ), + new Argument( + 'timeout', + new TypeCollection( + new Type\IntType() + ), + 10 + ) + ); + } + + /** + * + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec() + { + $cachedir = THELIA_ROOT . 'cache/feeds'; + + if (! is_dir($cachedir)) { + if (! mkdir($cachedir)) { + throw new \Exception(sprintf("Failed to create cache directory '%s'", $cachedir)); + } + } + + $feed = new \SimplePie($this->url, THELIA_ROOT . 'cache/feeds'); + + $feed->init(); + + $feed->handle_content_type(); + + $feed->set_timeout($this->timeout); + + $items = $feed->get_items(); + + $limit = min(count($tab), $this->limit); + + $loopResult = new LoopResult(); + + for($idx = 0; $idx < $this->limit; $idx++) { + + $item = $items[$idx]; + + $link = $item->get_permalink(); + + $title = $item->get_title(); + $author = $item->get_author(); + $description = $item->get_description(); + + $date = $item->get_date('d/m/Y'); + + $loopResultRow = new LoopResultRow(); + + $loopResultRow->set("URL", $item->get_permalink()); + $loopResultRow->set("TITLE", $item->get_title()); + $loopResultRow->set("AUTHOR", $item->get_author()); + $loopResultRow->set("DESCRIPTION", $item->get_description()); + $loopResultRow->set("DATE", $item->get_date('d/m/Y')); // FIXME - date format should be an intl parameter + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Admin.php b/core/lib/Thelia/Model/Admin.php index 68b151193..923b31462 100755 --- a/core/lib/Thelia/Model/Admin.php +++ b/core/lib/Thelia/Model/Admin.php @@ -3,7 +3,7 @@ namespace Thelia\Model; use Thelia\Model\om\BaseAdmin; -use Symfony\Component\Security\Core\User\UserInterface; +use Thelia\Core\Security\User\UserInterface; /** * Skeleton subclass for representing a row from the 'admin' table. @@ -36,7 +36,7 @@ class Admin extends BaseAdmin implements UserInterface * {@inheritDoc} */ public function getRoles() { - return array(new Role('USER_CUSTOMER')); + return array(new Role('USER_ADMIN')); } } diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index 1002d8d94..9f296ee06 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -3,8 +3,7 @@ namespace Thelia\Model; use Thelia\Model\om\BaseCustomer; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\Role\Role; +use Thelia\Core\Security\User\UserInterface; /** diff --git a/templates/admin/default/assets/css/admin.less b/templates/admin/default/assets/css/admin.less index a4ff763cd..fb3b8f8b7 100755 --- a/templates/admin/default/assets/css/admin.less +++ b/templates/admin/default/assets/css/admin.less @@ -56,16 +56,64 @@ a { // Bootstrap Adjustements ------------------------------------------------------ -.btn-primary, .row h3 .btn-large, .row-fluid h3 .btn-large, .row-fluid h4 .btn-large { - background: -moz-linear-gradient(center bottom , #E3530B 0%, #F39922 100%) repeat scroll 0 0 #E9730F; - box-shadow: 0 0 2px rgba(250, 250, 250, 0.5) inset, 0 1px 3px rgba(0, 0, 0, 0.2); - color: white; +hr { + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); + border-bottom: 1px solid rgba(250, 250, 250, 0.1); + width: 90%; + margin: 0 auto; + clear: both; + margin-top: 20px; +} + +.btn-primary, .btn-large { + background: #e9730f; + background-image: linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -o-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -moz-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -webkit-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -ms-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0, rgb(227,83,11)), + color-stop(1, rgb(243,153,34)) + ); + box-shadow: inset 0px 0px 2px rgba(250,250,250,0.5), 0px 1px 3px rgba(0,0,0,0.2); + color: white; +} + +.btn-large:hover, .btn-primary:hover { + background: #e9730f; + background-image: linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -o-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -moz-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -webkit-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -ms-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%); + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0, rgb(227,83,11)), + color-stop(1, rgb(243,153,34)) + ); + box-shadow: inset 0px 0px 2px rgba(250,250,250,0.8), 0px 1px 3px rgba(0,0,0,0.2); + color: white; +} + +.modal-footer { + background: none repeat scroll 0 0 transparent; + border: medium none; + box-shadow: none; + color: #7D756A; + margin-bottom: 0; + padding: 35px 15px 15px; + text-align: left; } // -- Brandbar ---------------------------------------------------------------- -/* --- BRAND BAR ---*/ - .loginpage { .brandbar { width: 100%; @@ -73,6 +121,10 @@ a { .hero-unit { background-color: transparent !important; + + h1 { + margin-bottom: 25px; + } } .well { @@ -146,7 +198,33 @@ a { } } +// -- Feed list on home page -------------------------------------------------- +.feed-list { + h2 { + font-size: 24px; + line-height: 120%; + color: #E9730F; + + a { + &:hover { + color: inherit; + text-decoration: none; + } + } + } + + h3 { + margin-bottom: 0; + padding-bottom: 0; + font-size: 90%; + line-height: 100%; + } + + .feed-list-item{ + padding: 10px 20px; + } +} // -- Login form -------------------------------------------------------------- .form-signin { diff --git a/templates/admin/default/includes/footer.inc.html b/templates/admin/default/includes/footer.inc.html index 3d0e58427..5fd1a6b8f 100755 --- a/templates/admin/default/includes/footer.inc.html +++ b/templates/admin/default/includes/footer.inc.html @@ -1,4 +1,16 @@ - {* Include required JS files *} +
+ + + {* Include required JS files *} {javascripts file='../assets/js/jquery.min.js'} diff --git a/templates/admin/default/includes/header.inc.html b/templates/admin/default/includes/header.inc.html index 64cf0605c..712a0a600 100755 --- a/templates/admin/default/includes/header.inc.html +++ b/templates/admin/default/includes/header.inc.html @@ -7,10 +7,6 @@ - {stylesheets file='../assets/css/*' filters='less,cssembed'} - - {/stylesheets} - {stylesheets file='../assets/bootstrap/css/bootstrap.css' filters='cssembed'} {/stylesheets} @@ -19,6 +15,10 @@ {/stylesheets} + {stylesheets file='../assets/css/*' filters='less,cssembed'} + + {/stylesheets} + {* TODO allow modules to include CSS here *} \ No newline at end of file diff --git a/templates/admin/default/login.html b/templates/admin/default/login.html index 20fadb19b..9c64612ac 100755 --- a/templates/admin/default/login.html +++ b/templates/admin/default/login.html @@ -1,16 +1,14 @@ -{$page_title={intl l='Thelia'}} +{$page_title={intl l='Welcome'}} {include file='includes/header.inc.html'}
- {{intl l='abcd'}|capitalize}
- {* - {thelia_module action='index_top'} - *} + + {module_include location='index_top'}

{intl l='Thelia Back Office'}

@@ -31,34 +29,26 @@ {/form_field} - +
-
+ {module_include location='index_middle'} -
- -
-

We DO display loops in back-office !

-
    - {loop type="category" name="catloop1"} -
  • {$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}, children: {$NB_CHILD} - {ifloop rel="inner1"} -
      - {loop type="category" name="inner1" parent="{$ID}"} -
    • Sub cat {$ID} (parent is {$PARENT}): {$TITLE}
    • - {/loop} -
    - {/ifloop} -
  • - {/loop} -
+
+ {loop type="feed" name="thelia_feeds" url="http://thelia.net/Flux-rss.html?id_rubrique=8" limit="3"} +
+

{$DATE}

+

{$TITLE|strip_tags}

+

{$DESCRIPTION|strip_tags|truncate:250:"...":true}

+

{intl l='Lire la suite »'}

+
+ {/loop}
- {* - {thelia_module action='index_bottom'} - *} + + {module_include location='index_bottom'} +
{include file='includes/footer.inc.html'} \ No newline at end of file