Tweeting from PHP Comments Off

Thanks to fabien Potencier for this hint :

Twitter is everywhere nowadays. Odds are eventually you will want to tweet from PHP. No need to use one of the numerous PHP Twitter libraries, as tweeting is as simple as using the PHP built-in file_get_contents() function:
function tweet($message, $username, $password)
{
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => sprintf("Authorization: Basic %s\r\n", base64_encode($username.':'.$password)).
"Content-type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query(array('status' => $message)),
'timeout' => 5,
),
));
$ret = file_get_contents('http://twitter.com/statuses/update.xml', false, $context);

return false !== $ret;
}

Pretty easy, no? Using the tweet() function is of course a piece of cake:
tweet(‘From PHP, yeah…’, ‘fabpot’, ‘Pa$$’)

;

source : http://fabien.potencier.org/article/20/tweeting-from-php

Tags: devloppement, PHP, twitter

Evaluate the similarity between objects through a “many to many” SQL relation Comments Off

RelationsIn many database-based projects you have to show your visitors that this “thing” is similar to this other one. For example, this blog post is similar to this other one. That’s a crucial functionnality and at first sight it’s looks easy to create.

The landscape

let’s start with this basic example :
In a blog, a “blog_post” has many “tag”. These relations are stored in a “blog_post_tag” table. When a blog post is displayed, we want to show the list of similar post to the current blog_post. Our “blog_post_tag” table just store “blog_post_id” and “tag_id“.

The first train of thought

I wanted to get all blog post that have the same associated tag. But, in this database-relation context “the same” may only mean only one of them. Quite annoying. So i finally get something that worked, and that was based on this kind of algorythm:

blogPostTags = $myBlogPost->getTags
postList = array()
foreach(blogPostTags as currentTag)
tempPostList = getAllBlogPostByTag(currentTag)
postList = array_merge(postList, array_diff(tempPostList,postList)
endforeach

Quite awfull isn’t it ? after two hours spent on something else and got back to home and discussed with friends (and whatever you want. Who said IT guy do not have a social life ?!) i just looked back at this problem and finally wrote this :

The proper way


SELECT COUNT(tag_id) as similarity, blog_post_id FROM blog_post_tag
WHERE tag_id IN (
SELECT tag_id FROM blog_post_tag WHERE blog_post_id = ?
)
GROUP BY blog_post_id

And that’s all. This SQL code gives you how many common tag you have between all the post that have at least on tag in common with a specific blog_post (replace ‘?’ by the correct value). Now just have to write it whith the Doctrine syntax ;-)

Conclusion

Just remember : when it sucks, just take a break !

Tags: devloppement, mysql, tips

Symfony : SQLSTATE[HY000]: General error: 1005 Can’t create table Comments Off

SQLSTATE[HY000]: General error: 1005 Can't create table
in a
symfony doctrine-build-all-load
command line means you have different integer size in your primary keys references

especially, sfDoctrineGuardPlugin use a integer(4) as primary key definition so, if you want to link your own ‘user’ class to sfGaurdUser class, you’ll have to define sf_uard_user_id as integer(4).

thanks to clear-cache.fr !

Tags: devloppement, mysql, symfony, tips

method setTemplate() in a sfComponent (symfony 1.2) Comments Off

source : blog.doubleu3.com

Oops, there’s no setTemplate() for components!

Why is this a problem? Because, without it, there’d have to be a seperate template file for each section’s action in the component. I just want to use the one template, and use the $section variable to determine what section to highlight.

The fix

The fix is to add a setTemplate() method to the sfComponents class.
It isn’t that complicated, but requires modification to a couple of files.

Add the following lines (2 methods, and one property definition) to
symfony/actions/sfComponent.class.php

/**
* Holds the sfView instance which performs the rendering.
*/
private $componentView;

/**
* @author Jared Armstrong
* Set the "View" object for this component, so that the component
* actions can modify the template for the view.
*
* @param sfView $componentView
*/
public function setComponentView($componentView) {
$this->componentView = $componentView;
}

/**
* @author Jared Armstrong
* Sets the template to use when rendering this component.
* @param string $template Name of the template to render
* (excluding _ and .php extension - automatically added since this is a component)
*/
public function setTemplate($template) {
$this->logMessage('Modifying template for component to \''.$template.'\'', 'debug');
if (isset($this->componentView) && $this->componentView instanceof sfView)
$this->componentView->setTemplate('_'.$template.'.php');
else
throw new sfException("Unable to set template for this component.
Component did not provide a sfView instance to modify.");
}

This provides the setTemplate() functionality like that of sfAction.

Now, we need to modify the code that creates the component instance and renders it, because we need to pass it the sfView instance to modify the output template which gets used.

In symfony/helpers/PartialHelper.php

function get_component($moduleName, $componentName, $vars = array()) {
...
$allVars = _call_component($moduleName, $componentName, $vars);
...
}

to

function get_component($moduleName, $componentName, $vars = array()) {
...
$allVars = _call_component($moduleName, $componentName, $vars, $view);
...
}

This passes the view instance to the method executing the component.

Now also

function _call_component($moduleName, $componentName, $vars) {
to

function _call_component($moduleName, $componentName, $vars, $componentView = null) {

and

function _call_component($moduleName, $componentName, $vars, $componentView = null) {
...
// create an instance of the action
$componentInstance = $controller->getComponent($moduleName, $componentName);
...
}

to

function _call_component($moduleName, $componentName, $vars, $componentView = null) {
...
// create an instance of the action
$componentInstance = $controller->getComponent($moduleName, $componentName);
$componentInstance->setComponentView($componentView);
...
}

Done!
Now your sfComponents should be able to successfully use the setTemplate method like that of your sfActions.

Possible better alternatives
Using the sfConfig, my guess is you can modify the class used to render ‘partials’, and when it runs the getTemplate() method, check to see if a variable has been set in the varholder that tells of a different template to use. However, the above method provides more transparency from actions to components.

Thank you Jared for this tip, wrote here to have a backup ;-)

Tags: devloppement, symfony, tips

How to add a post-commit mailing on SVN Comments Off

Here is a short mémo on how setting up an automatic emailing when a user commits files on a svn repository
Assuming you use a Ubuntu/Debian-based OS.

  1. First step : make sure you have a functionnal SVN-repository on the machine
  2. 2nd step : we’ll need libsvn-notify-perl package :sudo apt-get install libsvn-notify-perl
  3. You may now have the svnnotify binary in /usr/bin/ or something like this. try whereis svnnotify if you don’t know where it is
  4. go to you repository’s directory:cd /home/myname/svn/project1/
  5. create a file named post-commit in ./hooks/ and make it executable by www-datatouch ./hooks/post-commit && chown www-data:www-data ./hooks/post-commit && sudo chmod u+x ./hooks/post-commit
  6. Now edit post-commit file and write the following :#!/bin/sh
    REPOS="$1"
    REV="$2"
    /usr/bin/svnnotify -r "$REV" -C -d -H Alternative \
    --alt HTML::ColorDiff -p "$REPOS" -t "to@domain.tld" \
    --from 'from @ domain.tld ' \

    just replace to@domain.tld and from@domain.tld by your correct email adresses (advising that to@domain.tld may be a mailing-list that mail all the people that work on the project)
  7. Additionnaly, you can add this : --reply-to `cat "/home/myname/etc/svn-authors/myproject/$AUTHOR"`\ assuming that you have files that contains the email of each svn-user in the /home/myname/etc/svn-authors/myproject/ directory
    E.G : in the etc/svn-authors/myproject/ directory you can
    echo -n 'firstName.lastName@domain.tld' > userPseudo foreach of yours svn-users

Good luck !

Tags: devloppement, svn, sysadmin, tips, tool, ubuntu

Mémo débugage Javascript/Jquery Safari 3

Là ou IE et Firefox ne bronche pas, Safari refuse d’aficher une page web, le problème étant apparu après de multiple copié-collé de code javascript.
Le problème et la solution étant : lorsqu’on écris :<script type="text/javascript">
<!--
il ne faut pas oublier le // --> avant le </script>
Allez hop, une heure de gagné la prochaine fois … :’(

Tags: bonne pratiques, devloppement, JavaScript, Safari

Symfony : petite découverte pour débutants Comments Off

Bien qu’utilisant symfony (un peu) depuis quelques mois, il y a une fonctionnalité généré par propel, lors du la construction du modèle, que je vient de découvrir.

Pour la décrire, revenons un peu sur la base:
Si je créer un super application de recette de cuisine en ligne, je commence par décrire mon modèle dans schema.yml :
Propel:
user:
id:
name:
recipe:
id:
user_id:
title:
ingredient:
id:
title:
recipe_id:

Jusque là rien de miraculeux. On fait passer ça dans la moulinette propel:build-model et hop !
Ce que je connaissais déja, c’est accéder à un objet parent genre :
// http://myawsomeapp.tld/recipe/view/id/235
$recipe = RecipePeer::retrieveByPk($request->getParameter('id));
$author = $recipe->getUser();

Là déjà c’était génial. Le framework est capable de générer, pour un objet, une fonction qui permet d’accéder aux objets vers lesquels il pointe (souvenez vous le user_id).
Ce que je vient de découvrir (tardivement) c’est que la manip inverse est tout aussi vrai.
$inredients = $recipe->getIngredients()
(vous remarquerez le s)
Et voila !

ps : certes ceci est basique, mais n’ayant jamais eu trop le temps de bosser la doc de propel et n’ayant pas encore éplucher aux petit oignons le code généré par celui-ci, je ne découvre ceci qu’aujourd’hui et j’applaudis :)
ps2 : la balise <code> ne gère pas l’indentation apparemment. n’oubliez pas les espaces dans le schema.yml !

Tags: devloppement, symfony, tips

Svn mémo Comments Off

Impossible à trouver sur le web (ou alors google me déteste),
voici un mémo des commandes svn les plus utiles (selon moi)

  • Créer un repository:
    svnadmin create /path/to/repo
  • Première importation dans le repository:
    svn import /path/to/file/to/be/imported/ file:///path/to/repository/ -m "first import message"
  • Afficher les fichiers impactés par le commit #123 et le message de commit :
    svn log -v -r 123
  • Gestion des accès au repository :
    • /path/to/repository/conf/svnserve.conf
      [general]
      anon-access = read/write/none
      auth-access = read/write/none
      password-db = passwd
      realm = my SVN project foo
    • /path/to/repository/conf/passwd
      user:notencryptedpassword
  • Commandes usuelles :
    • mis à jour de la copie locale des fichiers :
      svn up
    • envoyer des fichiers mis à jour sur le repository :
      svn ci file1 file2 fil3 -m "commit message"

    Apparement il est possible d’avoir un tortoise-like sous ubuntu :
    $ sudo apt-get install nautilus-script-collection-svn
    $ nautilus-script-manager enable Subversion

    via : snippets.prendreuncafe.com

    et encore plus complet ( mais pas parfait, béta oblige, grosse lenteur du HDD donc de tout le système sur ma machine ): google code : Nautilus SVN

    Tags: devloppement, svn, tips, tool