Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Thursday, 2 February 2012

Drupal: iterating array items that are not properties (hashes)

I recently needed to iterate over the elements of an array, ignoring any "properties" (signified in Drupal using hashes e.g. $form['items']['#value']). Originally I did this by iterating over all the elements, and then filtering out those that I didn't want. Turns out there is a neater way: element_children(). This does the filtering for you, and returns the keys of normal (non-property) elements. You can use it like this:

foreach (element_children($form["items"]) as $i) {
    // something with $form["items"][$i]
}

Friday, 2 December 2011

Drupal 6: Enable/Disable the WYSIWYG Editor on Specific Forms

You will need your own custom module for this, in order to implement hook_form_FORM_ID_alter().

DISABLING
You can disable the WYSIWYG editor on any form by setting the FAPI (Forms API) setting #wysiwyg to FALSE e.g. for the Page node edit form, you can do this:
function MODULE_form_page_node_form_alter(&$form, &$form_state) {
    $form['body_field']['body']['#wysiwyg'] = FALSE;
}

ENABLING
  1. Some contrib modules (e.g. Ubercart) have completely disabled WYSIWYG editors on some of their textareas, and I haven't found a way around this.
  2. If you have checked the "Enable by default" option, the WYSIWYG editor should automatically be enabled for any form fields that have the "Input format" option below them.
  3. For other forms (with simple textareas that dont have the "Input format" option) you must manually enable the "Input format" option yourself. This can be done by again altering the $form object in your hook_form_FORM_ID_alter() e.g. for the Description field on the form to edit a content type:
function MODULE_form_node_type_form_alter(&$form, &$form_state) {
    $form['identity']['format'] = filter_form();
}


Update: if you're more into GUIs than fiddling in the code, you could just install the Better Formats module, which gives you loads of control on which Input formats are used for which forms. Then by having one plain-text input format, and another one associated with a WYSIWYG editor, you can easily control which forms use which.

Drupal 6: hook_form_node_form_alter() not working

I've long known about the versatile hook_form_alter() function, which allows you to alter any form before it gets displayed on the page, using your own custom module. Recently I discovered the wonderful hook_form_FORM_ID_alter() function, which is only fired for a specific form id, making it a better solution when you want to target only 1 form.

I had used this successfully a few times, and then hit a wall when I tried using it for the main node edit form (the form's id is node-form, so I called the function hook_form_node_form_alter). Half an hour later, I stumbled upon the solution: it does not want the HTML ID attribute, it wants the internal Drupal ID for the form. So in my custom module, I used this code to get the ID:

function MODULE_form_alter(&$form, &$form_state, $form_id) {
 echo "formID=".$form_id;
}

Which turned out to be page_node_form, so the final function that worked was called MODULE_form_page_node_form_alter().

REFERENCES
http://www.hashbangcode.com/blog/drupal-hookformalter-node-form-501.html

Wednesday, 20 July 2011

PHP Doctrine 2: Convert UK date string to datetime

You have a form with a date field, and on submit you want to save the value as a Doctrine Datetime. You may find PHP's strtotime() function, but this will only work for dates in the US format (e.g. mm/dd/yyyy) and not the UK format (e.g. dd/mm/yyyy). The solution is to use DateTime::createFromFormat() which lets you specify the way the date string is formatted.
$result = DateTime::createFromFormat("d/m/Y", $dateString);
This can then be set as your datetime property on your entity, and persisted in the database. You can see which letters to use to represent your date format here.

Wednesday, 13 July 2011

PHP autocomplete / code assist in Eclipse

I've been programming in PHP a lot recently, and the main issue I've been having is that Eclipse finds it difficult to auto-complete e.g. suggest methods that can be run on an instance of a class. This article shows you how to fix this using PHPDoc to give Eclipse more type information. Note: it assumes you have a User class on your include_path.

You can declare types for arguments to functions. Note: ignore the double spacing - it is a bug with the FogBugz wiki
function myFunction(User $user) {
$user-> // this will now autocomplete
}

You can declare return type of functions
/** @return User */
private function getUser() {
return new User();
}

public function run() {
$user = $this->getUser();
$user-> // this will now autocomplete
}

You can declare the type of class properties (AKA fields), accessed with $this->var. Note: you can also do this inline above the property itself, using @var instead of @property, BUT annoyingly the PHPdoc has to be in the 3 line form (doesn't work if you shorten it to 1 line e.g. /** @var User $user */)
/**
* @property User $user
*/
class myClass {
protected $user;
function myFunction() {
$this->user-> // this will now autocomplete
}
}

You can declare the type on variables in the code
/* @var $user User */
$user-> // this will now autocomplete

Zend Log: Log to a file, formatting output, logging request details, and all error info

Wham this in your Bootstrap.php (replacing YOUR_WEBSITE):
protected function _initLogger() {
$writer = new Zend_Log_Writer_Stream('/var/log/YOUR_WEBSITE/output.log');
$format = '%timestamp% %priorityName%: %message%' . PHP_EOL;
$formatter = new Zend_Log_Formatter_Simple($format);
$writer->setFormatter($formatter);
$logger = new Zend_Log($writer);
$logger->setTimestampFormat("d-M-Y H:i:s");
Zend_Registry::set('logger', $logger);
}
Functions starting with _init will automatically be run during the bootstrap. This will setup the logger to log to a file in your logs directory, with a slightly clearer format than the default one (inc. simplified date format). It then saves the logger instance in the Zend_Registry, which means we can access it from our controllers!

Now in your Controller:
class IndexController extends Zend_Controller_Action {
private $logger;
public function init() {$this->logger = Zend_Registry::get('logger');}
public function indexAction() {$this->logger->info("Hello");}
}

Next, lets setup our logger to log the details of all requests, as this is really useful for debugging. We do this with a Controller Plugin, by implementing the preDispatch function (create application/plugins/Logger.php):
class Application_Plugin_Logger extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$uri = $_SERVER['REQUEST_URI'];
if ($uri != "/favicon.ico") {
$logger = Zend_Registry::get('logger');
$logger->info("* REQUESTED URI ".$_SERVER['REQUEST_URI']
    .", CONTROLLER ".$request->getControllerName()
    .", ACTION ".$request->getActionName());
}
}
}
Note: we don't bother logging browsers requests for favicon.ico, as they are not very interesting

Then we need to register the plugin, which we do back in our bootstrap, at the end of _initLogger():
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_Logger());

Finally, we setup the ErrorController to log all error information by adding this code to errorAction():
$logger = Zend_Registry::get('logger');
$params = $errors->request->getParams();

$paramsString = "array (\n";
foreach($params as $key=>$value) {
$paramsString .= "'".$key."' => '".$value."'\n";
}
$paramsString .= ")";

$logger->crit("ERROR = ".$this->view->message."\n"
    ."MESSAGE = ".$errors->exception->getMessage()."\n"
    ."STACK TRACE = \n".$errors->exception->getTraceAsString()."\n"
    ."REQUEST PARAMS = ".$paramsString);

Wednesday, 1 June 2011

CentOS php-config: command not found

If you try using php-config, and you get the error: "command not found", you just need to install php-devel.
sudo yum install php-devel

Tuesday, 22 February 2011

PHP Logging on Ubuntu 10.04 Lucid

PHP CONFIGURATION
Enable PHP logging by setting up the appropriate variables in your php.ini. If you don't know where your php.ini file is, try the command: locate php.ini, mine was here: /etc/php5/apache2/php.ini:
error_reporting = E_ALL & ~E_DEPRECATED
log_errors = On
error_log = /var/log/apache2/php_errors.log
EXTRA: if you want to show PHP errors on screen, set:
display_errors = On
To finish, we restart apache: sudo /etc/init.d/apache2 restart


PERMISSIONS
Then find out what your apache user is called: ps aux | grep apache (mine was www-data), and ensure that user has full permissions on the log file directory (/var/log/apache2/). The best way to do this is ensure the user has group access i.e. either add the user the group currently assigned to the directory, or change the directory's group to one that the user is in! On my system, the directory had the group: adm, and so I added www-data to that group (see /etc/group). You then need to give the directory full permissions for group access: sudo chmod 770 /var/log/apache2/

To register these changes, we need to log out and back in again.


TESTING
An easy way to generate a PHP error is to call an undefined function i.e. put this PHP code into one of your pages:
a_function_that_doesnt_exist();
Now when you visit that page, you will either get a PHP error on screen (if you enabled that), or your browser will just display a 403 error, but importantly, your new log file php_errors.log should have been created and had it's first error logged.


INLINE PHP CONFIGURATION
One other method worth noting is inline configuration. During development, you may decide you want to temporarily enable showing errors on the screen for a particular page. The easiest way to do this, is simply to add this line of PHP to the top of your PHP file:
ini_set('display_errors', TRUE);

Thursday, 28 October 2010

Opening Drupal PHP files in Eclipse

By default, some Drupal files will not open in the proper editor (they will just be treated as plain text). Assuming you have PDT installed for PHP development, you can specify which filetypes contain PHP code and hence should be opened in the PHP editor.

Look in Windows > Preferences > General > Content Types > Text > PHP Content Type, and add each of the following associations:
*.engine
*.theme
*.install
*.inc
*.module
*.profile
*.test

PROBLEM
If when you then try opening one of these files, you get an error along the lines of:
Unable to create editor ID org.eclipse.php.editor: org.eclipse.core.internal.filebuffers.SynchronizableDocument cannot be cast to org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument

SOLUTION
Restart eclipse.


References: http://drupal.org/node/75242

Friday, 4 June 2010

Installing PHP 5.3 on CentOS 5

Using the 3rd party repository by Remi Collet, which seems to be the most popular 3rd party web repo.

1) Install the repo by following the instructions on his website: http://blog.famillecollet.com/pages/Config (this site is in French, which can be automatically translated if you use Google Chrome!). Note that it depends on the EPEL repo, but the instructions take care of that as well. For me, this meant executing the following commands:
wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
sudo rpm-Uvh remi-release-5 *. rpm EPEL-release-5 *. rpm

2) Enable the new repository by setting enabled=1 in this file: /etc/yum.repos.d/remi.repo

3) Upgrade your PHP packages. Optionally you can add the suffix mysql-* to upgrade your mysql packages as well. Note: this will automagically fetch the GPG key for Remi's repo.
sudo yum update php php-*

4) Restart Apache
sudo /etc/init.d/httpd restart

Note: after this I got an error on all pages: "Warning: strtotime(): It is not safe to rely on the system's timezone settings". The solution was to add my timezone to /etc/php.ini i.e. add the line
date.timezone = "Europe/London"
You can find a list of supported timezones here: http://www.php.net/manual/en/timezones.php


References
http://gofedora.com/how-to-install-php-on-centos-red-hat-rhel/