• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 592
  • Last Modified:

Need help to modify PHP to sort a directory list

Hello,

I have purchased an extension for Joomla (WorkForce) to display contact information for all of our employees.

When you first land on the "list all Employee's" page the employees are listed but not in alphabetical order. But the extension does provide a way to manual alphabetize the list by either Last or First name.

I have tried contacting the developer of this extension, but they have not responded to my inquiry.

What I am wanting is that by default when you first land on the "list all Employee's" page it lists the employee's in alphabetical order by their last name, but I have yet to figure out how to modify the code to do this.

I have included the code below. The site is not accessible from outside our network so I will not be able to share the link.

Inital code displaying of employees when you land on the "list all Employee's" Page:

// display results for employees
        if ($this->items)
        { 
            echo '
                <ul class="thumbnails span12">';
                    $this->k = 0;
                    $x = 0;
                    foreach($this->items as $e){
						$this->employee = $e;
                        echo $this->loadTemplate('employee');
                        $this->k = 1 - $this->k;
                        $x++;

                        if($x == $columns && $x < count($this->items)){
                            echo '</ul><ul class="thumbnails">';
                            $x = 0;
                        }
                    }
            echo '
                </ul>

Open in new window


The code for the loadTemplate('employee'); :

defined( '_JEXEC' ) or die( 'Restricted access' );
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers');

$employee_link      = JRoute::_(WorkforceHelperRoute::getEmployeeRoute($this->employee->id, $this->employee->department));
$department_name    = (JRequest::getVar('view') == 'allemployees') ? workforceHTML::getDepartmentName($this->employee->department).' - ' : '';

//check length of bio - decide whether or not to create snippet and read more link
$wflen     = $this->params->get('overview_char',250);
$biolen    = strlen($this->employee->bio);
$readmore  = ($biolen > $wflen) ? true : false;

switch($this->params->get('employee_columns', 2))
{
    case '1':
    default:
        $span = 12;
        break;
    case '2':
        $span = 6;
        break;
    case '3': 
        $span = 4;
        break;
    case '4':
        $span = 3;
        break;
}
?>

<li class="span<?php echo $span; ?>">
    <div class="thumbnail">
        <?php if($this->employee->icon && $this->employee->icon != 'nopic.png') echo '<a href="'.$employee_link.'"><img src="'.$this->employee_folder.$this->employee->icon . '" alt="' . $this->employee->name . '" /></a>'; ?>
        <h3><a href="<?php echo $employee_link; ?>"><?php echo $this->employee->name; ?></a></h3>
        <p class="wf-dep-position-holder"><?php echo $department_name; ?><span class="wf-employee-position"><?php echo $this->employee->position; ?></span></p>
        <div class="wf-icon-holder btn-toolbar">
            <div class="btn-group">
                <?php
                if($this->employee->website):
                    // make sure URL has scheme
                    $website    = JURI::getInstance( $this->employee->website );
                    if (!$website->getScheme()) $website = 'http://' . $this->employee->website;
                    $web_icon   = JHtml::_('image','components/com_workforce/assets/images/web.png', JText::_('COM_WORKFORCE_WEBSITE'));
                    echo '<a class="btn btn-mini hasTip" href="'.$website.'" target="_blank" title="'.JText::_('COM_WORKFORCE_WEBSITE').'::'.JText::_('COM_WORKFORCE_VISIT_WEBSITE').'">'.$web_icon.'</a>';
                endif;
                if($this->employee->availability):
                    $emp_avail      = $this->employee->availability;
                    $adisplay       = str_replace(';','<br />',$emp_avail);
                    $calendar_icon  = JHtml::_('image','components/com_workforce/assets/images/calendar.png', JText::_('COM_WORKFORCE_AVAILABILITY'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_AVAILABILITY').'::'.$adisplay.'" href="javascript:void(0)">'.$calendar_icon.'</a>';
                endif;
                if($this->params->get('show_vcard', '')):
                    $vcard_icon = JHtml::_('image','components/com_workforce/assets/images/vcard.png', JText::_('COM_WORKFORCE_VCARD'));
                    echo '<a class="btn btn-mini hasTip" href="'.JRoute::_('index.php?option=com_workforce&task=employee.vcard&employee_id='.(int)$this->employee->id.'&format=raw').'" target="_blank" title="'.JText::_('COM_WORKFORCE_VCARD').'::'.JText::_('COM_WORKFORCE_DOWNLOAD_VCARD').'">'.$vcard_icon.'</a>';
                endif;
                if($this->params->get('show_map') && $this->employee->street && $this->employee->street != ' '):
                    // create map address
                    $mapaddress     = $this->employee->street.' ';
                    $mapaddress    .= $this->employee->city ? $this->employee->city . ', ' : '';
                    $mapaddress    .= $this->employee->locstate ? workforceHTML::getStateName($this->employee->locstate) . ' ' : '';
                    $mapaddress    .= $this->employee->province ? $this->employee->province . ' ' : '';
                    $mapaddress    .= $this->employee->postcode ? $this->employee->postcode : '';
                    $mapaddress    .= $this->employee->country ? ' ' . workforceHTML::getCountryName($this->employee->country) : '';
                    $mapaddress		= urlencode($mapaddress);

                    $map_icon = JHtml::_('image','components/com_workforce/assets/images/map.png', JText::_('COM_WORKFORCE_SHOW_MAP'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_SHOW_MAP').'::'.htmlentities('<img src="http://maps.googleapis.com/maps/api/staticmap?markers='.$mapaddress.'&zoom=14&size=200x200&maptype=roadmap&sensor=false" />').'" href="javascript:void(0)">'.$map_icon.'</a>';                    
                endif;
                if(($this->params->get('allow_edit', '') && (!$this->user->guest && ($this->user->get('id') == $this->employee->user_id))) || $this->user->authorise('core.admin', 'com_workforce')):
                    $edit = JHtml::_('icon.edit', $this->employee);
                    echo '<a class="btn btn-mini hasTip" href="'.$edit['link'].'" title="'.JText::_('JGLOBAL_EDIT').'::'.$edit['tooltip'].'">'.$edit['image'].'</a>';
                endif;
                ?>
            </div>
            <div class="btn-group">
                <?php
                if ($this->employee->twitter && $this->params->get('show_twitter', false)):
                    $twitter_icon = JHtml::_('image','components/com_workforce/assets/images/twitter.png',JText::_('COM_WORKFORCE_TWITTER'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_TWITTER').'" href="'.workforceHTML::getUrl($this->employee->twitter).'" target="_blank">'.$twitter_icon.'</a>';
                endif;
                if ($this->employee->facebook && $this->params->get('show_facebook', false)):
                    $facebook_icon = JHtml::_('image','components/com_workforce/assets/images/facebook.png',JText::_('COM_WORKFORCE_FACEBOOK'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_FACEBOOK').'" href="'.workforceHTML::getUrl($this->employee->facebook).'" target="_blank">'.$facebook_icon.'</a>';
                endif;
                if ($this->employee->youtube && $this->params->get('show_youtube', false)):
                    $youtube_icon = JHtml::_('image','components/com_workforce/assets/images/youtube.png',JText::_('COM_WORKFORCE_YOUTUBE'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_YOUTUBE').'" href="'.workforceHTML::getUrl($this->employee->youtube).'" target="_blank">'.$youtube_icon.'</a>';
                endif;
                if ($this->employee->linkedin && $this->params->get('show_linkedin', false)):
                    $linkedin_icon = JHtml::_('image','components/com_workforce/assets/images/linkedin.png',JText::_('COM_WORKFORCE_LINKEDIN'));
                    echo '<a class="btn btn-mini hasTip" title="'.JText::_('COM_WORKFORCE_LINKEDIN').'" href="'.workforceHTML::getUrl($this->employee->linkedin).'" target="_blank">'.$linkedin_icon.'</a>';
                endif; 
                if ($this->employee->skype && $this->params->get('show_skype', false)):
                    $skype_icon = JHtml::_('image','components/com_workforce/assets/images/skype.png',JText::_('COM_WORKFORCE_SKYPE'));
                    echo '
                    <script type="text/javascript" src="http://www.skypeassets.com/i/scom/js/skype-uri.js"></script>                        
                    <div title="'.JText::_('COM_WORKFORCE_SKYPE').'" id="SkypeButton_Dropdown_'.$this->employee->skype.'_1">
                      <script type="text/javascript">
                        Skype.ui({
                          "name": "dropdown",
                          "element": "SkypeButton_Dropdown_'.$this->employee->skype.'_1",
                          "participants": ["'.$this->employee->skype.'"]
                        });
                      </script>
                    </div>';
                endif;
                ?>
            </div>
        </div>        
        <?php
        if($this->params->get('show_overview_contact', 1)):
            echo '<div class="wf-employee-contact-holder">';
                if($this->employee->email && $this->params->get('show_employee_email', 1)):                
                    echo '<div class="wf-contact-item"><abbr title="'.JText::_('COM_WORKFORCE_EMAIL').'">E:</abbr> '.JHTML::_('email.cloak', $this->employee->email).'</div>';
                endif;
                if($this->employee->phone1):
                    $ext1 = ($this->employee->ext1) ? ' '.JText::_('COM_WORKFORCE_EXT').':'.$this->employee->ext1 : '';
                    echo '<div class="wf-contact-item"><abbr title="'.JText::_('COM_WORKFORCE_PHONE1').'">P:</abbr> '.$this->employee->phone1.$ext1.'</div>';
                endif;
                if($this->employee->phone2):
                    $ext2 = ($this->employee->ext2) ? ' '.JText::_('COM_WORKFORCE_EXT').':'.$this->employee->ext2 : '';
                    echo '<div class="wf-contact-item"><abbr title="'.JText::_('COM_WORKFORCE_PHONE2').'">P2:</abbr> '.$this->employee->phone2.$ext2.'</div>';
                endif;
                if($this->employee->fax):
                    echo '<div class="wf-contact-item"><abbr title="'.JText::_('COM_WORKFORCE_FAX').'">F:</abbr> '.$this->employee->fax.'</div>';
                endif;
            echo '</div>';
        endif;
        if($this->employee->bio && $this->params->get('overview_char') >= 1):
            echo '<hr />';
            if($this->params->get('full_bio', false) || $readmore == false): //show full bio with no stripped tags
                echo '<p class="wf-employee-overview">'.$this->employee->bio.'</p>';
            else: //show snippet of bio with stripped tags
                echo '<p class="wf-employee-overview">'.workforceHTML::snippet($this->employee->bio, $wflen).'</p>';                
            endif;
            echo '<a class="btn btn-info readon" href="'.$employee_link.'">'.JText::_('COM_WORKFORCE_VIEW_BIO').'</a>';
        endif;
        ?>
        <?php $this->dispatcher->trigger( 'onAfterRenderEmployeeOverview', array( &$this->employee, &$this->params, &$this->user )); ?>
    </div>
</li>

Open in new window


Code for the class that does the sort when a user selects the option to sort:

public static function buildEmployeeSortList($filter_order, $attrib = null, $view = null)
    {
        $sortbys    = array();
        $sortbys[]  = JHTML::_('select.option', 'e.ordering', JText::_( 'COM_WORKFORCE_SELECT' ) );
		$sortbys[]  = JHTML::_('select.option', 'e.lname', JText::_( 'COM_WORKFORCE_LAST_NAME' ) );
        $sortbys[]  = JHTML::_('select.option', 'e.fname', JText::_( 'COM_WORKFORCE_FIRST_NAME' ) );
        if($view == 'allemployees') $sortbys[] = JHTML::_('select.option', 'd.name', JText::_( 'COM_WORKFORCE_DEPARTMENT' ) ); //ADDED 2/11/10
        return JHTML::_('select.genericlist', $sortbys, 'filter_order', $attrib, 'value', 'text', $filter_order );
    }

Open in new window



---

I know I am asking a bit, but I am in hopes of being able to figure this out. I can provide more code if needed.
0
Morgan
Asked:
Morgan
4 Solutions
 
Marco GasiFreelancerCommented:
What is the content of $this->items (line 2 of your first snippet)?
I suggest you to use the precious var_dump() function to see it:

echo "<pre>";
var_dump($this->items);
echo "</pre>";
0
 
Steve BinkCommented:
Without looking to deeply into the rest of the code, your quickest/easiest bet is to sort the records just prior to display.  That would be around line 7 in the first file you posted.  Take a copy of $this->items, and cast it or otherwise convert it into an array.  Sort that array by your chosen field.  Finally, modify the foreach() to use the sorted array.
0
 
Ray PaseurCommented:
My guess is that $this->items is an array or possibly an object.  When you run the var_dump() please post the results here.  You can obscure passwords and any other private information, but please do not alter any of the property names or data structure.  You do not have to post the entire output, just a few complete elements will be enough for us to see what we are dealing with.  Once we see the contents of $this->items we can advise how to sort it.  Probably we will use something like usort(); the exact answer will depend on the structure of $this->items.

The class that does the sort when the user selects a sort order appears to modify the query arguments.  It may turn out to be necessary to do that, but I think visualizing the data and looking to sort $this->items will give us a faster path to a solution.

How many elements (employees) are represented in $this->items?
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
MorganAuthor Commented:
Here is the results of var_dump function:

array(50) {
  [0]=>
  object(stdClass)#380 (37) {
    ["id"]=>
    string(1) "1"
    ["fname"]=>
    string(6) "First Name"
    ["lname"]=>
    string(5) "Last Name"
    ["alias"]=>
    string(12) "firstname-lastname"
    ["position"]=>
    string(14) "Web Programmer"
    ["department"]=>
    string(1) "5"
    ["email"]=>
    string(25) "email address"
    ["phone1"]=>
    string(12) "phone number"
    ["ext1"]=>
    string(0) ""
    ["phone2"]=>
    string(0) ""
    ["ext2"]=>
    string(0) ""
    ["fax"]=>
    string(0) ""
    ["street"]=>
    string(0) ""
    ["street2"]=>
    string(0) ""
    ["city"]=>
    string(0) ""
    ["locstate"]=>
    string(1) "0"
    ["province"]=>
    string(0) ""
    ["postcode"]=>
    string(0) ""
    ["country"]=>
    string(1) "0"
    ["featured"]=>
    string(1) "0"
    ["icon"]=>
    string(9) "nopic.png"
    ["bio"]=>
    string(0) ""
    ["ordering"]=>
    string(1) "1"
    ["state"]=>
    string(1) "1"
    ["website"]=>
    string(0) ""
    ["twitter"]=>
    string(0) ""
    ["youtube"]=>
    string(0) ""
    ["facebook"]=>
    string(0) ""
    ["linkedin"]=>
    string(0) ""
    ["skype"]=>
    string(0) ""
    ["user_id"]=>
    string(1) "0"
    ["availability"]=>
    string(0) ""
    ["departmentid"]=>
    string(1) "5"
    ["departmentname"]=>
    string(31) "Information Technology Services"
    ["name"]=>
    string(12) "A name"
    ["dep_alias"]=>
    string(31) "information-technology-services"
    ["phone"]=>
    string(12) "phone number"
  }
  [1]=>
  object(stdClass)#382 (37) {
    ["id"]=>
    string(1) "5"
    ["fname"]=>
    string(4) "First Name"
    ["lname"]=>
    string(5) "Last Name"
    ["alias"]=>
    string(10) "firstname-lastname"
    ["position"]=>
    string(24) "Financial Aid Generalist"
    ["department"]=>
    string(1) "7"
    ["email"]=>
    string(23) "email address"
    ["phone1"]=>
    string(12) "phone number"
    ["ext1"]=>
    string(0) ""
    ["phone2"]=>
    string(0) ""
    ["ext2"]=>
    string(0) ""
    ["fax"]=>
    string(0) ""
    ["street"]=>
    string(0) ""
    ["street2"]=>
    string(0) ""
    ["city"]=>
    string(0) ""
    ["locstate"]=>
    string(1) "0"
    ["province"]=>
    string(0) ""
    ["postcode"]=>
    string(0) ""
    ["country"]=>
    string(1) "0"
    ["featured"]=>
    string(1) "0"
    ["icon"]=>
    string(9) "nopic.png"
    ["bio"]=>
    string(0) ""
    ["ordering"]=>
    string(1) "1"
    ["state"]=>
    string(1) "1"
    ["website"]=>
    string(0) ""
    ["twitter"]=>
    string(0) ""
    ["youtube"]=>
    string(0) ""
    ["facebook"]=>
    string(0) ""
    ["linkedin"]=>
    string(0) ""
    ["skype"]=>
    string(0) ""
    ["user_id"]=>
    string(1) "0"
    ["availability"]=>
    string(0) ""
    ["departmentid"]=>
    string(1) "7"
    ["departmentname"]=>
    string(13) "Financial Aid"
    ["name"]=>
    string(10) "Name"
    ["dep_alias"]=>
    string(13) "financial-aid"
    ["phone"]=>
    string(12) "phone number"
  }
..and it continues in this fashion

Open in new window


------------------------

We have about 150+ employees.

Currently I have uploaded about 50 so far.

Thanks everyone for their feedback!

Thanks,

Neo
0
 
Ray PaseurCommented:
Perfect candidate for usort()
http://www.laprbass.com/RAY_temp_neonate.php

<?php // RAY_temp_neonate.php
ini_set('display_errors', TRUE);
error_reporting(E_ALL);
echo '<pre>';

// SORT AN ARRAY OF OBJECT BY LASTNAME, FIRSTNAME
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28312470.html#a39708223

// SETUP SOME TEST DATA
$object = new stdClass;

$object->id    = "1";
$object->fname = "Ray";
$object->lname = "Paseur";
$object->work  = "Programmer";
$object->func  = "testData";
$arr[] = clone $object;

$object->id    = "2";
$object->fname = "John";
$object->lname = "James";
$object->work  = "Student";
$arr[] = clone $object;

$object->id    = "3";
$object->fname = "Dave";
$object->lname = "Baldwin";
$object->work  = "Expert";
$arr[] = clone $object;

// A FUNCTION TO COMPARE BY NAMES
function cmp_name($a, $b)
{
    $a_name = $a->lname . $a->fname;
    $b_name = $b->lname . $b->fname;
    if ($a_name == $b_name) return 0;
    return ($a_name < $b_name) ? -1 : 1;
}

// SORT THE ARRAY
usort($arr, 'cmp_name');

// SHOW THE WORK PRODUCT
print_r($arr);

Open in new window

Best regards, ~Ray
0
 
MorganAuthor Commented:
Hello Ray,

Thanks for the work! Though I get a gist of what you are trying to accomplish, I am not verse enough with PHP to fully grasp how this works and therefore how to implement it with what I have so far.

The first question is why do we clone $object and assign it to our array? Isn't &object set as array already?

Taking what you have provided and trying to incorporate it to the existing code this is what I came up with:
       	function Comparison($a, $b) {
		$a_name = $a->lname . $a->fname;
    	        $b_name = $b->lname . $b->fname;
   		if ($a_name == $b_name) return 0;
    		       return ($a_name < $b_name) ? -1 : 1;	
		}
        // display results for employees
        if ($this->items)
        { 
            echo '
                <ul class="thumbnails span12">';
                    $this->k = 0;
                    $x = 0;
                    foreach($this->items as $e){
						$this->employee = usort($e, 'Comparison');
						//$this->employee = $e;
                        echo $this->loadTemplate('employee');
                        $this->k = 1 - $this->k;
                        $x++;
                        if($x == $columns && $x < count($this->items)){
                            echo '</ul><ul class="thumbnails">';
                            $x = 0;
                        }
                    }
            echo '
                </ul>
            <div class="clear-both"></div>';

Open in new window

The result I get back from this is nothing, just dash lines - so obviously I didn't do this correctly.

Thanks in advance,

neo
0
 
Ray PaseurCommented:
Lines 9-29 of the code snippet I posted were needed to create test data so I could show you how usort() works.  That would not be part of what you're working with.

I think you might want to try usort() on $this->items.  Then print out $this->items with var_dump() and see if that's the order you want.  If it is, then go back to the earlier example and put the usort() call into the code something like this (line 4).
// display results for employees
        if ($this->items)
        { 
            /* PUT usort() HERE*/
            echo '
                <ul class="thumbnails span12">'; ... ETC

Open in new window

0
 
MorganAuthor Commented:
Ray your awesome!

Thanks!

Finished code:

// order list alphabetically
		function Comparison($a, $b) {
			$a_name = $a->lname . $a->fname;
    		$b_name = $b->lname . $b->fname;
   			if ($a_name == $b_name) return 0;
    		return ($a_name < $b_name) ? -1 : 1;	
		}
        // display results for employees
        if ($this->items)
        { 
            usort($this->items, 'Comparison');
			echo '
                <ul class="thumbnails span12">';
                    $this->k = 0;
                    $x = 0;
                    foreach($this->items as $e){
						$this->employee = $e;
                        echo $this->loadTemplate('employee');
                        $this->k = 1 - $this->k;
                        $x++;
                        if($x == $columns && $x < count($this->items)){
                            echo '</ul><ul class="thumbnails">';
                            $x = 0;
                        }
                    }
            echo '
                </ul>

Open in new window


There are a few changes I need to make, because of the Manual sorting a user can do, but this works perfectly and does what I need it to.

Thanks!
0
 
Ray PaseurCommented:
Great!  Glad you got it working.  Thanks for the points and thanks for using EE, ~Ray
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now