Solved

Need help to modify PHP to sort a directory list

Posted on 2013-12-06
9
476 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 30

Assisted Solution

by:Marco Gasi
Marco Gasi earned 50 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 108

Accepted Solution

by:
Ray Paseur earned 450 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Great!  Glad you got it working.  Thanks for the points and thanks for using EE, ~Ray
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

772 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

11 Experts available now in Live!

Get 1:1 Help Now