コード例 #1
0
 /**
  * Executes autocomplete action.
  * returns formated list of best matching names and their ids
  */
 public function executeAutocomplete()
 {
     sfLoader::loadHelpers(array('General'));
     $model = $this->model_class;
     $module = c2cTools::model2module($model);
     $string = $this->getRequestParameter($module . '_name');
     // useful protection:
     if (strlen($string) < sfConfig::get('app_autocomplete_min_chars')) {
         return $this->renderText('<ul></ul>');
     }
     // return all documents matching $string in given module/model
     // NB: autocomplete on outings only returns those for which the current user is linked to
     // autocomplete on articles and images only returns collaborative and proper personal ones (all for moderators)
     $user = $this->getUser();
     $filter_personal_content = !$user->hasCredential('moderator') && ($module == 'articles' || $module == 'images');
     $results = Document::searchByName($string, $model, $user->getId(), $filter_personal_content);
     $nb_results = count($results);
     if ($nb_results == 0) {
         return $this->ajax_feedback_autocomplete('no results');
     }
     if ($nb_results > sfConfig::get('app_autocomplete_max_results') && $nb_results < sfConfig::get('app_list_maxline_number')) {
         // if there are too many results to display, but if there is at least one exact match, it is in the results returned by the db query
         // we display the exact matches, if any. We translate some special chars and capital letters
         sfLoader::loadHelpers(array('General'));
         $simple_string = remove_accents($string);
         $exact_matches = array();
         foreach ($results as $result) {
             if (remove_accents($result[$this->model_class . 'I18n'][0]['name']) == $simple_string || $module == 'users' && remove_accents($result['private_data']['username']) == $simple_string) {
                 $exact_matches[] = $result;
             }
         }
         if (count($exact_matches)) {
             $results = $exact_matches;
         } else {
             return $this->ajax_feedback_autocomplete('Too many results. Please go on typing...');
         }
     } elseif ($nb_results == sfConfig::get('app_list_maxline_number')) {
         // we have the maximum number of results returned by the db query, so we assume there are more
         // before giving up and returning "too many results", we can try some extra things
         // if we have lat lon info, we try to limit results to those in the neighboorhood
         if ($this->hasRequestParameter('lat') && $this->hasRequestParameter('lon') && in_array($module, array('sites', 'huts', 'parkings', 'summits'))) {
             $near_results = Document::searchByName($string, $model, $user->getId(), $filter_personal_content, false, array('lon' => floatval($this->getRequestParameter('lon')), 'lat' => floatval($this->getRequestParameter('lat'))));
             $nb_near_results = count($near_results);
             if ($nb_near_results && $nb_near_results < sfConfig::get('app_autocomplete_max_results')) {
                 $results = $near_results;
             } else {
                 return $this->ajax_feedback_autocomplete('Too many results. Please go on typing...');
             }
         } else {
             $exact_results = Document::searchByName($string, $model, $user->getId(), $filter_personal_content, true);
             $nb_exact_results = count($exact_results);
             if ($nb_exact_results) {
                 $results = $exact_results;
                 $exact_matches = true;
             } else {
                 return $this->ajax_feedback_autocomplete('Too many results. Please go on typing...');
             }
         }
     }
     // build the actual results based on the user's prefered language
     $items = Language::getTheBest($results, $model);
     // if module = summit, site, parking or hut, check for similarities and if any, append regions for disambiguation
     if (in_array($model, array('Summit', 'Site', 'Parking', 'Hut'))) {
         $items_copy = $items;
         for ($i = 1; $i < count($items); $i++) {
             $item_cmp = array_shift($items_copy);
             foreach ($items_copy as $item) {
                 if (levenshtein(remove_accents($item_cmp[$this->model_class . 'I18n'][0]['name']), remove_accents($item[$this->model_class . 'I18n'][0]['name'])) <= 3) {
                     $add_region = true;
                     break 2;
                 }
             }
         }
     }
     if (isset($add_region)) {
         // retrieve attached regions best names
         $q = Doctrine_Query::create()->select('m.id, g0.main_id, a.area_type, ai.name, ai.culture')->from("{$model} m")->leftJoin("m.geoassociations g0")->leftJoin('g0.AreaI18n ai')->leftJoin('ai.Area a')->addWhere('g0.main_id IN (' . implode(',', array_keys($items)) . ')')->addWhere("g0.type != 'dm'")->execute(array(), Doctrine::FETCH_ARRAY);
         $areas_array = Language::getTheBestForAssociatedAreas($q);
         // choose the best area description (like in homepage)
         foreach ($areas_array as $item) {
             $area_name = Area::getBestRegionDescription($item['geoassociations']);
             if (!empty($area_name)) {
                 $items[$item['id']]['area_name'] = $area_name;
             }
         }
     }
     // create list of items
     $html = '<ul>';
     foreach ($items as $item) {
         $identifier = $model == 'Document' ? $this->__(substr($item['module'], 0, -1)) . ' ' : '';
         // if module = documents, add the object type inside brackets
         switch ($model) {
             case 'Outing':
                 $postidentifier = ' (' . $item['date'] . ')';
                 // if outings, we append the date
                 break;
             case 'Summit':
             case 'Hut':
                 $postidentifier = ' - ' . $item['elevation'] . $this->__('meters');
                 // if summit or hut, append elevation
                 break;
             case 'Book':
                 $postidentifier = (check_not_empty($item['author']) ? ' - ' . $item['author'] : '') . (check_not_empty($item['publication_date']) ? ' - ' . $item['publication_date'] : '');
                 break;
             case 'User':
                 $postidentifier = ' (' . $item['private_data']['username'] . ')';
                 // if user, append forum nickname
                 break;
             default:
                 $postidentifier = '';
         }
         $postidentifier .= isset($item['area_name']) ? ' (' . $item['area_name'] . ')' : '';
         // if region attached, we append it
         $html .= '<li id="' . $item['id'] . '">' . $item[$this->model_class . 'I18n'][0]['name'] . '<span class="informal">' . "<em>{$postidentifier}</em> <small>[{$identifier}" . $item['id'] . ']</small></span></li>';
     }
     if (isset($exact_matches)) {
         $html .= '<div class="feedback">' . $this->__('only exact matches. Go on typing') . '</div>';
     }
     if (isset($nb_near_results) && $nb_near_results) {
         $html .= '<div class="feedback">' . $this->__('only near matches. Go on typing') . '</div>';
     }
     $html .= '</ul>';
     return $this->renderText($html);
 }
コード例 #2
0
ファイル: _latest.php プロジェクト: snouhaud/camptocamp.org
     $timedate = $item['date'];
     if ($timedate != $date) {
         echo '<span class="date">' . format_date($timedate, $item_date_format) . '</span>';
         $date = $timedate;
     }
     echo get_paginated_activities($item['activities']) . ' ';
     $i18n = $item['OutingI18n'][0];
     $id = $item['id'];
     $lang = $i18n['culture'];
     echo link_to($i18n['name'], "@document_by_id_lang_slug?module=outings&id={$id}&lang={$lang}&slug=" . make_slug($i18n['name']), array('hreflang' => $lang));
     $outing_data = array();
     $max_elevation = displayWithSuffix($item['max_elevation'], 'meters');
     if (!empty($max_elevation)) {
         $outing_data[] = $max_elevation;
     }
     $area_name = Area::getBestRegionDescription($item['geoassociations'], true);
     if (!empty($area_name)) {
         $outing_data[] = $area_name;
     }
     if (count($outing_data) > 0) {
         echo ' <span class="meta">(' . implode(' - ', $outing_data) . ')</span>';
     }
     if (isset($item['nb_images'])) {
         $images = picto_tag('picto_images_light', format_number_choice('[1]1 image|(1,+Inf]%1% images', array('%1%' => $item['nb_images']), $item['nb_images'])) . ' ';
         echo $images;
     }
     ?>
         </li>
 <?php 
 }
 ?>