Mar 13
Digg
Stumbleupon
Technorati
Delicious

Symfony CMS frameworks comparison (updated)

Unexpectedly we’ve figured out that there are at least 4 big symfony CMS frameworks (honestly until now we’ve heard only about Diem and Sympal). We are going to consider here specifically only CMS frameworks b/c there is also whole bunch of symfony CMS plugins: sfSimpleCMSPlugin, sfDynamicCMSPlugin, sfW3studioCmsPlugin, etc.

Basically symfony CMS framework is not really new framework but it is rather bunch of CMS related plugins on top of symfony framework (they include e.g. plugins to modify content, add comments, generate SEO friendly URLs, other content-related tasks).

In fact each such symfony CMS framework worth separate article but for now we just want to provide some basic overview, so here are ours players:

First of all it’s worth to mention that only SteerCMS is Propel-oriented, other 3 requires Doctrine. Also Diem, Sympal and SteerCMS provides not only actual CMS features but additionally extra functionality like email messaging, caching, commenting, internal search engine, etc. Apostrophe looks pretty young and it still needs more work to become really comparable to other 3 CMS frameworks (it still can be used as good light weighted alternative which you can embed into your existing project).

So we prepared this quick comparison matrix and planning to keep extending it as soon as we will figure out anything else we missed here. It’s also very welcome to put in comments anything which you think worth to add to this matrix:

Diem Sympal SteerCMS Apostrophe
ORM Doctrine Doctrine Propel Doctrine
Internal Search Yes Yes Yes No
Slots/Inline editing Yes Yes No Yes
Blog Yes Yes Yes No
Commenting Yes Yes Yes No
Menu Yes Yes No No
Breadcrumb Yes Yes No No
Extra Cache Yes Yes Yes No
Versioning Yes No No Yes
Command Line Yes Yes No No
Multi sites management No Yes No No

By the way, when we create this matrix we were inspired by another one provided on Sympal’s site which compares Sympal to other CMSs (e.g. Joomla and Typo3).

We are also sorry in advance if we made mistake regarding any feature of provided CMS, we are promise to fix it it happened.

To Symfonians!

* updated comparison matrix (03/14/2010)


Author: admin
Mar 07
Digg
Stumbleupon
Technorati
Delicious

Job Queue in Symfony

The project is growing up like Alice after drinking poison. You expected that it should handle only a few requests and eventually it has to serve many more requests at same moment. Or another scenario – you need to run at once a few tasks and make sure they all are going to be completed and you want system notifies you about their progress. That’s where job queue comes to help you. In specific jobs queue is something we have to use in our symfony-driven RSS reader – we want to make sure parsing of each feed source can be done independently and in time.

It seems there are a few solutions for this problem if you use symfony:

1. Symfony 1.0 plugin sfJobQueue. So you’d have to rewrite it a bit to make it working with newer symfony versions (especially if you don’t plan to use Propel). Plugin has quite basic functionality but advantage of its using – built-in backend modules to manage jobs progress (so good for quick solutions).

2. Zend provides a few ways to solve queuing problem. Zend_Queue is unified class which can use a different messaging platforms like Amazon SQS, Zend Platform Queue, etc. In order to use it with symfony you’d have install Zend bridge plugin or add classes directly into lib folder. Here is available simple sample of its using for mass sending emails with MSSQL

Another approach from Zend is Job Queue for Zend Platform which provides really powerful bunch of queue features, just have a look on this sample:

$job_queue = new ZendAPI_Queue('gollum.zend.office');
$job_queue->login('1234');
$job = $job_queue->getJob(8);
$job->setRecurrenceData(3600, time()+3600*24);
$job->setJobDependency(16);  // This job will perform only after job 16 was successfully executed
$job_queue->updateJob($job);   // The job queue will update job #8 with the new properties of the given Job object

Obviously you’d have install Zend Platform which makes this solution less simple than others (I’ve never used it so probably it does not really complicated). For interested I’d also recommend to have a look on this analytic article: Zend Job Queue.

3. Gearman is scalable queue solution or like they describe their-self:

a system to farm out work to other machines, dispatching function calls to machines that are better suited to do work, to do work in parallel, to load balance lots of function calls, or to call functions between languages.

So in some sense this solution is the most perspective as you can be sure that you’ll be able to handle as much requests as you need. You’d have to use this PHP API if you go with gearman.

There are a few notes regarding it though. So firstly when you install gearman daemon you’ll most probably will have to get libevent lib, here are the installation steps:

wget http://launchpad.net/gearmand/trunk/0.12/+download/gearmand-0.12.tar.gz
tar zxf gearmand-0.12.tar.gz
yum install libevent-devel
./configure
make
make install

Also current php extension 0.6.0 can’t be compiled properly (it seems to be working fine only under PHP 5.3) so you’d have to go either with PEAR package (which is still alpha though):

pear install Net_Gearman-0.2.3

or install previous version of php extension to compile it properly on servers with php < 5.3.
On everything else we refer you to gearman PHP API docs in order to start using it.

4. And eventually if you think that none of provided solutions is suitable you can always write own one using this article which provides general ideas on job queue implementation: http://stut.net/2009/05/29/php-job-queue/

So there is quite big amount of approaches to get queuing problem solved. We hope you’ll drop us comment if you know any other approach. Personally I would vote for gearman as this looks like pretty promising solution so developing infrastructure around it would be good investment.

Finally here are some related subjects which are kind of out of scope of this article but still can be interesting for you:

Asynchronous work in backend:
http://groups.google.com/group/symfony-users/browse_thread/thread/afdda6e5f92d8f21?pli=1

symfony queue requests sent by a single browser session:
http://forum.symfony-project.org/index.php/m/77832/


Author: admin
Feb 27
Digg
Stumbleupon
Technorati
Delicious

Fabien Potencier – the father and the mother of Symfony framework

This post is dedicated to Fabien Potencier – the father and the mother of Symfony framework.
Only biography we’ve found about him is also know as so-called “little history of symfony”:

1994 to 1997 Fabien went to the Ecole National Supérieure des Mines de Nancy.
1997 to 1998 Added master entrepreneur at HEC School of Management to his curriculum vitae.

In June 1998 Fabien and Grégory Pascal created there own little company called Sensio in France, an office was created in France, later in 2008 in Canada and the United States. In October 2005 the Symfony framework was licensed and two years later the first version was launched.

His personal site is http://fabien.potencier.org/

You can find his thoughts, people he gets inspiration from, connections on these social sites:

http://twitter.com/fabpot
http://twitter.com/fabpot/following
http://www.linkedin.com/in/fabienpotencier

Unfortunately, that’s all we were able to figure out about him. So if you know something more about his biography or would like to share some personal information about him which can be interesting – please use our comment.

You can have a look on him in action :) on Symfony 2010 conference during his presentation about Symfony 2 (he looks like funny and smart person):

Also don’t miss his page with presentations as he is actively participate on conferences and there are lot of interesting slides from him:

http://www.slideshare.net/fabpot/presentations

Here are just some of them:










Author: admin
Feb 22
Digg
Stumbleupon
Technorati
Delicious

Symfony TV

Hi everybody,

We’ve decided to introduce Symfony TV area on our site. So starting from this post we are going to locate there symfony related videos. For now these are videos from Symfony Live 2010 conference. On our opinion it’s important addon to presentation slides which we’ve provided in previous posts. You can see the open discussion with symfony core development team and “symfony in cloud” presentation. Once we’ll find more videos from the conference we publish them as well. So if you have filmed something from this conference.. actually if you have filmed anything related with symfony and would like to share we’ll be happy to publish it as well. So watch and enjoy.

Symfony Live 2010 Conference: Core Dev Team Q&A

Deploying symfony application to the cloud by Kris Wallsmith on Symfony Live 2010 Conference. If you liked presentation slides about using symfony in cloud environment which we provided in previous post – you must watch this video with presentation’s author detailed comments.


Author: admin
Feb 19
Digg
Stumbleupon
Technorati
Delicious

Symfony Live Presentation. Part 2

Here goes another round of presentations taken from Symfony Live 2010 Day 2. I’ve put them in order of importance for me and left some comments. So lets start..

Symfony 2.0 revealed by Fabien Potencier.

It’s surely the most important presentation on Symfony conference. Symfony’s father Fabien Potencier presents next major symfony release and uncover important details about it. From what I’ve seen Symfony 2 is becoming framework standard in php world. And along with symfony there is also bundled other great php libraries (they are optional for using but recommended) like Swift Mailer, Doctrine ORM, etc. One thing I’m concerned about – I did not see anything about Twig. So I’m going to view all the slides from conference once more but I really did not see any single mention about the template engine http://www.twig-project.org/ introduced by Fabien Potencier a while ago.

Symfony in the Cloud from Kris Wallsmith.

This presentation is not only for the ones who is interested in cloud servers. In general it describes in depth how to configure and use database layer in symfony. So if you use master/slave DB approach it’s worth to look into it (presentation contains lot of code samples). Author consider how he used it for his http://www.nebul.us project.

Debugging and Profiling Symfony Apps by Alvaro Videla

It’s another one hot presentation – how to debug, log and visualize this data for big projects. Author goes through available symfony classes which can be used for these purposes and external tools like XHProf and Tsung, Graphite. Surely, if you are not familiar with this stuff yet this is going to be useful for you even if you are working on small project.

OkAPI meet symfony, symfony meet OkAPI by Lucas

OkAPI is definitely something new to me. It looks like php framework which decided to use symfony components instead of writing own ones. So it can be interesting if you are still looking for “better” framework.

Using Zend Framework with Symfony from Matthew Weier O’Phinney

I’ve never thought that Zend Framework and Symfony are really competing. And this presentation proves that. It shows the way how to use the best Zend classes in Symfony, e.g. Zend_Gdata or Zend_Service_Amazon – they don’t have quality analogue in symfony plugins – therefore it makes sense to build Zend classes into symfony project. The presentation provides also other points for interactions between these 2 frameworks so I believe it’ll be interesting for both symfony and zend developers.

Building A Platform From Open Source At Yahoo by Dustin Whittle

I guess this presentation did not bring something really new. In general it’s the same as was already introduced on Symfony Live 2009. So if you did not hear about ysymfony (Yahoo Symfony) yet – go and watch it. There is mentioned usage of YQL so if you did not try it yet – good chance to look how it works.

There were also non-symfony related presentations which obviously worth to mention as they are interesting.

PHP Performance

Git 101 Presentation

So guys, Symfony 2010 Live conference is over and next year will go under sign of Symfony 2. Hopefully since that release this framework will be evolving bit slower (or rather smoother) as at this point it’s still complicated to decided which version to use (keeping in mind that it should be upgraded soon).


Author: admin
Feb 17
Digg
Stumbleupon
Technorati
Delicious

Symfony Live presentations

These are presentations from Symfony 2010 Day 1 (I’d name it “Doctrine” day).

Doctrine 2 – Not The Same Old Php Orm Very good introduction to next doctrine version (will be supported for only php 5.3 though, rewritten and improved Doctrine Query Language). I recommend to watch these slides before make decision about using ORM for next project.

Using Doctrine Migrations explains in depth how to use Doctrine migration tools. Very cool way to fully automate the migration and reduce fails percentage. I have not looked into that mechanism yet but looks pretty promising.

Here is also bonus presentation which was not added on official Symfony blog yet:

Using symfony events to create clean class interfaces

So next symfony conference day is coming and we are expecting even more interesting slides and news.

Symfonians united!


Author: admin
Jan 19
Digg
Stumbleupon
Technorati
Delicious

symfony question from Javi

little children portraits taken in the studio ...

We’ve recently got the following question from newbie and thought someone may have a quick response for this to help the guy :-)

Hi,

these are my steps first and then my question:

I have added this model and this fixture to my app :

Birthday:
  columns:
    testdate: date
 
Birthday:
  example:
    testdate: "2009-1-1"

I have generated the Birthday module. Then I’ve generated the filter
class (BirthdayFormFilter.class.php) and I have created a form filter
object in executeIndex():

$this->filter = new BirthdayFormFilter();

After that, i’ve added this lines to the index template:

<?php echo form_tag('birthday/filtrar') ?>
<?php echo $filter; ?>
<div><?php echo submit_tag('Filter') ?></div>
</form>

When i click the ‘Filter’ button i get this error:

500 | Internal Server Error | Doctrine_Connection_Mysql_Exception
SQLSTATE[HY093]: Invalid parameter number: number of bound variables
does not match number of tokens
stack trace
 
    * at ()
      in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/Doctrine/Connection.php line 1086 ...
            1083.
            1084.         $name = 'Doctrine_Connection_' . $this-
 
&gt;driverName . '_Exception';
 
            1085.
            1086.         $exc  = new $name($e-&gt;getMessage(), (int)
$e-
 
&gt;getCode());
 
            1087.         if ( ! isset($e-&gt;errorInfo) || ! is_array
($e-
 
&gt;errorInfo)) {
 
            1088.             $e-&gt;errorInfo = array(null, null, null,
null);
            1089.         }
    * at Doctrine_Connection-&gt;rethrowException(object('PDOException'),
object('Doctrine_Connection_Statement'))
      in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/Doctrine/Connection/Statement.php line 253 ...
             250.         } catch (Doctrine_Adapter_Exception $e) {
             251.         }
             252.
             253.         $this-&gt;_conn-&gt;rethrowException($e, $this);
             254.
             255.         return false;
             256.     }
    * at Doctrine_Connection_Statement-&gt;execute(array('month' =&gt; '1',
'day' =&gt; '2', 'year' =&gt; '2014'))
      in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/Doctrine/Connection.php line 1014 ...
            1011.         try {
            1012.             if ( ! empty($params)) {
            1013.                 $stmt = $this-&gt;prepare($query);
            1014.                 $stmt-&gt;execute($params);
            1015.
            1016.                 return $stmt;
            1017.             } else {
    * at Doctrine_Connection-&gt;execute('SELECT b.id AS b__id, b.testdate AS
b__testdate FROM birthday b WHERE b.testdate &gt;= ? AND b.testdate &lt;= ?', array('month'
=&gt; '1', 'day' =&gt; '2', 'year' =&gt; '2014'))
      in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/Doctrine/Query/Abstract.php line 992 ...
             989.             return $this-&gt;_conn-&gt;exec($query,
$params);
             990.         }
             991.
             992.         $stmt = $this-&gt;_conn-&gt;execute($query,
$params);
             993.         return $stmt;
             994.     }
 995.
    * at Doctrine_Query_Abstract-&gt;_execute(array('month' =&gt; '1', 'day'
=&gt; '2', 'year' =&gt; '2014'))
      in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/Doctrine/Query/Abstract.php line 1036 ...
            1033.                 $result = $this-
 
&gt;_constructQueryFromCache($cached);
 
            1034.             }
            1035.         } else {
            1036.             $stmt = $this-&gt;_execute($params);
            1037.
            1038.             if (is_integer($stmt)) {
            1039.                 $result = $stmt;
    * at Doctrine_Query_Abstract-&gt;execute()
      in SF_ROOT_DIR/apps/frontend/modules/birthday/actions/
actions.class.php li

I know the error is produced because this:

Doctrine_Connection->execute('SELECT b.id AS b__id, b.testdate AS
b__testdate FROM birthday b WHERE b.testdate >= ? AND b.testdate
<= ?', array('month' => '1', 'day' => '2', 'year' => '2014'))

But if my steps are correct, why symfony is generating this useless clause? What am i doing wrong?Regards
Javi


Author: admin
Dec 20
Digg
Stumbleupon
Technorati
Delicious

Using Symfony and Sphinx

In continue to our previous post RSS Reader Symfony 1.4 Tutorial we’ve decided to add to our RSS Reader search feature. One which may fits our purposes is Sphinx.

So here are a few simple steps to prepare Sphinx for using

1. Get the latest stable release from here and untar it somewhere on your server
2. ./configure
3. make
4. make install
5. cp /usr/local/etc/sphinx.conf.dist /usr/local/etc/sphinx.conf (folder location may very slightly)
6. edit sphinx configuration by adding your DB details and search query:

vi /usr/local/etc/sphinx.conf

source src1
{
        type                                    = mysql
 
        sql_host                                = localhost
        sql_user                                = db_username
        sql_pass                                = db_password
        sql_db                                  = db_name
        sql_port                                = 3306  # optional, default is 3306
 
        sql_query                               = \
                SELECT id, source_id, created_at, name, description \
                FROM feed
 
        sql_attr_uint                   = source_id
        sql_attr_timestamp              = created_at
 
        sql_query_info                  = SELECT * FROM feed WHERE id=$id
}
 
 
index test1
{
        source                          = src1
        path                            = /var/data/test1
        docinfo                         = extern
        charset_type                    = sbcs
}
 
 
indexer
{
        mem_limit                               = 32M
}
 
 
searchd
{
        port                            = 9312
        log                             = /var/log/searchd.log
        query_log                       = /var/log/query.log
        read_timeout                    = 5
        max_children                    = 30
        pid_file                        = /var/log/searchd.pid
        max_matches                     = 1000
        seamless_rotate                 = 1
        preopen_indexes                 = 0
        unlink_old                      = 1
}

7. start indexing your database (the most probably you’ll need to run it periodically through cron):

/usr/local/bin/indexer test1

8. run actual Sphinx search daemon:

/usr/local/bin/searchd

When deamon is running there can be a problem with re-indexing:

using config file ‘/usr/local/etc/sphinx.conf’…
indexing index ‘test1′…
FATAL: failed to lock /var/data/test1.spl: Resource temporarily unavailable, will not index. Try –rotate option.

so you may need to stop it firstly (so kill search deamon, do indexing and start it again).

Thanks to ServerGroove symfony hosting we are able to setup it and investigate how it would work on their virtual server.

Now lets install sfSphinxPlugin to RSS Reader project and add some basic search code:

So first of all lets add search action to our actions.class.php:

public function executeSearch()
{
  $this->query = $this->getRequestParameter('q');
  $this->page = $this->getRequestParameter('p', 1);
  $options = array(
    'limit'   => 10,
    'offset'  => ($this->page - 1) * 10,
    'weights' => array(100, 1),
    'sort'    => sfSphinxClient::SPH_SORT_EXTENDED,
    'sortby'  => '@weight DESC',
    'port' => 9312
  );
  if (!empty($this->query))
  {
    $this->sphinx = new sfSphinxClient($options);
    $res = $this->sphinx->Query($this->query, 'test1');
    $this->pager = new sfSphinxDoctrinePager('Feed', $options['limit'], $this->sphinx);
    $this->pager->setPage($this->page);
    $this->pager->init();
    $this->logMessage('Sphinx search "' . $this->query . '" [' . $res['time'] .
                      's] found ' . $this->pager->getNbResults() . ' matches');
  }
}

So here worth to mention at least 2 important things:

We had to use:

1. parameter ‘port’ => 9312 to specify on which port Sphinx daemon is running.
2. sfSphinxDoctrinePager pager class which is luckily available in Sphinx plugin.

So all other here is pretty clear, just lets mention that we use index named test1 and we apply pager for table feed (mapped object Feed) which contains parsed RSS items.

Now lets create template searchSuccess.php which will show all found items and highlight searched keywords in them:

 
<?php use_helper('Search') ?>
 
<?php if (empty($query)): ?>
<?php return ?>
<?php endif ?>
 
<?php $res = $pager->getResults() ?>
<?php if (empty($res)): ?>
No result matches your query
<?php else: ?>
<?php if ($sphinx->getLastWarning()): ?>
Warning: <?php echo $sphinx->getLastWarning() ?>
<?php endif ?>
<ol start="<?php echo $pager->getFirstIndice() ?>">
<?php foreach ($res as $item): ?>
  <li>
    <h3><?php echo link_to(highlight_search_result($item->getName(), $query), $item->getLink(), 'target="_blank"') ?></h3>
    <?php echo html_entity_decode(highlight_search_result($item->getDescription(), $query)) ?>
  </li>
<?php endforeach ?>
</ol>
<?php endif ?>
 
<?php if ($pager->haveToPaginate()): ?>
  <?php echo link_to('&laquo;', '/home/search?q=' . $query . '&p=' . $pager->getFirstPage()) ?>
  <?php echo link_to('&lt;', '/home/search?q=' . $query . '&p=' . $pager->getPreviousPage()) ?>
  <?php $links = $pager->getLinks()?>
  <?php foreach ($links as $page): ?>
    <?php echo ($page == $pager->getPage()) ? $page : link_to($page, '/home/search?q=' . $query . '&p=' . $page) ?>
  <?php endforeach ?>
  <?php echo link_to('&gt;', '/home/search?q=' . $query . '&p=' . $pager->getNextPage()) ?>
  <?php echo link_to('&raquo;', '/home/search?q=' . $query . '&p=' . $pager->getLastPage()) ?>
<?php endif ?>

So for now we have ready RSS reader script with ability to search through the parsed feeds.
Next step we are going to implement some basic user interface which would allow for users to add own feed sources. This will be presented in our next article and after that we are going to make this project available for public collaborating at GitHub and run live version at ServerGroove symfony hosting.

Happy Christmas!


Author: admin
Dec 12
Digg
Stumbleupon
Technorati
Delicious

RSS reader symfony 1.4 tutorial

3D render of an RSS symbol

Thanks to symfony hosting ServerGroove we’ve got eventually a chance to implement our old idea about super-duper RSS reader which would work as web service for which we can add multiple features on demand (yes there is still no good enough web RSS reader for us).

So lets see how to write RSS reader on symfony in 15 minutes (we’ve already had some basics written for symfony 1.2 with propel so it was good chance to figured out doctrine differences). Here goes main steps we did:

  • 1. symfony generate:project rssreader
  • 2. symfony generate:app frontend
  • 3. create DB called rssreader
  • 4. create doctrine/schema.yml
  • 5. symfony doctrine:build –all –no-confirmation –and-load
  • 6. symfony plugin:install sfFeed2Plugin
  • 7. symfony plugin:install sfWebBrowser

For schema file we propose to use this one:

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
35
36
37
category:
  actAs: { Timestampable: ~ }
  columns:
    name:         { type: string(255) }
    description:  { type: string(4000) }
    parent_id:    { type: integer, default: 0 }
 
source:
  actAs: { Timestampable: ~ }
  columns:
    category_id:  { type: integer, notnull: true }
    name:         { type: string(255) }
    description:  { type: string(4000) }
    link:         { type: string(4000) }
    author:       { type: string(255) }
    pub_date:     { type: varchar(100) }
    generator:    { type: varchar(100) }
    language:     { type: varchar(100) }
    response:     { type: string(4000) }
    notes:        { type: string(4000) }
    is_private:   { type: boolean }
  relations:
    category: { onDelete: CASCADE, local: category_id, foreign: id, foreignAlias: Sources }
 
feed:
  actAs: { Timestampable: ~ }
  columns:
    source_id:    { type: integer, notnull: true }
    name:         { type: string(255) }
    link:         { type: string(4000) }
    summary:      { type: string(4000) }
    description:  { type: string(4000) }
    author:       { type: string(255) }
    response:     { type: string(4000) }
    notes:        { type: string(4000) }
  relations:
    source: { onDelete: CASCADE, local: source_id, foreign: id, foreignAlias: Feeds }

So we have category / feed source and actual feeds tables.
At this point worth to mention that we had to convert Propel schema to Doctrine, e.g. replace type names:

varchar(255) => string(255)
longvarchar => string(4000)

Also when we tried to install sfFeed2 and sfWebBrowser plugins it said:


Unable to get plugin licence information for plugin "sfFeed2Plugin": Unknown package: "sfFeed2Plugin" (Debug: File http://plugins.symfony-project.org:80/REST/sffeed2plugin/info.xml not valid (received: HTTP/1.0 404 No version available with the installed symfony version)) (use --force-license to force installation)

We did not spend time on figuring out the reason of it (as our goal is to have rss reader in 15 minutes) so we simply downloaded plugins as tgz and unarchived them into lib directory.

Now important part of project is actual rss reader script. It’s pretty straightforward though, we put it into “batch” directory so we can execute it as cron task:

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
 
  require_once(dirname(__FILE__) . '/../config/ProjectConfiguration.class.php');
  $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
  sfContext::createInstance($configuration);
 
  $databaseManager = new sfDatabaseManager($configuration);
  $databaseManager->loadConfiguration();
 
  $sources = Doctrine::getTable('Source')->createQuery('a')->execute();
 
  foreach ($sources as $source) {
 
    $feeds = sfFeedPeer::createFromWeb($source->getLink());
    foreach ($feeds->getItems() as $feed) {
 
      $q = Doctrine_Query::create()
        ->select('COUNT(id) as cnt')
          ->from('feed')
          ->where('link = ?', $feed->getLink());
      $results = $q->execute();
      if ($results[0]['cnt']) continue;
 
      $d = new Feed();
      $d->setSourceId($source->getId());
      $d->setName($feed->getTitle());
      $d->setLink($feed->getLink());
      $d->setDescription($feed->getDescription());
      $d->save();
 
    }
 
  }

So it just goes through sources table and retrieve new unique feeds. Lets run it daily.
Lets also skip backend part for now (of course we could quickly make it with backend generator but most probably you would like to import your favourite feed sources as CSV or so). So you only have to add somehow rows into source table with proper feed link (“link” column is for that)

To read feeds, lets just create home module with actions.class.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
class homeActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this->sources = Doctrine::getTable('Source')
      ->createQuery('a')
      ->execute();
 
    $this->feeds = Doctrine::getTable('Feed')
      ->createQuery('a')
      ->execute();
  }
 
}

And indexSuccess.php template:

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
<h1>Recently Added RSS Feeds</h1>
 
<table width="100%">
  <tbody>
    <?php foreach ($feeds as $feed): ?>
    <tr>
      <td><?php echo link_to($feed->getName(), $feed->getLink(), "target='_blank' id='feed{$feed->getId()}'") ?></td>
      <td width="1%"><?php echo link_to(" ", $feed->getSource()->getLink(), 'target="_blank" class="feed"') ?></td>
    </tr>
   <?php endforeach; ?>
  </tbody>
</table>
 
 
<h1>Recently Added RSS Sources</h1>
 
<table width="100%">
  <tbody>
    <?php foreach ($sources as $source): ?>
    <tr>
      <td><?php echo $source->getCategory() ?></td>
      <td><?php echo link_to($source->getName(), $source->getLink()) ?></td>
      <td><?php echo $source->getAuthor() ?></td>
      <td><?php echo $source->getPubDate() ?></td>
      <td width="1%"><?php echo link_to(" ", $source->getLink(), 'target="_blank" class="feed"') ?></td>
    </tr>
    <?php endforeach; ?>
  </tbody>
</table>

Don’t forget to change config/routing.yml so it has:

1
2
3
homepage:
  url:   /
  param: { module: home, action: index }

That’s all. Cookie is ready to eat. Run feeds fetching script from batch and make sure you see feeds on homepage of your project.

Very soon we are going to deploy this project on our ServerGroove account and you can give it a try.

Also we are planning to keep it as open-source ongoing project.

By the way, how do you think what is the best way to provide ability for other developers to create own plugins for it? Which API may fit this project?


Author: admin
Dec 05
Digg
Stumbleupon
Technorati
Delicious

upgrade to symfony 1.4

Was trying to upgrade to symfony 1.4 from symfony 1.2 without luck. After a few attempts to upgrade with usual command “pear upgrade symfony/symfony-1.4.0″ and “pear upgrade symfony” I decided today is wrong day for upgrade it always returned:

File http://pear.symfony-project.com:80/Chiara_PEAR_Server_REST/p/packages.xml not valid (received: HTTP/1.1 404 Not Found

So I thought there must be something with pear server. Later I remembered that read Fabien’s article about new pear server Pirum. After that I digged into PEAR syntax and figured out useful task “channel update”, so eventually in order to upgrade I had to run:

pear channel-update pear.symfony-project.com
pear upgrade symfony/symfony-1.4.0

Whoo-hoo! Now am configuring Diem 5.0 Alpha 5 for testing. It looks fabulous by the way..


Author: admin