Generate the WSDL file from a class using a Zend component

Matthew Weier O’Phinney answers a very common question;

“Is there a way to generate the WSDL file from a class using a Zend component?”

Yes — via Zend_Soap_Autodiscover:

http://framework.zend.com/manual/en/zend.soap.autodiscovery.html

A typical workflow is to do the following:


if ('GET' == $_SERVER['HTTP_METHOD']) {
$server = new Zend_Soap_Autodiscover();
} else {
$server = new Zend_Soap_Server();
}

$server->setClass('SomeClass');
echo $server->handle();

Basically, you handle GET requests as a request for the WSDL, and anything else as a SOAP request.

Acceptance Test-Driven Development

Giorgio Sironi writes an interesting TDD story; I am halfway through reading Growing object-oriented software, guided by tests, a book that teaches Test-Driven Development in a Java environment. A review will come soon, since the process described in this work is really language-agnostic and interesting also for php developers.

However, the book’s authors introduce a very productive practice, which consists in a double cycle of TDD:

* a longer cycle, where you write acceptance (aka end-to-end) tests, deriving them from the user stories or formal requirements, and make them pass;

* a shorter cycle contained in the first, which happens in the phase when an acceptance test is red: you write unit tests and make them pass until the related acceptance test does not fail anymore.

Read complete story @ PHP Zone.

Zend Framework + Doctrine 1 Integration

Benjamin Eberlei writes; Hello everyone,

I completed a first version of Zend + Doctrine 1 integration today and want to share it with all you. Since currently the status on a 1.11 release is unclear I contacted all the contributors to various Doctrine-related components and combined them into a single release and wrote some documentation on all the different parts and how they relate to each other.

http://github.com/beberlei/zf-doctrine

The code is under the New BSD License. There is a comprehensive getting started guide shipped with the Github Project.

The following parts are included in this release:

  • Application Resource contributed by Matt Lurz
  • Dynamic Form Generation contributed by Jani Hartikainen
  • Paginator Adapter contributed by Matt Lurz and Juozas Kaziukenas
  • Zend Tool Provider and modular Zend Project Style Support

Thanks to all the contributors and various other people that contributed ideas and code.

For any feedback regarding this integration, you can use the issue tracker on Github.

This release depends on Doctrine 1.2.2 to allow model code-generation from YAML files that supports Zend Framework Modular projects and their directory structure.

Most of the current glue code out there is made obsolete by generating Models that follow the Zend Framework naming conventions, into Zend Framework models/ directories. Additionally there is also support for modular applications whose model classes should follow the PEAR naming schema.

Additionally the dynamic form support allows to create simple forms that allow to create and edit Doctrine_Record instances and their relations.

This is a great help to rapidly prototype admin forms (however support for more complex forms is not yet included).

Since both projects are currently very focused on their 2.0 releases, this release aims to glue all the existing code for Doctrine 1.x and Zend Framework integration 1.x together, giving them a platform to flourish.

greetings,
Benjamin

Talk: PHP Best Practices – Matthew Weier O’Phinney and Lorna Jane Mitchell

Writing maintainable code is an art that takes effort and practice to master.
Part of that art is learning what tools and strategies will assist you in that effort. In this tutorial, we will cover a variety of practices and tools that can make your life, and the lives of your team members, easier as you develop your applications. Among them, we will provide overviews of:

  • Version Control
  • Coding Standards
  • Unit Testing basics
  • QA tools: phpcs, phploc, phpmd, continuous integration, and more
  • Team Collaboration tools, such as Skype, IRC, issue trackers, and more

via Talk: PHP Best Practices – Joind.in.

Accessing Bootstrap Resources from Anywhere

Aleksey V. Zapparov posts a very nice solution to a very common question when dealing with Bootstrap resources;

Hello,
You can either register precious resources in registry, e.g.:


protected function _initMyResource()
{
$res = 'foobar';
Zend_Registry::set('myResource', $res);
return $res;
}

Or you can register the whole bootstrap, so you can place in it’s constructor, something like this:


public function __construct($application) {
parent::contstruct($application);
Zend_Registry::set('Bootstrap', $this);
}

So later you’ll be able to access resources via:

$res = Zend_Registry::get('myResource');

or:

$res = Zend_Registry::get('Bootstrap')->getResource('MyResource');

And there is another way to get your bootstrapper from almost
everywhere:

$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$resource = $bootstrap->getResource('MyResource');

Sincerely yours,
Aleksey V. Zapparov A.K.A. ixti

Zend Framework Class to retreive your RSS feeds used in Google Reader

Rémi Goyard wrote a nice little class to access your Google Reader Feeds take a peek below, he says;

I finally wrote my own class to retreive data from my Google reader Account (stared items, shared items, …)
The class needs some more work.
Regards
Rémi

< ?php /** * Class to retreive your rss feeds used in Google Reader * thanks to : * @see http://www.niallkennedy.com/blog/2005/12/google-reader-api.html * @see http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI * * @author Rémi Goyard * @category Core * @package Core_Gdata * @subpackage Gdata * @copyright Rémi Goyard * @license http://framework.zend.com/license/new-bsd New BSD License * @version 0.1 */ /** * Zend_Gdata_HttpClient */ require_once 'Zend/Http/Client.php'; /** * Zend_Version */ require_once 'Zend/Version.php'; class Core_Gdata_Reader{ /** * The Google client login URI */ const CLIENTLOGIN_URI = 'https://www.google.com/accounts/ClientLogin'; /** * The default 'source' parameter to send to Google */ const DEFAULT_SOURCE = 'Zend-ZendFramework-Google-Reader 1.0/Zend'; /** * The Google reader Base URI */ const GOOGLE_READER_BASE_URI = "http://www.google.com/reader/"; /** * Default Google Reader Actions */ private $GOOGLE_READER_ACTIONS = array( "subscriptions" =>"atom/user/[USERID]/pref/com.google/subscriptions",
"starred" =>"atom/user/[USERID]/state/com.google/starred",
"shared" => "atom/user/[USERID]/state/com.google/broadcast",
"broadcast" => "atom/user/[USERID]/state/com.google/broadcast",
"read" => "atom/user/[USERID]/state/com.google/read",
"reading-list" => "atom/user/[USERID]/state/com.google/reading-list",
"tag" => "atom/user/[USERID]/label/[TAG]"
);

/**
* Default Params
*/
private $_defaultParams = array("n"=>20);

const SERVICE_NAME = "reader";

private $_userID = "";
private $_email = "";
private $_password = "";

/**
* @var Zend_Http_Client
*/
private $_client = null;

/**
*
* @param string $email
* @param string $password
* @param string $userID
*/
public function __construct($email, $password, $userID){
if (! ($email && $password && $userID)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception(
'Please set your Google credentials before trying to ' .
'authenticate');
}
$this->_email = $email;
$this->_password = $password;
$this->_userID = $userID;
$this->_setHttpClient();

}
private function _setHttpClient()
{
if (! ($this->_email && $this->_password)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception(
'Please set your Google credentials before trying to ' .
'authenticate');
}
$this->_client = new Zend_Http_Client();
$this->_client->setParameterPost("Email", $this->_email);
$this->_client->setParameterPost("Passwd", $this->_password);
$this->_client->setParameterPost("Service", self::SERVICE_NAME);
$this->_client->setConfig(array(
'maxredirects' => 0,
'strictredirects' => true,
'useragent' => self::DEFAULT_SOURCE.Zend_Version::VERSION
)
);
$this->_client->setUri(self::CLIENTLOGIN_URI);
$this->_client->setMethod("POST");
$response = $this->_client->request();
if($response->getStatus() == 200){
foreach (explode("\n", $response->getBody()) as $l) {
$l = chop($l);
if ($l) {
list($key, $val) = explode('=', chop($l), 2);
$this->_client->setCookie($key,$val );
}
}
return true;
}else{
$this->_client = null;
require_once 'Zend/Exception.php';
throw new Zend_Exception('Authentication Error got Response Code : '.$response->getStatus());
}
}

/**
* Import Atom Feed
*
* @param String $type request type
* @param Array $params request params
* @return Zend_Feed_Abstract
*/
public function import($type, $params = array())
{
if(array_key_exists($type, $this->GOOGLE_READER_ACTIONS)){
if(! empty($params)){$this->_defaultParams = $params;}
// TODO : TAG ...
// TODO : manage POST actions
$urlId = str_replace("[USERID]", $this->_userID, $this->GOOGLE_READER_ACTIONS[$type] );
$url = self::GOOGLE_READER_BASE_URI.$urlId;
$this->_client->resetParameters();
$this->_client->setMethod("GET");
require_once 'Zend/Feed.php';
Zend_Feed::setHttpClient($this->_client);
return Zend_Feed::import($url);
}else{
require_once 'Zend/Exception.php';
throw new Zend_Exception('The action '.$type.' does not exists or is not yet implemented');
}
}
}

MySQL does support preparing some DDL statements, However…

Bill Karwin gives some insight into some work arounds when creating functions, triggers and procedures using Zend Framework;

MySQL does support preparing some DDL statements, even in older versions. See http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html
for lists of what statements can be prepared.

However, some DDL statements are still not supported as prepared statements, for example CREATE FUNCTION, CREATE TRIGGER, CREATE PROCEDURE.

DELIMITER is not supported as an executable statement at all, whether you prepare it or whether you do an immediate execute. Statements like DELIMITER, PAGER, SOURCE, CONNECT, and QUIT and others are builtins of the mysql command-line client. These commands are not recognized by the MySQL server.

You need to set the DELIMITER only if you’re running the CREATE FUNCTION statement in an SQL script. The default API for SQL statements does not support multiple statements per call. So you don’t have to delimit statements and you don’t have to change the delimiter.

So Nils’s solution should be the following:

1. Don’t worry about DELIMITER, you don’t need it.

2. You must DROP and CREATE in two separate statements.

3. Bypass the default ZF query method. Go directly to the
PDO::query() method when you execute a statement that isn’t preparable. You can access the PDO object using the getConnection() method of your ZF Db adapter:

$db->getConnection()->query( $drop_function_statement );
$db->getConnection()->query( $create_function_statement );

Regards,
Bill Karwin

Reporting with Zend_Tool and Zend_

Jon Lebensold posts a continuation to his screencast on Zend_tool; Reporting with Zend_Tool and Zend_Log

This video uses a collection of powerful PHP libraries in order to illustrate how easy it really is to build a command-line tool for reporting against XML files. We start off by logging visitor statistics in the controller into a log file with Zend_Log. Once data has been collected, we’re then able to utilize SimpleXML, Zend_Date and the Zend_Tool component to build out a very simple reporting tool. This is of course just an example of what’s possible. What comes to mind for me is building a cron job for generating reports based on the zf.sh executable, or even just doing backups at the command-line with the help of a fully integrated Zend Framework installation.

I’ve noticed that configuration information isn’t properly loaded into Zend_Tool and am still trying to figure out the design decisions there. You’ll notice that I was having some timezone issues with regards to Zend_Date and it seems that specifying a timezone in my application.ini file didn’t resolve the issue.

Grab a copy of the project or browse the repository.

via Zendcasts.

Zend Framework 1.10.4 Released – Notably Zend_Amf 200-300% faster

On behalf of the Zend Framework community, I’m pleased to announce the immediate availability of Zend Framework 1.10.4, our fourth maintenance release in the 1.10 series. You can download it from our downloads page:

http://framework.zend.com/download/latest

This release includes approximately 50 bugfixes, the majority of which were contributed during our Bug Hunt Days two weeks ago. The fixes contributed help stabilize and improve the 1.10 series.

Three fixes in particular are worth noting:

* ZF-7493: an important serialization improvement in Zend_Amf that has
been benchmarked as providing 200-300% faster serialization of large
datasets.

* ZF-9263: a fix to Zend_Loader::isReadable() to fix a regression found
on Windows platforms. This fix should eliminate most if not all
raised warnings that occurred during resource and plugin loading.

* ZF-9504: a patch was applied to Zend_XmlRpc_Value to make value
generation more efficient. Benchmarks and profiling show enormous
changes on large datasets: in one example, memory usage drops from
>1GB to 20MB, while dropping from execution times of >60s to around
10s.

We’d like to thank everyone who committed time, code, and translations since the 1.10.3 release — the community has been quite productive!


Matthew Weier O’Phinney