Share » Learn » eZ Publish » Creating Custom Admin Modules & Views

Creating Custom Admin Modules & Views

Monday 18 April 2011 2:42:34 pm

  • Currently 4 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Creating a second view – handling POST data

Once you have created the module and the first view, setting up the second view is much, much quicker as a lot of the initial steps we took only need to be carried out at module rather than view level. Because of this we do not need to create or update nearly as many files.

To show how we can handle form data, let’s setup a basic form which takes email content from the user and then sends it to the users who have signed up to receive newsletters. We will start by updating the files we already have and then we will build the additional TPL and PHP file we need to create to implement the logic and display code for the new view.

 

Updating existing files

The only files we need to update are those which hold view specific information. The key file to update is the module.php we created in our modules directory (/extension/mynewsletter/modules/newsletter/module.php) which you may recall details where each view is located within the module. Apart from this the only other file to update is the static left navigation template file we created (/extension/mynewsletter/design/admin/templates/newsletter/leftmenu.tpl).

Let’s update both of these now with the details of our new view.

 

Updating the Module.php file for multiple views

Open your module.php file (/extension/mynewsletter/modules/newsletter/module.php). To add another view to our module we need to add another array to $ViewList with the details for the new module. Let’s call our new view “sendemail” and give it a different permission so that only certain users can send newsletters (additions to our previous module.php file are in bold) :

<?php
$module = array( 'name' => 'newsletter' ); //the name of our module

$ViewList = array();//add as many views as you want here
$ViewList['userlist'] = array( 'script' => 'userlist.php', 
                               'default_navigation_part' => 'newslettersnavigationpart',
                               'functions' => array( 'read' ));//the script used to setup the template plus the user permissions required for it (also see below)
<b>$ViewList['sendemail'] = array( 'script' => 'sendemail.php', 
                                'default_navigation_part' => 'newslettersnavigationpart',
                                'functions' => array( 'send'));</b>
 
//setting user permissions required by our module:
$FunctionList = array(); 
$FunctionList['read'] = array(); 
<b>$FunctionList['send'] = array(); </b>
?>
 

As you can see it is pretty much identical to our previous code. We have separated the permissions between the views so it is possible for a user to view the user list without sending emails and vice versa. This is a great way of limiting who can do what in your modules and ensure you maintain a good level of security.

As with the ‘userlist’ view we can get the URL from the array key used in the $ViewList array. Once we have created the templates we will be able to access the page at the url:

http://www.yoursite.com/admin/newsletter/sendemail

 

Updating the left navigation

Again, our left menu is going to be a simple addition to the code we already have. Open the menu template (/extension/mynewsletter/design/admin/templates/newsletter/leftmenu.tpl). Since we are using a different permission we need to check the user’s access level to both “read” and now “send” but this is based on the code we have already created. Our new code is shown in bold:

{def $has_read_permission = fetch( 'user', 'has_access_to',
                                   hash( 'module',   'newsletter',
                                         'function', 'read', 
                                         'user_id', $current_user.contentobject_id  ) )}
<b>{def $has_send_permission = fetch( 'user', 'has_access_to',
                                   hash( 'module',   'newsletter',
                                         'function', 'send', 
                                         'user_id',$current_user.contentobject_id  ) )}</b>

<div class="box-header"><div class="box-tc"><div class="box-ml"><div class="box-mr"><div class="box-tl"><div class="box-tr">
<h4>Newsletters</h4>
</div></div></div></div></div></div>

<div class="box-bc"><div class="box-ml"><div class="box-mr"><div class="box-bl"><div class="box-br"><div class="box-content">
<ul>
    {if $has_read_permission}
        <li><div><a href={'/newsletter/userlist'|ezurl()}>Users signed up</a></div></li>
    {/if}
<b>    {if $has_send_permission}
        <li><div><a href={'/newsletter/sendemail'|ezurl()}>Send email</a></div></li>
    {/if}</b>
</ul>
</div></div></div></div></div></div>
 

Creating our new view- Template file

Now, we need to make sure the user has a template to see. We are going to create a simple POST based form. We will then use eZHTTPTool to access the text the user has entered send it out to the mailing list. We will make use of the feedback box we used in our previous view to show feedback to the user. For simplicity, our form will only allow users to send text based rather than HTML emails. Create a file called “sendemail.tpl” in the same directory as our other templates (/extension/mynewsletter/design/admin/templates/newsletter/). Add the following code to the new file:

{*Include message box if necessary:*}
{if or(is_set($feedback),is_set($error))}
    {include uri="design:newsletter/newsletter_feedback_box.tpl" feedback=$feedback error=$error}
{/if}

<div class="box-header">
    <div class="button-left">
        <h2 class="context-title">Send Email</h2>
    </div>
    <div class="float-break"></div>
</div>

<div class="box-content">    
    <form method="POST" >                
        <div class="block">
            <label>Enter your email</label>
            <textarea name="email" cols="60" rows="20"></textarea>    
        </div>
        <div class="controlbar">
            <div class="block">
                <input type="submit" title="Send the email to all users in your mailing list" value="Send email" name="sendButton" class="defaultbutton">
            </div>
            </div>
    
    </form>
</div>
 

The key part is the simple form we have created within the bottom div (with the class “box-content”) which will pass the email back to the view where it will be sent out. The other content within the template is to ensure the view is tailored for the admin site access.

 

Creating our new view – PHP file

We now need to create the PHP file which will setup the view. The same file will also be sending the email. Create a new PHP file called sendemail.php and store it alongside our existing PHP files (/extension/mynewsletter/modules/newsletter/).

Our code is split into three parts, code each of the following code blocks in the order they appear:

 

Initialising the eZ Publish based variables

As well as the Template Object we initialised in our previous view, in our new view we need to process form fields. In eZ Publish we do this using the eZHTTPTool which provides a wrapper to GET, POST and Session data.

Be mindful of the different code for eZ Publish 4.2 and earlier.

<?php
$http = eZHTTPTool::instance();
$tpl = eZTemplate::factory();//this lines of code is for ez publish 4.3, replace it with the following line for versions prior to that
//version <4.3 of eZ Publish should use these lines of code instead:
//include_once( 'kernel/common/template.php' );
//$tpl = templateInit();
 

Processing the form

Straight after the variables are set we need to carry out the form processing and send the email to the mailing list, if the user has submitted the form. We are carrying this out now to ensure that when the main view template is fetched, the feedback from the pending request is available if necessary:

if ( $http->hasPostVariable( 'email' ) )
{
    //setting up the eZMail object:
    $mail = new eZMail();
    $ini = eZINI::instance();
                       $emailSender = $ini->variable( 'MailSettings', 'AdminEmail' );
    $mail->setSender( $emailSender );    
    $mail->setReceiver( $emailSender, "MySite Newsletter");
                       $mail->setSubject( "Newsletter from MySite" );
                       $mail->setBody( $http->postVariable('email') );
    
    /* fetching all users who wish to receive emails: */
    $attributeFilter  = array( array( 'user/newsletter', '=', 1 ) );
    $params = array('AttributeFilter'=>$attributeFilter);
    //getting the ID of where the users sit in the cms (limiting the area eZ has to search for the objects):
    $parent_node = eZContentObjectTreeNode::fetchByURLPath( 'users/members' ); //note the lowercase. Use underscores rather than hyphens if spaces are included in the path
    $parent_node_id = $parent_node->NodeID;
    
    //putting all of the above together into a fetch query:
    $newsletter_users = eZContentObjectTreeNode::subTreeByNodeID( $params, $parent_node_id );
    
    //adding all users to the receiver list:
    foreach( $newsletter_users as $user )
    {
        $userFields = $user->attribute( 'data_map' );
        $mail->addBcc( $userFields['user_account']->attribute('content')->attribute('email'), $userFields['user_account']->attribute('content')->attribute('login'));
    }

    if ( eZMailTransport::send( $mail ) )
    {
        $tpl->setVariable( 'feedback', "The email has been sent to " . count( $mail->bccElements() ) . " users" );
        
    }
    else 
    {
        $tpl->setVariable( 'error', "There was a problem sending the email" );
    }
}
 

The eZHTTP tool is very straightforward to use and can be used in exactly the same way to pull out GET parameters if necessary. Once we have established an email needs to be sent, we initialise an eZMail object and add all users within the mailing list to the BCC list the email is being sent to. We then send out the email and then supply an appropriate message to the user, based on the result. It should be noticed that the following PHP:

/*fetching all users who wish to receive emails:*/
$attributeFilter  = array( array( 'user/newsletter', '=', 1 ) );
$params = array('AttributeFilter'=>$attributeFilter);
//getting the ID of where the users sit in the cms (limiting the area eZ has to search for the objects):
$parent_node = eZContentObjectTreeNode::fetchByURLPath( 'users/members' ); //note the lowercase. Use underscores rather than hyphens if spaces are included in the path
$parent_node_id = $parent_node->NodeID;

// putting all of the above together into a fetch query:
$newsletter_users = eZContentObjectTreeNode::subTreeByNodeID( $params,$parent_node_id );
 

Is equivalent to the Fetch we created previously in our template for the list of users (userlist.tpl):

{def $users_folder = fetch( 'content', 'node', hash( 'node_path', 'Users/Members' ) )
     $newsletter_users = fetch( 'content', 'list', 
                                hash( 'parent_node_id', $users_folder.node_id,
                                      'attribute_filter', array( array( 'user/newsletter', '=', 1 ))))
}
 

Please note you can also use the ezcMail class (from the Apache Zeta Components) for emails when sending emails via eZ Publish.

 

Process the view

Finally, we need to setup the content the user sees. This code works in an identical manner to the code we created for our previous view:

// Process template and set path data:
$Result = array();
$Result['content'] = $tpl->fetch( 'design:newsletter/userlist.tpl' );//main tpl file to display the output

$Result['left_menu'] = "design:newsletter/leftmenu.tpl";
$Result['path'] = array( array( 'url' => 'newsletter/userlist',
                                'text' => 'User List' ) );
?>
 

The Finished View

Our second view is now complete, The final view should look something like the following:

Send email view

 

Printable

Printer Friendly version of the full article on one page with plain styles

Author(s)