Added Feed loop to retreive feeds using SimplePie

This commit is contained in:
franck
2013-07-06 10:18:19 +02:00
parent 962afc6d14
commit 6e5b259d44
11 changed files with 339 additions and 42 deletions

View File

@@ -6,6 +6,7 @@
<loops>
<loop class="Thelia\Core\Template\Loop\Category" name="category"/>
<loop class="Thelia\Core\Template\Loop\Feed" name="feed"/>
</loops>

View File

@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <fabien@symfony.com>
*/
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;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <fabien@symfony.com>
*/
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();
}

View File

@@ -30,6 +30,20 @@ interface UserInterface {
*/
public function getAlgo();
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* @return Role[] The user roles
*/
public function getRoles();
/**
* Removes sensitive data from the user.
*

View File

@@ -0,0 +1,127 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
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 <franck@cqfdev.fr>
*/
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;
}
}

View File

@@ -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'));
}
}

View File

@@ -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;
/**

View File

@@ -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 {

View File

@@ -1,4 +1,16 @@
{* Include required JS files *}
<hr />
<footer class="modal-footer">
<div class="container">
<p>{intl l='&copy; Thelia 2012'}
- <a href="http://www.openstudio.fr/" target="_blank">{intl l='Édité par OpenStudio'}</a>
- <a href="http://forum.thelia.net/" target="_blank">{intl l='Forum Thelia'}</a>
- <a href="http://contrib.thelia.net/" target="_blank">{intl l='Contributions Thelia'}</a>
<span class="pull-right">{intl l='interface par <a target="_blank" href="http://www.steaw-webdesign.com/">Steaw-Webdesign</a>'}</span>
</p>
</div>
</footer>
{* Include required JS files *}
{javascripts file='../assets/js/jquery.min.js'}
<link rel="stylesheet" href="{$asset_url}" target="screen">

View File

@@ -7,10 +7,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{stylesheets file='../assets/css/*' filters='less,cssembed'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{stylesheets file='../assets/bootstrap/css/bootstrap.css' filters='cssembed'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
@@ -19,6 +15,10 @@
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{stylesheets file='../assets/css/*' filters='less,cssembed'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{* TODO allow modules to include CSS here *}
</head>
<body>

View File

@@ -1,16 +1,14 @@
{$page_title={intl l='Thelia'}}
{$page_title={intl l='Welcome'}}
{include file='includes/header.inc.html'}
<div class="loginpage">
{{intl l='abcd'}|capitalize}
<div class="brandbar container">
<a class="brand" href="index.php">{images file='assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}</a>
</div>
<div id="wrapper" class="container">
{*
{thelia_module action='index_top'}
*}
{module_include location='index_top'}
<div class="hero-unit">
<h1>{intl l='Thelia Back Office'}</h1>
@@ -31,34 +29,26 @@
<label class="checkbox"> <input type="checkbox" name="remember" value="yes"> {intl l='Remember me'}</label>
{/form_field}
<button type="submit" class="btn btn-primary">{intl l='Login'} <i class="icon-play"></i></button>
<div class="pull-right"><button type="submit" class="btn btn-primary">{intl l='Login'} <i class="icon-play icon-white"></i></button></div>
</form>
</div>
<div class="row-fluid">
{module_include location='index_middle'}
</div>
<div>
<h2>We DO display loops in back-office !</h2>
<ul>
{loop type="category" name="catloop1"}
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}, children: {$NB_CHILD}
{ifloop rel="inner1"}
<ul>
{loop type="category" name="inner1" parent="{$ID}"}
<li>Sub cat {$ID} (parent is {$PARENT}): {$TITLE}</li>
{/loop}
</ul>
{/ifloop}
</li>
{/loop}
</ul>
<div class="row-fluid feed-list">
{loop type="feed" name="thelia_feeds" url="http://thelia.net/Flux-rss.html?id_rubrique=8" limit="3"}
<div class="span4 feed-list-item">
<h3>{$DATE}</h3>
<h2><a href="#URL" target="_blank" title="{intl l='Lire la suite'}">{$TITLE|strip_tags}</a></h2>
<p>{$DESCRIPTION|strip_tags|truncate:250:"...":true}</p>
<p><a class="btn" href="#URL" target="_blank">{intl l='Lire la suite »'}</a></p>
</div>
{/loop}
</div>
</div>
{*
{thelia_module action='index_bottom'}
*}
{module_include location='index_bottom'}
</div>
{include file='includes/footer.inc.html'}