Archive | symfony RSS for this section

Posting to Twitter using PHP

I haven’t had much to post about lately so I’ll just share a simple bit of code to update your Twitter status and shrink any urls in the post. Maybe someone will find it useful.

I downloaded a small Twitter class from here but the download link doesnt seem to work anymore so leave a comment if you want the script. There are also loads of other free PHP twitter scripts so just do a search.

The site I was building just needed to post the name and url of an item to twitter. This bit of code will first shrink the URL using TinyURL’s api, then post to twitter.

Note: I wrote this for a Symfony 1.0 project. I haven’t used sfWebBrowser in 1.2 so im not sure if it will work, but you could replace it with cURL or even just file_get_contents()

$curTwitter = new twitter("USERNAME", "PASSWORD");
 
$b = new sfWebBrowser();
$my_url = 'http://www.YOUR-DOMAIN.com/';
 
$b->get('http://tinyurl.com/api-create.php?url='.$my_url);
$tinyurl = $b->getResponseText();
 
$curTwitter->setStatus($this->getRequestParameter('name'). ' ' . $tinyurl );


Update: Forgot to mention, sfWebBrowser is a plugin for anyone who didnt know.


Follow me on twitter

multiple TinyMCE editors with sfWidgetFormTextareaTinyMCE

I noticed the other day that when using the sfWidgetFormTextareaTinyMCE widget which is part of the sfFormExtraPlugin plugin, it wouldnt display more than 1 editor on a page. After looking at the class and comparing the javascript to the javascript that was generated by the old textarea_tag() function I noticed a few differences.

To fix this, copy \plugins\sfFormExtraPlugin\lib\widget\sfWidgetFormTextareaTinyMCE.class.php to \lib\widgets\ and make the following change to the javascript:

<script type="text/javascript">
  tinyMCE.init({
    mode:                              "exact",
    theme:                             "%s",
    elements:                          "%s",
    %s
    %s
    theme_advanced_toolbar_location:   "top",
    theme_advanced_toolbar_align:      "left",
    theme_advanced_statusbar_location: "bottom",
    theme_advanced_resizing:           true
    %s
  });
</script>

You will probably have to create the \lib\widget directory. Dont forget to clear your cache.

Running multiple Symfony versions on the same server

If you want to start learning symfony 1.2 but only have 1 server, this guide will show you how to run multple versions.

http://symfonynerds.com/blog/?p=123

If you are running windows, this forum post explains an alternative method to using symlinks.

Filtering sfLucene Results

Often I need to add the ability to filter sfLucenes search results by certain criteria (price, category, etc). While im sure that it can probably be done using the plugins configuration files, its quite simple to just write your own simple interface.

$lucene = sfLucene::getInstance('ProductIndex', 'en');
$query = new sfLuceneCriteria($lucene);
$query->addSane($this->getRequestParameter('q'));
$results = $lucene->friendlyFind($query);
 
foreach ($results as $result)
{
    $matched_products[] = $result->getId();
}

The $matched_products array now contains all the product ID’s that were found. So now I ran a query applying the nessecary filters and use the IN() operator to limit it to the products found by Lucene. In the example I havent applied any of my filters, I am only checking that the product is active.

$c = new Criteria();
$c->add(ProductsPeer::ID, $matched_products, Criteria::IN);
$c->add(ProductsPeer::ACTIVE, 1);
$this->products = ProductsPeer::doSelect($c);

The only problem I ran into is that results of this query won’t be in the same order as Lucenes results, by default it will order it by the ID’s. After some investigation I discovered the mysql CASE statement.

if (count($matched_products) > 0)
{
 
  $order_by = ' case ('.ProductsPeer::ID.')';
  $count = 1;
  foreach ($matched_products AS $id)
  {
        $order_by .= ' when '.$id.' then '.$count.' ';
        $count++;
  }
  $order_by .= ' end ';
 
  $c->addAscendingOrderByColumn( $order_by , Criteria::CUSTOM);
 
}

Apply the above code to your query and the results will be returned in the same order as $matched_products.

Jobeet – New Symfony 1.2 tutorial

Jobeet

Symfony have started a new tutorial for 1.2 similar to the Askeet tutorial for Symfony 1.0.

Jobeet is a set of 24 short tutorials, 1 being released every day between December 1st  and Christmas. Each tutorial is meant to only take 1 hour to complete.

This is something I definitely need to look into when I have some time off later this month.

View the tutorial

Symfony 1.20 released

Symfony 1.20 was officially released yesterday.

Read about it here

Guess I have some learning to do when I eventually get time. Especially considering I skipped version 1.1

Repopulating forms

I while ago I was stuck for quite a while trying to figure out why my form wasn’t being repopulated after an error occured.

What I forgot was that if there is more than 1 form on the page you must specify the forms name in the validation file.

fillin:
  enabled: true
  param:
    name: my_form

Even though this is well documented it can be easily missed. I found the most common situation is when every page has a search form at the top which you forget about.

save the ouput of an action

I needed to create a css file genertor which allowed the user to style their own profile. After browsing around for a while some one on the forums told me about getPresentationFor().

//manually set the request parameter of the skin that I want to generate
$ph = $this->getRequest()-&gt;getParameterHolder();
$ph->set('id', $skin-&gt;getId());
$ph-&gt;set('preview', 'true');
 
$this->css_contents = $this->getPresentationFor('skins','css'); //this calls the css action in the skins module

you can then save $this->css_contents to a file or the database.

quickly get the absolute website url

Often you need to get the absolute URL of the site to insert a link into an email or something similar.

This becomes annoying in a large environment where there are multiple copies of the site (dev, staging etc) all with different urls. While you could easily create it using the $_SERVER array, or store the full url in the app.yml (meaning you have to change it for each copy of the site), this method is much easier.

eg to generate the link to forgot password page you would do:

<?php $url = url_for("@forgot_pass", true); ?>

That second parameter “true” tells it return the absolute path. Whats nice is that it includes the controller aswell (eg frontend_dev.php), which makes testing easier.

Remember, you’ll need to load the Url helper to use this function. From the action or model it can be done like this:

sfLoader::loadHelpers(array('Url'));

fromArray()

I recently had to import a property csv file where each record contained over 70 fields!

Manually saving each column would have taken forever so I browsed the Base class and found the function fromArray().

All I had to was make sure my database columns were in the same order as the csv file and rest was pretty simple.

$property = new Properties();
 
$fields = PropertiesPeer::getFieldNames(); //retrieve the tables field names
 
$i = 0;
foreach ($fields AS $field)
{
$new_fields[$field] = $csv_data[$i];
$i++;
}
 
$property->fromArray($new_fields);
$property->save();