Guest User

Untitled

a guest
Sep 4th, 2010
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.48 KB | None | 0 0
  1.  
  2. Creating "pagination" links that go by first letter of a name, rather than items per page, in CakePHP (1.2).
  3.  
  4. The views were complicated by the fact that there were several types of Members. This is one of them:
  5.  
  6. CREATE VIEW members_by_letter AS
  7. SELECT CASE
  8. WHEN u.user_type_id = 2 THEN LOWER(SUBSTRING(u.last_name,1,1))
  9. WHEN u.user_type_id = 3 THEN LOWER(SUBSTRING(u.organisation_name,1,1))
  10. END AS letter, COUNT(u.id) AS present
  11. FROM users AS u
  12. INNER JOIN user_types AS ut
  13. ON ut.model IN ('Professional', 'Organisation') AND ut.id = u.user_type_id
  14. GROUP BY letter ORDER BY letter;
  15.  
  16.  
  17. But this should suffice:
  18.  
  19. CREATE VIEW members_by_letter AS
  20. SELECT LOWER(SUBSTRING(u.last_name,1,1)) AS letter, COUNT(u.id) AS present
  21. FROM users AS u
  22. GROUP BY letter ORDER BY letter;
  23.  
  24.  
  25. /**
  26.  * Members paged by letter
  27.  */
  28. public function index($letter = null)
  29. {
  30.     $letter = is_null($letter) ? 'a' : substr(strtolower((string) $letter), 0, 1);
  31.    
  32.     $members = $this->Member->findByLetter($letter);
  33.  
  34.     $alpha_list = Cache::read('alpha_list_members', 'default');
  35.  
  36.     if (!$alpha_list)
  37.     {
  38.         $alpha_list = $this->Member->getAlphaList();
  39.        
  40.         Cache::write('alpha_list_members', $alpha_list, 'default');
  41.     }
  42.    
  43.     $this->set(compact('letter', 'alpha_list', 'members'), false);
  44.    
  45.     /* render the element only if AJAX
  46.      */
  47.     if ($this->RequestHandler->isAjax())
  48.     {
  49.         Configure::write('debug', 0);
  50.         $this->viewPath = 'elements'.DS.'members';
  51.         $this->render('alpha_list');
  52.     }
  53. }
  54.    
  55. Don't forget to delete the cache if a new Member comes along or another is deleted.
  56.  
  57. Model code:
  58.  
  59. /**
  60.  * This will return an array: the keys are each letter of the alphabet for which
  61.  * there is at least one last name (or organisation name, for some types) in the
  62.  * members list. The member type queried is dependent upon the view name passed in.
  63.  * Returns an array in the form:
  64.  *
  65.  * 'a' => 1, 'b' => 1, etc.
  66.  *
  67.  * Letters for which there are no names are omitted.
  68.  *
  69.  * @return  mixed   an array of letters
  70.  *
  71.  */
  72. function getAlphaList()
  73. {
  74.     /* The result of the query should be an array in the form:
  75.      *   'a' => 1, 'b' => 1, etc.
  76.      * The keys are each letter of the alphabet for which
  77.      * there is at least one last name (or organisation name) in the members list.
  78.      * The value for each key is the number that is present in the table.
  79.      * This array will be merged with the one below, resulting in an array with every
  80.      * letter of the alphabet as the keys, the values of which will determine which
  81.      * letters will be links.
  82.      */
  83.     $default = array(
  84.         'a'=>0,'b'=>0,'c'=>0,'d'=>0,'e'=>0,'f'=>0,'g'=>0,'h'=>0,'i'=>0,'j'=>0,
  85.         'k'=>0,'l'=>0,'m'=>0, 'n'=>0,'o'=>0,'p'=>0,'q'=>0,'r'=>0,'s'=>0,'t'=>0,
  86.         'u'=>0,'v'=>0,'w'=>0,'x'=>0,'y'=>0,'z'=>0
  87.     );
  88.    
  89.     /* select from view
  90.      */
  91.     $letters = Set::combine(
  92.         $this->query('SELECT * FROM members_by_letter'),
  93.         "{n}.${view_name}.letter",
  94.         "{n}.${view_name}.present"
  95.     );
  96.    
  97.     /* some of these are not alpha -- remove for now
  98.      */
  99.     foreach($letters as $key => $val)
  100.     {
  101.         if (is_numeric($key)) unset($letters[$key]);
  102.     }
  103.    
  104.     return am($default, $letters);
  105. }
  106.  
  107.  
  108. I can't remember, offhand, what the "some of these are not alpha" was about.
  109.  
  110. findByLetter() uses this condition:
  111.  
  112. "lower(left(User.last_name, 1)) = '${letter}'"
  113.  
  114.  
  115. The index view includes an element, members/alpha_list.ctp, which laid out the list of Members. That element, in turn, included another, general element, alpha_links.ctp. I did it this way because, as I said, there were several types of members.
  116.  
  117. echo $this->element(
  118.     'alpha_links',
  119.     array(
  120.         'letter' => $letter,
  121.         'route' => array(
  122.             'controller' => 'members',
  123.             'action' => 'index'
  124.         )
  125.     )
  126. );
  127.  
  128.  
  129. alpha_links.ctp:
  130.  
  131. <?php
  132. /* Creates a series of links, one for each letter of the alphabet where at least one
  133.  * entry in the DB corresponds. Otherwise, the letter is represented in a span.
  134.  */
  135. if (isset($alpha_list) && isset($route))
  136. {
  137. ?>
  138. <div class="AlphaLinks">
  139.     <h4>List Alphabetically</h4>
  140. <?php
  141.     foreach($alpha_list as $key => $val)
  142.     {
  143.         /* are there members for this letter?
  144.          */
  145.         if ($val > 0)
  146.         {
  147.             /* is this the current letter?
  148.              */
  149.             if (isset($letter) && $key == $letter)
  150.             {
  151. ?>
  152.     <span id="current"><?= $key ?></span>
  153. <?php
  154.             }
  155.             else
  156.             {
  157.                 echo $html->link(
  158.                     $key,
  159.                     am($route, array('letter' => $key)),
  160.                     array('title' => $key, 'rel' => $key)
  161.                 );
  162.             }
  163.         }
  164.         else
  165.         {
  166.             /* no names for this letter
  167.              */
  168. ?>
  169.     <span><?= $key ?></span>
  170. <?php
  171.         }
  172.     }
  173. ?>
  174. </div> 
  175. <?php
  176. }
  177. ?>
Advertisement
Add Comment
Please, Sign In to add comment