Skip to content

Blogs

NETTUTS.com: How to Use CakePHP's Access Control Lists

PHPDeveloper.org - Fri, 07/30/2010 - 21:13

On NETTUTS.com today there's a new detailed tutorial on how to use the access control list functionality that comes with the CakePHP framework.

If you're building a CMS, you'll probably need different user roles'"superusers, admins, users - with different permission levels. Too complicated to code? Enter CakePHP's ACL (Access Control Lists). With the right setup, you'll be checking user permissions with just one line.

They talk about what "access control lists" are but shows you an example of one including the database tables and the full scripts for the Users controller, a model to hook into the database and the view for output to the user. They include methods for denying access, checking permissions, and modifying a user's permissions.

Categories: Blogs

Developer.com: 10 Experimental PHP Projects Pushing the Envelope

PHPDeveloper.org - Fri, 07/30/2010 - 20:41

On Developer.com today there's a new post listing ten experimental projects that are "pushing the envelope" in the PHP languages:

As the saying goes, "Just because you can do something doesn't mean you should." But in the world of programming, stretching boundaries is just part of the fun. The PHP community has never been one to shy away from bending their favorite language more ways than a shopping mall pretzel, and as the ten wild projects introduced in this article indicate, the fervor for experimentation is as strong as ever!

Here's their list of the ten projects they see as trying to stretch the language to its limits:

Categories: Blogs

Ask About PHP: Codeigniter: Creating dynamic graphs using JQuery and FusionCharts

PHPDeveloper.org - Fri, 07/30/2010 - 19:11

On the Ask About PHP blog today there's a new tutorial about integrating the OpenFlashCharts tool into a CodeIgniter application to display data.

I recently upgraded some of my Codeigniter applications that used OpenFlashCharts to using FusionCharts Free, and at the same time incorporated some javascript to allow me to change the graphs dynamically at the client-side. This has greatly improved the usability of my charts and graphs that I pump out. As such, I thought I would share how I did this and hopefully someone will find it useful as well.

He walks you through the steps needed to install - putting all of the files in the right places, creating a controller to use the scripts and a view to output the finished chart. A demo of the end result is also included.

Categories: Blogs

Chris Hartjes' Blog: Snakes and Elephants Playing Nice Together: PHPUnit and py.test with Hudson

PHPDeveloper.org - Fri, 07/30/2010 - 18:03

In the latest post to his blog Chris Hartjes talks about how he got python and PHP working together as a part of his testing with Hudson.

These days, it's becoming increasingly harder to find web applications that are homogenous in terms of the tools they use to Get Things Done. [...] Loosely coupled components, passing messages to each other, is great architecture to try and build if you have both the skills and patience to make it work.

His technique combines the testing of PHPUnit for PHP with the Py.test functionality for Python with the continuous integration tool Hudson to run them both as a part of the same build process.

Categories: Blogs

Symfony Project Blog: Translations (Documentation)

PHPDeveloper.org - Fri, 07/30/2010 - 16:19

Have a flair for translation and want to help out an open source project in need? Consider helping the Symfony Project with their translation efforts for their manual.

The Symfony2 documentation is written in English and many people are involved in the translation process. First, become familiar with the markup language used by the documentation. Then, subscribe to the Symfony docs mailing-list, as collaboration happens there. Finally, find the master repository for the language you want to contribute for.

Full details on what they need help on and where/how to get involved are on the documentation page of the new Symfony 2 website.

Categories: Blogs

PHPBuilder.com: The PHP Content Management/Framework Upgrades in ExpressionEngine 2

PHPDeveloper.org - Fri, 07/30/2010 - 14:31

On PHPBuilder.com there's a recent article detailing some of the updates in the latest version of the ExpressionEngine product (CMS) from EllisLab.

This popular Web development solution recently took another major step forward with the July 12 release of ExpressionEngine 2.1, the product's first major upgrade in several years. Version 2 sports a number of new features and significant improvements over its predecessor, many of which I'll highlight in this article.

He touches on a few of the updates in this latest revision:

  • CodeIgniter Integration
  • Redesigned Control Panel
  • Improved Template Management
  • Integrated File Manager and Image Editor
  • Accessories (a sort of add-on feature)

You can find out more about ExpressionEngine on its site.

Categories: Blogs

Snakes and Elephants Playing Nice Together: PHPUnit and py.test with Hudson

@TheKeyboard - Chris Hartjes - Thu, 07/29/2010 - 21:05

These days, it's becoming increasingly harder to find web applications that are homogenous in terms of the tools they use to Get Things Done. The ability to build the web front-end of your site using PHP but a critical part that requires asynchronous processing using Node.js is something that is both exciting and, well, practical. Loosely coupled components, passing messages to each other, is great architecture to try and build if you have both the skills and patience to make it work.

For a project at work, I am using PHP (specifically Zend Framework) for the front-end but are using Python scripts run as a cron-job (and also on-demand when statistical corrections occur) to collect raw stats for a variety of sports, and then generate fantasy point totals for the games we run. I'm already using PHPUnit for tests of the front end, and I decided to to use py.test to test my Python scripts.

Setting up tests in Python was pretty simple. Here's one of my test scripts:

PLAIN TEXT PYTHON:
  1. import py
  2. import baseball_scoring
  3.  
  4. def test_batter_empty_data_set():
  5.     expected_points = 0
  6.     test_data = dict()
  7.     test_points = baseball_scoring.batter_points(test_data)
  8.     assert expected_points == test_points
  9.  
  10. def test_batter_simple():
  11.     test_data = {
  12.         'hits': 4,
  13.         'doubles': 1,
  14.         'triples': 1,
  15.         'home_runs': 1,
  16.         'runs_scored': 1,
  17.         'rbi': 1,
  18.         'stolen_bases': 1,
  19.         'league': 'bluejays2010'
  20.     }
  21.     expected_points = 11
  22.     test_points = baseball_scoring.batter_points(test_data)
  23.     assert expected_points == test_points
  24.  
  25. def test_pitcher_empty_data_set():
  26.     expected_points = 0
  27.     test_data = dict()
  28.     test_points = baseball_scoring.pitcher_points(test_data)
  29.     assert expected_points == test_points
  30.  
  31. def test_pitcher_simple():
  32.     test_data = {
  33.         'wins': 1,
  34.         'losses': 0,
  35.         'saves': 0,
  36.         'strikeouts': 7,
  37.         'complete_games': 1,
  38.         'shutouts': 1,
  39.         'league': 'bluejays2010'
  40.     }
  41.     expected_points = 25
  42.     test_points = baseball_scoring.pitcher_points(test_data)
  43.     assert expected_points == test_points

Very similar to tests with PHPUnit, right? So now that I had both PHPUnit tests and py.tests tests (hrm, is there are better way to say that?) to run, I had to figure out how to automatically run them. More specifically, how to get our installation of Hudson to run them.

Getting PHPUnit to play nice with Hudson was relatively easy. I installed the NUnit plugin for Hudson, made sure I installed phpunit, and then I added it's use to my build scripts. However, the strength of Hudson is that with the use of another plugin I could read reports of all those tests. So when things failed, I would not have to look at the console output to figure things out. There's a place in the Hudson config where you can configure this:
PHPUnit configuration in Hudson

Now, I figured that the same thing could be done with py.test. It had an option so that at run-time you could tell it where to put JUnit-compatible test result files. After a little tinkering, I got it to work. First step was adding execution of it to my build script. Here is the latest-and-greatest version of that script:

mkdir /var/www/games-hudson/${BUILD_ID}
cd ${WORKSPACE}/games
/usr/local/zend/bin/php doctrine-cli migrate
cd ${WORKSPACE}/games/tests
/usr/local/zend/bin/phpunit --log-junit=${WORKSPACE}/build/logs/phpunit-results.xml
cd ${WORKSPACE}/games/scripts
/usr/bin/py.test --junitxml=${WORKSPACE}/build/logs/pytest-xmlrunner.xml
cp -R /var/lib/hudson/jobs/${JOB_NAME}/workspace/games/* /var/www/games-hudson/${BUILD_ID}
chmod 777 /var/www/games-hudson/${BUILD_ID}/tmp
rm -rf /var/www/games-hudson/current
ln -sf /var/www/games-hudson/${BUILD_ID} /var/www/games-hudson/current

Next, I then told Huson where it could find the JUnit-compatible files generated by py.test:

Telling Hudson where to find the py.test output

So there you have it. Now, when I do a commit and trigger a Hudson build, both my PHPUnit and Python tests get run. And there is output to check, so I don't have to dig through console output to figure things out.
PHPUnit

Categories: Blogs

Open Source Your Career, my story

Left on the Web - Stefan Koopmanschap - Wed, 07/28/2010 - 22:06
About a month ago my good friend Lorna Mitchell put out a call for stories on how working with Open Source has influenced people's careers. Given that a lot of my recent career has been driven by my involvement in Open Source, I shared my story with Lorna. But I also wanted to share some of my story with everyone. So here is my story and opinion on how Open Source can influence your career in a positive way.
Categories: Blogs

Gonzalo Ayuso's Blog: Clustering PHP applications. Tips and hints

PHPDeveloper.org - Wed, 07/28/2010 - 17:09

In a new post to his blog today Gonzalo Ayuso offers some tips for those out there wanting to cluster their PHP applications effectively.

Sometimes a web server and a database is fair enough to meet our project requirements. But if the project scales we probably need to think in a clustered solution. This post is an attempt at being an unsorted list of ideas working with clustered PHP applications. Maybe more than a list of ideas is a list of problems that you will face when swapping from a standalone server to a clustered server.

He touches on a few different topics you might need to consider:

  • consistency in source code
  • writing to the file systems
  • deployment problems
  • authentication/authorization issues
  • handling sessions/logs/cache files
Categories: Blogs

IBM developerWorks: Build a web-based notification tool with XMPP

PHPDeveloper.org - Wed, 07/28/2010 - 16:57

On the IBM developerWorks site there's a recent tutorial about using PHP and Javascript with the XMPP to create a small web-based notification tool (called Pingstream).

Real-time web applications are networked applications, with web-based user interfaces, that display Internet information as soon as it's published. Examples include social news aggregators and monitoring tools that continually update themselves with data from an external source. In this tutorial, you will create Pingstream, a small notification tool that uses PHP and JavaScript to communicate over the Extensible Messaging and Presence Protocol (XMPP), a set of XML technologies designed to support presence and real-time-communications functionality.

You'll need to already have the usual software installed - PHP, Apache and MySQL - as well as a few others: Openfire, jQuery, Strophe, XMPPHP and LastRSS. They introduce some of the concepts behind real-time messaging, the XAMPP protocol and, of course the code to show how to create their service.

Categories: Blogs

WebHostingHero Blog: A Look at the Original PHP Developers

PHPDeveloper.org - Wed, 07/28/2010 - 15:44

On the WebHostingHero blog today there's a new post going back to the roots of the PHP language and some of the original contributors like Rasmus Lerdorf, Zeev Suraski and Andi Gutmans.

When PHP began in 1995, it represented a fork on common object oriented programming languages. Designed to help provide scripting for the web, the language took on a life of its own as it became one of the primary web development standards. Today, PHP is used by millions worldwide and powers a majority of sites.

They talk about how some of the original developers are active in helping to better the languages (directly and indirectly) and how the advocacy of the community has helped it grow even stronger over the years. There's also mini-spotlights on each of the three mentioned above.

Categories: Blogs

Hokuten.net: A WordPress User's Guide to Drupal

PHPDeveloper.org - Wed, 07/28/2010 - 14:13

If you're a WordPress user and have been wanting to get into Drupal, you should check out this guide on hokuten.net. It gives you information on two main points - installation and theming.

Anyone who has worked with both knows that anything you can do in WordPress, you can do in Drupal, and vice versa. It just takes some elbow grease. [Drupal] is a great thing to learn because of its broad market, but WordPress developers might find some difficulty getting acclimated'"Drupal has a much higher learning curve.

They mention some of the differences between the installation of the two (creating settings files, making additional directories) and a table showing the correlating theme files between the two.

Categories: Blogs

NETTUTS.com: 20 Steps to a Flexible and Secure WordPress Installation

PHPDeveloper.org - Tue, 07/27/2010 - 19:18

On NETTUTS.com today there's a new tutorial about installing and configuring a secure WordPress installation for your site.

A comprehensive WordPress installation, albeit simple to produce, often requires multiple steps '" many of which can easily be omitted accidentally. How many times have you forgotten to customize your permalink structure? How about adding in a sitemap plugin? What about changing your timezone? If you've installed WordPress more than once, chances are you've missed something. Take the following steps and you'll never miss anything again.

Some of the steps are larger - "Get WordPress from SVN", "Add .htaccess Rules", "Apply the 4G Blacklist" - and some are smaller changes like setting up profiles, changing read/write/discussion settings and generating a sitemap. This is a great guide even if you already have WordPress installed.

Categories: Blogs

Nick Belhomme's Blog: PHP 5.3.3 Namespaces

PHPDeveloper.org - Tue, 07/27/2010 - 18:53

In a new post to his blog Nick Belhomme takes a look at namespaces in PHP 5.3 - what they are and how to use them (complete with code snippets of a small sample project).

With PHP5.3.3 recently released I really feel it is time that php developers are taking namespaces seriously. If you don't I guarantee you will be out of a job within five years. Namespaces are a fundamental part of the future of PHP.

He also makes his sample project available for download so you can follow along a bit better. He shows how to create a namespace, how to use them in both simple and more complex examples.

Categories: Blogs

Marco Tabini's Blog: PHP 5.2 support ends just as its adoption begins

PHPDeveloper.org - Tue, 07/27/2010 - 17:16

In a new post to his blog Marco Tabini has voiced his opinion on the decision made by the PHP development group to set the end of life of the PHP 5.2.x series with the latest release (5.2.14).

n case you missed it, the PHP team has just released 5.2.14, which effectively ends active support for the 5.2 branch. [...] The logic behind this decision is...puzzling.

He mentions the recent announcements of a few large PHP-based projects to officially support PHP 5.2 and how, because of the large jump in functionality from pre-5.2, it might be a good idea to reconsider this (preemptive?) retirement. He adds that making a move like this without consideration to these larger products could reflect negatively on the language itself. Be sure to check out the comments for more views from other members of the community.

Categories: Blogs

Sebastian Bergmann's Blog: Using HipHop for Static Analysis

PHPDeveloper.org - Tue, 07/27/2010 - 16:13

In a new blog entry today Sebastian Bergmann quickly shows a method of performing some code analysis on code transformed by HipHop for PHP.

HipHop for PHP, the source code transformer that turns PHP code into C++ code that can then be compiled with g++, can also be used for static code analysis to find problems in PHP source code.

He includes a script that creates an XML document that both Checkstyle and PHP_CodeSniffer can use to check for a valid format on his sample "CodeErrors.js" file. He includes the script to create this XML file.

Categories: Blogs

Key/value tables and how to use them in CakePHP 1.3

nuts and bolts of cakephp - teknoid - Tue, 07/27/2010 - 16:07

The key/value tables are a nice a approach to database modeling, when we need to store some arbitrary data about another model.

For example, let’s take a User model.
We could create a single users table to hold all of the potential data or even create an additional table such as user_details with all additional fields, which “might” be needed.

However, what happens when we don’t exactly know how much or what data will be eventually required by the application?

  • How many phones does the user have? Should we create a table with fields phone1, phone2, phone3, etc.?
  • What about emails? (Some users have 1 some have 5)
  • What happens if the business later on decides to ask for a fax number?.. and person’s height or favorite color?

If we attempt to predefine all the place-holders (columns or fields in a table) for the potential data, the table can grow horizontally into an unmanageable monster.

This is the perfect time to enter key/value tables.

Let’s consider our User model and, therefore the users table:

CREATE TABLE `users` (
  `id` char(36) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `username` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The table couldn’t be simpler. All we’ll store here is the user’s login information. The rest will be handled by the user_details table…
It’s worth to mention that our models will have a pretty standard association:
User hasMany UserDetail and on the flip side UserDetail belongsTo User

Alright, next, we have the user_details table:

CREATE TABLE `user_details` (
  `id` char(36) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `user_id` char(36) COLLATE utf8_unicode_ci DEFAULT NULL,
  `field` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The columns field and value will actually store the user details. Because this table is going to grow vertically, potentially we can store an unlimited and completely arbitrary information about a user. As a matter of fact two different parts of your app can handle storing the user details completely independent of each other. For example, when a user plays the role of a “Guest” versus a user who represents a “Member”, or better yet… a user who is not event a human being, but rather a corporate entity, in which case typical fields like first_name and last_name, may become completely irrelevant.

Hopefully you can start seeing how the key/value approach can help our modeling be a lot more flexible.

… but let’s look closer at some details… how do we deal with this in cake-like-ways?

Actually, it is not that different from what you are already accustomed to.

Let’s see our UsersController:

class UsersController extends AppController {

  public function add () {
    if(!empty($this->data)) {
      $this->User->saveAll($this->data, array('validate' => 'first'));
    }
  }

}

Nothing unusual so far…

Next comes our add.ctp view:

echo $this->Form->create('User');
echo $this->Form->input('User.username');
echo $this->Form->input('UserDetail.0.dob');
echo $this->Form->input('UserDetail.1.gender', array(
                        'type' => 'radio',
                        'legend' => FALSE,
                        'options' => array(
                                  'M' => 'M',
                                  'F' => 'F'
                       )));
echo $this->Form->input('UserDetail.2.phone');
echo $this->Form->input('UserDetail.3.email');
echo $this->Form->end('Save');

Nothing unusual so far, yet again.
We are going to save a User with some username as well as some User details: date of birth, gender, phone and an email.
Thinking back, once the save happens, our user_details table will have four records for a single user ID.

Let’s see the models then:

User:

class User extends AppModel {
  public $hasMany = array('UserDetail');

  public $validate = array(
    'username' => array(
        'rule' => 'isUnique',
        'message' => 'Username already exists'
    )
  );
}

UserDetail:

class UserDetail extends AppModel {
  public $belongsTo = array('User');

  public $validate = array(
     'dob' => array(
        'rule' => 'notEmpty',
        'message' => 'Please select a date of birth'
     ),
     'gender' => array(
        'rule' => 'notEmpty',
        'message' => 'Please select a gender'
     ),
     'phone' => array(
        'rule' => 'phone',
        'message' => 'Please enter a phone'
     ),
     'email' => array(
        'rule' => 'email',
        'message' => 'Please enter a valid email'
     )
  );

  public function beforeSave() {
     foreach($this->data[$this->alias] as $field => $value) {
        if($field !== 'user_id') {
          $this->data[$this->alias]['field'] = $field;
          $this->data[$this->alias]['value'] = $value;
        }
     }
     return true;
  }
}

So the validation is handled “as always”.

The only little bit of trickery is in our beforeSave() method…
Here we take our existing fields from the data array (dob, gender, phone…), and convert them to the expected key/value pair (or field/value based on the column names). We are skipping the user_id which is automatically injected by saveAll() just as needed.

Well, this should be a good starting point…

The more extravagant example would be showing the ability to store validation rules and field types in the DB as well. This is helpful if you would like an admin back-end to manage the requirements for user details. As of this example, we’d have to manually adjust the views and validation rules to allow for any new fields. If we store the rules (as serialized array for example) as well as field type(s), the form building and validation would be done on the fly and would allow business users to manage the specifics of the required data.

… but that’s a topic for another day.

Categories: Blogs