Solved

Need help to modify PHP to sort a directory list

Posted on 2013-12-06
9
481 Views
Last Modified: 2013-12-10
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
Comment
Question by:Morgan
9 Comments
 
LVL 31

Assisted Solution

by:Marco Gasi
Marco Gasi earned 50 total points
ID: 39702768
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
 
LVL 50

Expert Comment

by:Steve Bink
ID: 39702771
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
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 450 total points
ID: 39702988
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
 
LVL 1

Author Comment

by:Morgan
ID: 39706714
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 108

Accepted Solution

by:
Ray Paseur earned 450 total points
ID: 39708223
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
 
LVL 1

Author Comment

by:Morgan
ID: 39709061
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
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 450 total points
ID: 39709384
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
 
LVL 1

Author Comment

by:Morgan
ID: 39709812
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39709910
Great!  Glad you got it working.  Thanks for the points and thanks for using EE, ~Ray
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
This article discusses how to create an extensible mechanism for linked drop downs.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now