Skip navigation

Tag Archives: zend

Basically when you are developing for Social Engine, the best approach you’d take is to try as much as possible not to modify the pre-existing modules. That is because whenever a new SocialEngine update has been released, you’ll find hard time porting your changes to the new update. Not to mention the risk of messing up a pre-existing SE code.

Luckily Social Engine follows a Modular design pattern. That is,  according to Wikipedia:

Modular programming is a software design technique that increases the extent to which software is composed of separate, interchangeable components, called modules by breaking down program functions into modules, each of which accomplishes one function and contains everything necessary to accomplish this

Modules in SocialEngine are found in “/application/modules/”.  You’ll find a nice bunch of pre-existing modules that constitute SocialEngine functionality.

So how do you create a module? There is a nice process that takes takes care of creating the basic module structure and makes it already part of the application. The process consists of 3 parts:

  1. Creating the module
  2. Installing the module
  3. Building the module
—–

This is not an official guide on how to create a module for SE, these steps I just discovered them while playing around with SE and this is what I actually do to create a module. I hope they become helpful to you 🙂

 ——

Creating the module:

  1. First off, head to your website, and login with a user who has admin privileges.
  2. We need the Package Manager, so go to this link after you login: http://<SOCIAL_ENGINE_ADDR>/install/manage, replacing of course <SOCIAL_ENGINE_ADDR> with the correct one. Inside the package manager you’ll find different installed modules, and you can enable/ disable them as you wish.
  3. Switch to Developer SDK Tab and click on Create a Package
  4. As you see Social Engine can setup for you any type of package you might need. In our case we’d select package of type Module. Complete the rest of required fields and hit “Create Package” button.
Createpackage

Create Package form

By now you’ll have a compressed archive downloaded. If you look into it you’ll find the basic module file structure has been created for you. So next step is to actually make that module part of Social Engine so that you could start working on it and preview the changes immediately.

 ——

Installing the module:

Head again to http://<SOCIAL_ENGINE_ADDR>/install/manage, and click on Install New Packages link. The process of installing a new package consists of several automated steps. You just need to specify the package to install (which is the one downloaded from the previous steps), and the Step called “Enter FTP Info“. If Social Engine is running on your local server (the actual computer that you’re developing on), then you could just choose “None” for the FTP Connection Type, put in the Path to SE (it should be already there though) and mark “Search for SocialEngine Path“. Otherwise you’ll have to fill up the FTP connection fields.

FTP Info

FTP Fields

Then keep hitting continue until you’re done. You should get message like this in the end:

Successfully installed package

So now you’ve got you’re package created, installed and enabled in your SocialEngine application. You’ll find your module has appeared in SE’s modules folder and you can now modify it as you wish. If you’re still getting started with SocialEngine, these guides might be useful as well:

 ——

Building the module:

When you have finished developing your module and you’re ready to send it for example to a client, or sell it somewhere, you can have SocialEngine build an installable package for your module.

  1. “Go to the “Developer SDK Tab” in the Package Manager.
  2. Click on Build Packages
  3. Find your module an make a tick in the associated checkbox
  4. Click on “Build Packages” button.
  5. You can now click on your package to download it. This page is also accessible from “Manage Package Files” link in Developer SDK Tab under Package Manager
Manage Packages

 

Modal Window

SE Modal Window for confirmation

Social Engine provides an easy way for showing modal windows for users. Some example for its uses are the following:

  • Confirmation windows
  • Notification windows with Timeout
  • Taking a simple input on the fly, or even showing a whole form.

Modal Windows in SocialEngine 4 are created using mootools’s plugin “smoothbox”. Simply  a modal window here is just an iframe, displaying a view as a result of calling a specific action in a controller (see Controllers).  Let’s examine what happens when you try to delete an activity.

If you look at the html tag of the delete link you’ll find that it looks like the following:

<a href=”/activity/index/delete/action_id/126″ class=”smoothbox”>Delete</a>

Any anchor <a> tag that is given a class attribute with value “smoothbox”, opens the href link in a modal window (the i-frame), instead of transferring the whole page to it. This very much simulates an Ajax request with the least effort. Let’s inspect the href value to see where it leads:

 

Module: Activity, Controller: Index, Action:Delete, Parameters: action_id=126

So head up to this action. The first few lines in the action are just to check  if the user is allowed to perform the delete operation. Also notice that the same method is invoked for both, deleting an activity (AKA action) or deleting a comment on an activity. Let’s focus this time on lines concerned with deleting the activity itself. Go for the line that say:

if (!$this->getRequest()->isPost())      return;

What happens here is that the action checks if it is invoked by a POST request (that request that takes place when you submit a form of type=post), if it is not a post request, the action just returns at this point, causing the default view for this action (delete.tpl) to render (more info on Controllers). Notice the variable passed to the view (before return) carrying the action/activity Id, which in our example is 126.

$this->view->action_id  = $action_id  = $this->_getParam(‘action_id’, null);

If you open that view (delete.tpl), you’ll find a form of type=post just as expected. It contains the confirmation message to display:

Are you sure that you want to delete this activity item and all of its comments? This action cannot be undone

Form elements include:

  • A hidden field carrying the action Id passed from the view
  • A submit button.
  • A “Cancel”  link.

Cancel link just calls the instance of smoothbox in the parent window and closes it.

<a href=”javascript:void(0);” onclick=”parent.Smoothbox.close();”><?php echo $this->translate(“cancel”) ?></a>

On submitting the form, the same action handles the request, but this time it bypasses the condition checking if it’s not a POST request (since the action is called by submitting the form). The lines after that condition just check again for further permissions, then the actual deletion takes place. We’re not to worry here about the actual deletion process, this guide is only concerned with the modal window itself and how it works. So After deleting:

$this->view->status  = true;

$this->view->message = Zend_Registry::get(‘Zend_Translate’)->_(‘This activity item has been removed.’);

$this->view->smoothboxClose = true;

return $this->render(‘deletedItem’);

The status of the operation is set to true and passed to the view to indicate success, along with the success message to display. Also a flag (smoothboxClose) is set to true to tell the view to close the smoothbox. Finally the script renders “deletedItem.tpl”

I’ll break up deletedItem.tpl into 3 parts.

Part 1:

<script type=”text/javascript”>

parent.$(‘activity-item-<?php echo $this->action_id ?>’).destroy();

 

To further simulate the ajax request, after the activity item has been deleted it should be removed from the page. The above line simply does that by getting the HTML element containing that activity using its Id and removes it. The above translates to parent.$(‘activity-item-126’).destroy();

Part 2:

setTimeout(function()

{

parent.Smoothbox.close();

}, <?php echo ( $this->smoothboxClose === true ? 1000 : $this->smoothboxClose ); ?>);

</script>

parent.Smoothbox.close() is invoked after 1000 ms only if smoothboxClose passed from deleteAction was set to true. That is to allow enough time for the user to read the success message before hiding it.

And finally:

<div class=”global_form_popup_message”>

<?php echo $this->message ?>

</div>

This shows the success message passed from deleteAction().

Here is another drawing for you

deleteAction

An API file consists of functions that provide methods of communication between a module and other modules (including itself). For example to allow interaction with database tables associated with that module; instead of duplicating a basic select statement across multiple files, we could just create a function inside the API file that returns the result of that select statement.

This makes life much easier, specially when there are complex queries (like containing pagination and stuff) that need to be called from several controllers or actions. Even better, we won’t need to worry if for example a tablename has changed in an update or something, since all we will be updating is the API to match the new name.

In a module, APIs are created inside the “Api” folder. I think it’s a SE convention to name the basic/ default API for a module as “Core”. However assume we’re creating an API called “Myapi” just for the sake of learning.

Assume we’re in a module called “Mymodule”. Inside the “Api” folder create a file called “MyApi.php” that contains the following:

<?php

class Mymodule_Api_Myapi extends Core_Api_Abstract{

}

?>

Notice the naming convention of the class name: {ModuleName}_Api_{ApiName}

Now just add any function to that class so it becomes something like this

<?php

class Mymodule_Api_Myapi extends Core_Api_Abstract{

public function addNumbers($a, $b){

return $a+$b;

}

}

?>

Of course an API would contain more sophisticated functions than addition, but that is just an example. Now in order to call this function from anywhere in the application:

$myApi =  Engine_Api::_()->getApi(‘myapi’, ‘mymodule’);

$sum = $myApi->addNumbers(10, 5);

“getApi” takes API name and Module name as parameters, and returns an instance of the API.

Since Social Engine uses the Zend Framework, the files structure are most probably the same. Social Engine uses modules. So inside the application directory you find modules folder. Each module has a separate folder, containing its associated controllers, models, views, widgets ..etc.

Controllers:

Controllers are found inside controllers folder. Each controller class has defined actions (methods) and each method must have an associated view.

Controllers’ naming convention is NameController.php. The controller’s class name becomes {modulename}_{controllername}Controller

So if we’re inside User module and looking at the Profile Controller, you’ll find:

  • Controller filename is ProfileController.php
  • Controller class name is User_ProfileController

The standard method in controller is the init()  method. This is the method that get invoked when the class is instantiated. So inside it important variables that are used within other method in the controller should be set. For example, setting the subject. I understood that socialengine uses the term “Subject” to name a variable, or an item that the user is currently looking at. For example when you view someone’s profile, the subject becomes that person. If you’re viewing a group, subject becomes that group. Subject is set in the init function so as to be available easily to all other methods in the same controller.

To set subject:

if( !Engine_Api::_()->core()->hasSubject() )    {  //Check is there is  no already set subject

$subject_temp = Engine_Api::_()->user()->getUser($id);      //set temp variable to some user, we got using his id

if( $subject_temp->getIdentity() )        {        //If temp is indeed a valid  user

Engine_Api::_()->core()->setSubject($subject_temp);      // set the subject to that user

}

}

To get subject:

$subject = Engine_Api::_()->core()->getSubject();

Methods other than init() are called actions. The take the following convention:

public function methodnameAction(){ }

inside which the action’s logic is defined.

Each  controller has a folder containing it’s views, found in views/scripts folder. For Profile Controller explained above, there is a folder called “profile“, and for each method in this controller -other than init() – there must be an associated view. So if we have a method called helloAction, there must be a file called hello.tpl within that folder.

To invoke a certain action within a certain controller, you follow this scheme in URL:

http://serveraddress/modulename/controllername/actionname/

This action gets invoked, and automatically the associated view gets rendered for display.