Twitter autofollow cakephp shell script

To promote a website I created some time ago, I thought it would be nice to setup a Twitter account for that site. But how to get some followers? Follow the potential followers first! How to do that? Find tweets with keywords that relate to the site and follow those people, because they are probably interested in my site too :).

For this I created a cakephp shell script that will do this magic. One limitation is that Twitter does not allow you to follow more than 2000 people unless you have ‘enough’ people following you back. But if your site is interesting enough, you will get followed back.

The code can be improved some more by storing some of the responses in a database, this will speed up the script when you get a lot of followers, maybe later when I have some time again I will add that feature. You need API access to Twitter, please consult the developer pages at to learn more about that.

Note: there is a problem with the Twitter search API and the Twitter API, they do not use the same IDs for users, so it is not (yet) possible to do matching on userIDs, we have to use screennames instead, pitty because it slows things down.

So here is the code for the script:

class TwitterfollowShell extends Shell {
// Twitter user, password and screenname
private $user=’userIDforTwitterAccount’;
private $pass=’passwordForTwitterAccount’;
private $screen_name = “screennameForTwitterAccount”;function main() {

// $term contains the search words to find in recent tweets
$term = “twitter+OR+follow+OR+tweet”;

// Get followers
$cursor = -1;
$followed = array();
do {
$apiUrl = “;.$this->screen_name.”.json?cursor=”.$cursor;
$apiresponse = $this->callTwitter($apiUrl);
if ($apiresponse) {
echo $cursor.”\n”;
$json = json_decode($apiresponse);

$cursor = $json->next_cursor_str;
if ($json != null) {
foreach ($json->users as $user) {
$followed[] = strtolower($user->screen_name);
} while ($apiresponse && $cursor);

// Get blocked users and add them to the followed array
//        $apiUrl = “;;
$blockedUsers = 0;
$page = 1;
do {
$apiUrl = “;.$page;
$apiresponse = $this->callTwitter($apiUrl);
if ($apiresponse) {
$json = json_decode($apiresponse);
if ($json != null) {
foreach ($json as $user) {
$followed[] = strtolower($user->screen_name);
if (count($json) == 20) {
} else {
$page = 0;
} while ($apiresponse && $page);

// search some keywords !
$apiUrl = “; . $term . “&rpp=100”;
$apiresponse = $this->callTwitter($apiUrl);

if ($apiresponse) {
$results = json_decode($apiresponse);
$count = 20;

if ($results != null) {
$resultsArr = $results->results;
if (is_array($resultsArr)) {
foreach ($resultsArr as $result) {
$from_user = strtolower($result->from_user);
if (!in_array($from_user,$followed) ) {
$apiUrl = “; . $from_user. “.json”;
$apiresponse = $this->callTwitter($apiUrl,true,”follow=true”);
if ($apiresponse) {
$response = json_decode($apiresponse);
if ($response != null) {
if (property_exists($response,”following”)) {
if ($response->following === true) {
echo “Now following ” . $response->screen_name . “\n”;
$followed[] = strtolower($response->screen_name);
} else {
echo “Couldn’t follow ” . $response->screen_name . “\n”;
} else {
echo “Follow limit exceeded, skipped ” . $result->from_user.”(“.$result->from_user_id . “)\n”;
} else {
// Already following
echo ‘.’;

function callTwitter($apiUrl, $post=false, $postFields = null) {
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_USERPWD, $this->user.”:”.$this->pass);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($post) {
curl_setopt($ch, CURLOPT_POST, 1);
if ($postFields) {
curl_setopt($ch, CURLOPT_POSTFIELDS,$postFields);
$apiresponse = curl_exec($ch);
return $apiresponse;


Problem with $this->Session->setFlash when using caching

Originally posted in the CakePHP Google Groups

I have a problem with some cakephp (version 1.2.5) code. It
concerns using $this->Session->setFlash in a controller action. Part
of the controller code:

$this->Session->setFlash(__(‘Everything fine.’, true), ‘flashinfo’);

As you can see I use a custom layout for the Flash message called

<div id=”flashInfoMessage” style=”display:none;”>
<?php echo $content_for_layout; ?>
<script language=”JavaScript” type=”text/javascript”>

code for the javascript Flash class:
return false;

What this does is show the flash message for 7 seconds after which it
will be hidden by using the nice scriptaculous effect Fade.

I have two of these layouts, one for informational messages (green
background) and one for errors (red background).

This all works perfectly fine as long as I do not use cake view
caching. But of course I want to have caching in the site for speed.

To render the flash message I placed this into the layout

<?php $session->flash(); ?>

With caching turned on and a cached version of the page being rendered
already present in the cache, this generates the following error as
soon as the redirect is performed and the specified URL in the
redirect is being rendered:

Notice (8): Trying to get property of non-object [CORE/cake_1.2.3.8166/
libs/view/helpers/session.php, line 145]

Code | Context

$key    =       “flash”
$flash  =       array(
“message” => “Uw contactformulier is verzonden.”,
“layout” => “flashinfo”,
“params” => array()
$view   =       false

} else {
$view =& ClassRegistry::getObject(‘view’);
list($tmpLayout, $tmpVars, $tmpTitle) = array
($view->layout, $view->viewVars, $view->pageTitle);

SessionHelper::flash() – CORE/cake_1.2.3.8166/libs/view/helpers/
session.php, line 145
include – APP/tmp/cache/views/home.php, line 72
View::renderCache() – CORE/cake_1.2.3.8166/libs/view/view.php, line
Dispatcher::cached() – CORE/cake_1.2.3.8166/dispatcher.php, line 678
Dispatcher::dispatch() – CORE/cake_1.2.3.8166/dispatcher.php, line 123
[main] – APP/webroot/index.php, line 88

Fatal error: Call to undefined method stdClass::renderLayout() in /usr/
session.php on line 147

The error does not occur on first time rendering of the page,
everything works as expected in that case. Also when caching is
globally turned off, everything works as expected.

Any ideas of what I am doing wrong ? Or is this a bug ?

The HABTM drama continues

I’m not happy, thought I worked it out: how to paginate a model with multiple HABTM associations like I wrote in my previous blog post. But no, well the first page I get back from the query is ok. But when going to page 2, which is the last page according to what is shown on page 1, I get some results from page 1 and suddenly there is a total of 5 pages (all records from the database). Going back from page 2 to page 1 by clicking the pagination navigation link, I get a different page 1 then the one I got initially. Back to the drawing board ?

What’s happing is this: the initial search parameters that are fed to the controller from the form are not passed on to the next page. The only thing passed is the page number. In this article at the cake bakery I found a possible solution. What Rob Conner suggests there is to use sessions to pass along the search parameters. Guess I will try to implement it like that. Not a very clean solution in my opinion. I think CakePHP is still missing some functionality in the pagination part. It all works fine of course if you specify fixed conditions in the controller, but it does not seem ‘automagic’ when you feed the controller with parameters from a form.

The way I’m feeding the parameters, through a ‘post’ form, might be the cause. See, the page links (previous, next and page numbers) are nothing more than just html links (<a> tag), so the link should contain the paramters. This is possible by using a ‘get’ form, but that doesn’t create such nice URLs (you will see your database field names). Another option could be using a form with hidden fields that is submitted when clicking the page links, but I’m not sure yet if that is possible with the pagination functions provided by Cake. So I think for now I will take the session approach.

There must be more of you running into problems like this. I wonder how you solve these kind of things with Cake. Please leave a comment with your solution(s).

Getting what you want with HABTM using multiple models and pagination…

dbschemaOh my o my… This has cost me hours/days. Maybe it’s easy if you’re a long term CakePHPer. But I just started developing with this framework, also never used anything like an MVC framework before. Ok, I know how to do databases, php, javascript,etc… But this is something else. The basics of CakePHP are quite easy to understand and use. Simple stuff like you read in the tutorials: a user has posts, a post has comments. These are all hasMany and belongTo relations, those just work fine when doing pagination. But then you have something like Posts have Tags. Then you get into the hasAndBelongsToMany (HABTM) arena, where the ‘fun’ begins… With just to tables and doing a findAll or paginate is still not all that complicated. (by the way I’m using nightly builds of the 1.2 version).

So what has given me so much ‘stress’ the past few days? Well, I’m developing a site that now has something like 30 tables (habtm join tables included), not all that big yet. But I have one table (addresses) that has multiple habtm relations (sections, areas, tags; among others). Still no problem if you just do a plain findAll(), but what if you want to search for addresses that are linked to a certain section AND area and maybe even a tag? To make it even more complex, an address hasMany telephone numbers, URLs and belongs to a user and a country and hasOne logo. There is more in the model but this gives you an idea of what I’m doing.

So I present a form to the user of the site. The form has some SELECTs where the user can select which section, area, tag and/or zip code to find addresses for. The result should be a paginated presentation of addresses. An address consists of fields like: company name, street name, zip code, telephone number(s), URL(s), logo, etc.. Here comes the somewhat simplified code (there are some comments in the controller code to explain what happens):

Continue reading