Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Need help to modify PHP to sort a directory list

Posted on 2013-12-06
9
Medium Priority
?
568 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 200 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 51

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 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 1800 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 1800 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 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 1800 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 111

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The title says it all. Writing any type of PHP Application or API code that provides high throughput, while under a heavy load, seems to be an arcane art form (Black Magic). This article aims to provide some general guidelines for producing this typ…
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…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
Suggested Courses

580 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