Add a Page to WPShower Slideshow

The WPShower WordPress theme comes with a slideshow that allows you to add posts with a featured image to it. You can’t however add pages with featured images to it. To do this you need to do the following:

1) Modify sight_add_box()


// functions.php
function sight_add_box() {
global $meta_box;

add_meta_box($meta_box['id'], $meta_box['title'], 'sight_show_box', $meta_box['page'], $meta_box['context'], $meta_box['priority']);

/* The above function adds the box to any "edit post" page. By changing the $context argument of add_meta_box() to 'page' we are saying added this Slideshow Options widget to "edit page" page. */
add_meta_box($meta_box['id'], $meta_box['title'], 'sight_show_box', 'page', $meta_box['context'], $meta_box['priority']);
}

2) Tell the slideshow grab pages along with posts

// slideshow.php
// $slides = get_posts($args); // Before
$slides = array_merge(get_posts($args), get_pages($args));

ZendX_JQuery_View_Helper_AjaxLink Doesn’t Handle “append”

Zend’s extra JQuery package has a nice helper you can use to create ajax links, but it can only update a container that you give it.


ajaxLink("Add Item",
"/generate/list-item",
array('update' => '#my-list'));
?>

This doesn’t work to well if you want to create a list of N items…

Instead of bugging Zend to fix this (There aren’t doing any more additions to the 1.X series), I just added the following to line 202 of AjaxLink.php:


// Add an append option to AjaxLink - Brian
else if(!empty($options['append']) && is_string($options['append'])){
$updateContainer = $options['append'];
$callbackCompleteJs[] = sprintf('%s("%s").append(data);', $jqHandler, $updateContainer);
}

Wala, now you can use jQuery’s append function:


ajaxLink("Add Item",
"/generate/list-item",
array('append' => '#my-list'));
?>

Creating Custom Zend Element – Phone Number

(using Zend 1.11.11)

So I wanted to make a phone number input that would have 3 boxes; area code, prefix and line. (Yes I just now learned what the three parts meant)

To do this, you need to create two things:

  • A Form Element
    • This is used to validate our element.
  • A View Helper to display it.
    • Used to create the input boxes.

Here is my PhoneNumber class:


setValue($value); // Parent call to isValid will set the value to a single part, not the whole phone number.
return false;
}

// If the user entered a number, make sure that the values are digits.
if($value != null){
// Make sure that each fild is a number
$digits = new Zend_Validate_Digits();
$errors = array();
if(!$digits->isValid($area) || !$digits->isValid($prefix) || !$digits->isValid($line)){
$this->setValue($value); // $digits->isValid will set the value to either $area, $prefix or $line, which is not the phone number value.
$this->_messages = array('Please only use numbers for phone number.');
$this->markAsError();
return false;
}
}

// Parent resets the value.
$this->setValue($value);
return true;
}

public function getValue()
{
if(is_array($this->_value)) {
$value = $this->_value['area'] . '-' .
$this->_value['prefix'] . '-' .
$this->_value['line'];

// No value given.
if($value == '--') {
$value = null;
}
$this->setValue($value);
}

return parent::getValue();
}
}

The class is pretty straight forward; it has two methods, getValue and isValid. isValid does the following:

  1. Creates a phone number value of xxx-xxx-xxxx.
  2. Uses parent isValid method to check for blank values (if required)
  3. Checks each part of the phone number to see if only numbers were used.

getValue() just returns the xxx-xxx-xxxx format of the phone number.

Now we need a way to create the actual display of our new element, this is where our view helper comes in:


view->formText(
$name . '[area]',
$area,
$areaAttribs) . '-' .
$this->view->formText(
$name . '[prefix]',
$prefix,
$prefixAttribs) . '-' .
$this->view->formText(
$name . '[line]',
$line,
$lineAttribs
);
}
}

This view helper creates 3 textboxes (using FormText view helper) to create the phone number element.

To add the element to a form:


$this->addElement('phoneNumber', 'phone_number', array(
'label' => 'Phone Number',
'validators' => array(
array('NotEmpty', true, array('messages' => 'Please input your phone number.'))
),
'required' => true,
'class' => 'phonenumber'
));

Over all, that’s pretty simple. You could use decorators (which I made a post about in one of my first blog postings Creating A Dynamic Grouped Form Element) but that seems to be a little bit more complicated, but I think it does provide more power…

Any way, with this approach you can start building some complex inputs fairly easily.

Adding Multiple View Helper Paths To application.ini

(using Zend 1.11.11)

To add a single path:
resources.view.helperPath.Custom_Zend_View_Helper = "Custom/Zend/View/Helper"

If you need to important from a variety of libs:

; Reset
resources.view[] =
; Add new paths
resources.view.helperPath.Custom_Zend_View_Helper = "Custom/Zend/View/Helper"
resources.view.helperPath.Another_Zend_View_Helper = "Another/Zend/View/Helper"

Restricting A User’s Email To A Specific Domain With Custom Zend Validator

At work, some of our online forms need to make sure that user’s use a specific email address. Since I write most of my forms with Zend, I was hoping there was already a validator for that, nope. Oh well, it wasn’t that hard to write one.

The following class will make sure that a given email address is from a specific domain. (This won’t verify it’s an email, though I could of just extended Zend_Validate_EmailAddress)


'Invalid domain used.',
self::NO_DOMAIN => 'No email domain provided.'
);

public function __construct($allowedDomain, $options = array()){
$this->_allowedDomain = $allowedDomain;
}

public function isValid($email)
{
$this->_setValue($email);

$domain = explode('@', $email);

// If no domain.
if(count($domain) == 1){
$this->_error(self::NO_DOMAIN);
return false;
}
// Wrong domain used.
if($domain[1] != $this->_allowedDomain){
$this->_error(self::BAD_DOMAIN);
return false;
}

return true;
}
}

To implement it on a form element:


$this->addElement('text', 'email', array(
'label' => 'Email:',
'description' => '(Please use your @my.domain.com account.)',
'validators' => array(
array('EmailDomain', true, array('my.domain.com')),
array('EmailAddress', false, array('messages' => 'Please use your my.domain.com email address.'))
)
));

Get File Name Extension Of Uploaded File

This is fairly simple and common thing to do (you can’t always trust the MIME type).  All you have to do to get the extension of uploaded file is to parse the file name until you reach the last “.”.  Whatever is after that “should” be your file extension.


// strripos just finds the index of the last occurrence of the given string.
echo substr($filename, strripos($filename, '.'),strlen($filename));

Keeping Your Clean URL After A Zend_Controller_Action Redirect

If you need to redirect from within your controller all you have to do is:


class myController extends Zend_Action_Controller
{
public function indexAction()
{
// "goto/here => gotoController:hereAction
$this->_redirect("/goto/here");
}
}

This works, but leaves you with your ugly url:


http://mywebsite/index.php/goto/here

To fix this, just set the preprendBase value to false:


$this->_redirect("/goto/here", array('prependBase' => false);
// Now http://mywebsite/goto/here

Zend’s documentation wasn’t very helpful with this. The API doesn’t even mention what parameters are available to set. The reference guide does, but doesn’t tell you any of the default settings.

Calling A Zend_Controller_Action_Helper within another Zend_Controller_Action_Helper

I’m not sure if this falls under good coding practices, but if you need access to one of your helper functions from within another one just get a static instance of it:


$helper = Zend_Controller_Action_HelperBroker::getStaticHelper('myOtherHelper');

This would come in handy if you’re not using the MVC design pattern (ie. no controller access) But for an MVC example of how to do this:

Example: HelloWold Helper combines Hello Helper and World Helper.

Hello Helper:

class Custom_Controller_Action_Helper_Hello extends Zend_Controller_Action_Helper_Abstract
{
/**
* @var Zend_Loader_PluginLoader
*/
public $pluginLoader;

/**
* Constructor: initialize plugin loader
*
* @return void
*/
public function __construct()
{
$this->pluginLoader = new Zend_Loader_PluginLoader();
}

public function direct()
{
return "Hello";
}
}

World Helper:

class Custom_Controller_Action_Helper_World extends Zend_Controller_Action_Helper_Abstract
{
/**
* @var Zend_Loader_PluginLoader
*/
public $pluginLoader;

/**
* Constructor: initialize plugin loader
*
* @return void
*/
public function __construct()
{
$this->pluginLoader = new Zend_Loader_PluginLoader();
}

public function direct()
{
return "World";
}
}

HelloWorld Helper

class Custom_Controller_Action_Helper_HelloWorld extends Zend_Controller_Action_Helper_Abstract
{
/**
* @var Zend_Loader_PluginLoader
*/
public $pluginLoader;

/**
* Constructor: initialize plugin loader
*
* @return void
*/
public function __construct()
{
$this->pluginLoader = new Zend_Loader_PluginLoader();
}

public function direct()
{
$hello = Zend_Controller_Action_HelperBroker::getStaticHelper('hello');
$world= Zend_Controller_Action_HelperBroker::getStaticHelper('world');
return "$hello $world!!!";
}
}

Use the helpers to say Hello World. http://localhost/hello-world/speak

class HelloWorldController extends Zend_Controller_Action
{
public function speakAction()
{
echo $this->_helper->helloWorld(); // Hello World!!!
}
}