浏览代码

Evolution #125: Actualisation des éléments ajax

bastien 13 年前
父节点
当前提交
9bed3ec5aa

+ 6 - 0
app/Resources/translations/userui.fr.yml 查看文件

41
     inputs:
41
     inputs:
42
       cancel:       Annuler
42
       cancel:       Annuler
43
       submit:       Faire la demande
43
       submit:       Faire la demande
44
+  new:
45
+    has_news:       %count% éléments viennent d'être ajoutés, %link%
46
+    has_news_one:   %count% élément vient d'être ajouté, %link%
47
+    has_news_link:  cliquez ici pour les afficher
48
+    has_news_link_one:  cliquez ici pour l'afficher
49
+    has_news_link_more_x:  cliquez ici pour en afficher %x%
44
            
50
            
45
 filter:
51
 filter:
46
   network: "Résultats de "
52
   network: "Résultats de "

+ 164 - 0
src/Muzich/CoreBundle/Controller/ElementController.php 查看文件

211
     }
211
     }
212
   }
212
   }
213
   
213
   
214
+  protected function getcountNewMessage($count)
215
+  {
216
+    if ($count == 1)
217
+    {
218
+      $transid = 'tags.new.has_news_one';
219
+      $transidlink = 'tags.new.has_news_link_one';
220
+    }
221
+    else if ($count == 0)
222
+    {
223
+      return '';
224
+    }
225
+    else 
226
+    {
227
+      $transid = 'tags.new.has_news';
228
+      $transidlink = 'tags.new.has_news_link';
229
+    }
230
+    
231
+    
232
+    if ($count > ($limit = $this->container->getParameter('search_default_count')))
233
+    {
234
+      $link = $this->trans(
235
+        'tags.new.has_news_link_more_x', 
236
+        array(
237
+          '%x%' => $limit
238
+        ), 
239
+        'userui'
240
+      );
241
+    }
242
+    else
243
+    {
244
+      $link = $this->trans(
245
+        $transidlink, 
246
+        array(), 
247
+        'userui'
248
+      );
249
+    }
250
+    
251
+    $link = '<a href="#" class="show_new_elements" >'.$link.'</a>';
252
+    
253
+    return $this->trans(
254
+      $transid, 
255
+      array(
256
+        '%count%' => $count,
257
+        '%link%'  => $link
258
+      ), 
259
+      'userui'
260
+    );
261
+  }
262
+  
263
+  /**
264
+   * Retourne le nombre de nouveaux éléments possible
265
+   *
266
+   * @param int $refid 
267
+   */
268
+  public function countNewsAction($refid)
269
+  {
270
+    if (!$this->getRequest()->isXmlHttpRequest())
271
+    { 
272
+      return $this->redirect($this->generateUrl('index'));
273
+    }
274
+    
275
+    if ($this->getUser() == 'anon.')
276
+    {
277
+      if ($this->getRequest()->isXmlHttpRequest())
278
+      {
279
+        return $this->jsonResponse(array(
280
+          'status' => 'mustbeconnected'
281
+        ));
282
+      }
283
+      else
284
+      {
285
+        return $this->redirect($this->generateUrl('index'));
286
+      }
287
+    }
288
+    
289
+    $es = $this->getElementSearcher();
290
+    $es->update(array(
291
+      // On veux de nouveaux éléments
292
+      'searchnew' => true,
293
+      // Notre id de référence
294
+      'id_limit'  => $refid
295
+    ));
296
+    
297
+    $count = $es->getElements($this->getDoctrine(), $this->getUserId(), 'count');
298
+    
299
+    return $this->jsonResponse(array(
300
+      'status'   => 'success',
301
+      'count'    => $count,
302
+      'message'  => $this->getcountNewMessage($count)
303
+    ));
304
+  }
305
+  
306
+  /**
307
+   * Cette action, utilisé en ajax seulement, retourne les x nouveaux éléments
308
+   * depuis le refid transmis. Tout en respectant le filtre en cours.
309
+   * 
310
+   * @param int $refid identifiant de l'élément de référence
311
+   * 
312
+   * @return jsonResponse
313
+   */
314
+  public function getNewsAction($refid)
315
+  {
316
+    if (!$this->getRequest()->isXmlHttpRequest())
317
+    { 
318
+      return $this->redirect($this->generateUrl('index'));
319
+    }
320
+    
321
+    if ($this->getUser() == 'anon.')
322
+    {
323
+      if ($this->getRequest()->isXmlHttpRequest())
324
+      {
325
+        return $this->jsonResponse(array(
326
+          'status' => 'mustbeconnected'
327
+        ));
328
+      }
329
+      else
330
+      {
331
+        return $this->redirect($this->generateUrl('index'));
332
+      }
333
+    }
334
+    
335
+    $es = $this->getElementSearcher();
336
+    $es->update(array(
337
+      // On veux de nouveaux éléments
338
+      'searchnew' => true,
339
+      // Notre id de référence
340
+      'id_limit'  => $refid,
341
+      // On en veut qu'un certain nombres
342
+      'count'     => $this->container->getParameter('search_default_count')
343
+    ));
344
+    
345
+    // Récupération de ces nouveaux élméents
346
+    $elements = $es->getElements($this->getDoctrine(), $this->getUserId());
347
+    
348
+    // On en fait un rendu graphique
349
+    $html_elements = $this->render('MuzichCoreBundle:SearchElement:default.html.twig', array(
350
+      'user'        => $this->getUser(),
351
+      'elements'    => $elements,
352
+      'invertcolor' => false
353
+    ))->getContent();
354
+    
355
+    // On calcule le nouveau compte de nouveaux
356
+    $count = 0;
357
+    if (count($elements))
358
+    {      
359
+      $es->update(array(
360
+        // On veux de nouveaux éléments
361
+        'searchnew' => true,
362
+        // Notre id de référence
363
+        'id_limit'  => $elements[0]->getId(),
364
+        // On n'en récupère que x
365
+        'count'     => $this->container->getParameter('search_default_count')
366
+      ));
367
+      $count = $es->getElements($this->getDoctrine(), $this->getUserId(), 'count');
368
+    }
369
+    
370
+    return $this->jsonResponse(array(
371
+      'status'  => 'success',
372
+      'html'    => $html_elements,
373
+      'count'   => $count,
374
+      'message' => $this->getcountNewMessage($count)
375
+    ));
376
+  }
377
+  
214
 }
378
 }

+ 32 - 8
src/Muzich/CoreBundle/Repository/ElementRepository.php 查看文件

30
    * @param ElementSearcher $searcher
30
    * @param ElementSearcher $searcher
31
    * @return Doctrine\ORM\Query
31
    * @return Doctrine\ORM\Query
32
    */
32
    */
33
-  public function findBySearch(ElementSearcher $searcher, $user_id)
34
-  {    
33
+  public function findBySearch(ElementSearcher $searcher, $user_id, $exec_type = 'execute')
34
+  {
35
     // Tableaux des paramétres
35
     // Tableaux des paramétres
36
     $params_ids = array();
36
     $params_ids = array();
37
     $params_select = array();
37
     $params_select = array();
38
     $params_select['uid'] = $user_id;
38
     $params_select['uid'] = $user_id;
39
+    $order_by = "ORDER BY e_.created DESC, e_.id DESC";
39
     
40
     
40
     // Booléen nous permettant de savoir si un where a déjà été écrit
41
     // Booléen nous permettant de savoir si un where a déjà été écrit
41
     $is_where = false;
42
     $is_where = false;
138
       }
139
       }
139
     }
140
     }
140
     
141
     
141
-    // Si id_limit est précisé c'est que l'on demande "la suite"
142
+    // Si id_limit est précisé c'est que l'on demande "la suite" ou "les nouveaux"
142
     $where_id_limit = '';
143
     $where_id_limit = '';
143
-    if (($id_limit = $searcher->getIdLimit()))
144
+    if (($id_limit = $searcher->getIdLimit()) && !$searcher->isSearchingNew())
144
     {
145
     {
145
       $where_id_limit = ($is_where) ? ' AND' : ' WHERE';
146
       $where_id_limit = ($is_where) ? ' AND' : ' WHERE';
146
       $is_where = true;
147
       $is_where = true;
147
       $where_id_limit .= " e_.id < :id_limit";
148
       $where_id_limit .= " e_.id < :id_limit";
148
       $params_ids['id_limit'] = $id_limit;
149
       $params_ids['id_limit'] = $id_limit;
149
     }
150
     }
151
+    elseif ($id_limit && $searcher->isSearchingNew())
152
+    {
153
+      $where_id_limit = ($is_where) ? ' AND' : ' WHERE';
154
+      $is_where = true;
155
+      $where_id_limit .= " e_.id > :id_limit";
156
+      $params_ids['id_limit'] = $id_limit;
157
+      // Pour pouvoir charger les x nouveaux on doit organiser la liste 
158
+      // de manière croissante
159
+      $order_by = "ORDER BY e_.created ASC, e_.id ASC";
160
+    }
150
     
161
     
151
     // Requête qui selectionnera les ids en fonction des critéres
162
     // Requête qui selectionnera les ids en fonction des critéres
152
-    $r_ids = $this->getEntityManager()
163
+    $id_query = $this->getEntityManager()
153
       ->createQuery(
164
       ->createQuery(
154
         "SELECT e_.id
165
         "SELECT e_.id
155
         FROM MuzichCoreBundle:Element e_
166
         FROM MuzichCoreBundle:Element e_
163
         $where_favorite
174
         $where_favorite
164
         $where_id_limit
175
         $where_id_limit
165
         GROUP BY e_.id
176
         GROUP BY e_.id
166
-        ORDER BY e_.created DESC, e_.id DESC")
177
+        $order_by")
167
      ->setParameters($params_ids)
178
      ->setParameters($params_ids)
168
-     ->setMaxResults($searcher->getCount())
169
-     ->getArrayResult()
170
     ;
179
     ;
171
     
180
     
181
+    // Si on a précisé que l'on voulait un count, pas de limite
182
+    if ($exec_type != 'count')
183
+    {
184
+      $id_query->setMaxResults($searcher->getCount());
185
+    }
186
+    
187
+    // si l'on a demandé un count
188
+    if ($exec_type == 'count')
189
+    {
190
+      // On retourne cette query
191
+      return $id_query;
192
+    }
193
+    
194
+    $r_ids = $id_query->getArrayResult();
195
+    
172
     $ids = array();
196
     $ids = array();
173
     
197
     
174
     if (count($r_ids))
198
     if (count($r_ids))

+ 7 - 0
src/Muzich/CoreBundle/Resources/config/routing.yml 查看文件

81
   pattern: /element/{element_id}/remove
81
   pattern: /element/{element_id}/remove
82
   defaults: { _controller: MuzichCoreBundle:Element:remove }
82
   defaults: { _controller: MuzichCoreBundle:Element:remove }
83
   
83
   
84
+element_new_count:
85
+  pattern: /ajax/element/new/count/{refid}
86
+  defaults: { _controller: MuzichCoreBundle:Element:countNews, refid: null }
87
+  
88
+element_new_get:
89
+  pattern: /ajax/element/new/get/{refid}
90
+  defaults: { _controller: MuzichCoreBundle:Element:getNews, refid: null }
84
   
91
   

+ 2 - 0
src/Muzich/CoreBundle/Resources/views/layout.html.twig 查看文件

38
     url_search_tag = "{{ path('search_tag') }}";
38
     url_search_tag = "{{ path('search_tag') }}";
39
     url_get_favorites_tags = "{{ path('ajax_get_favorites_tags') }}";
39
     url_get_favorites_tags = "{{ path('ajax_get_favorites_tags') }}";
40
     url_add_tag = "{{ path('ajax_add_tag') }}";
40
     url_add_tag = "{{ path('ajax_add_tag') }}";
41
+    url_element_new_count = "{{ path('element_new_count') }}";
42
+    url_element_new_get = "{{ path('element_new_get') }}";
41
   </script>
43
   </script>
42
   {% block js %}{% endblock %}
44
   {% block js %}{% endblock %}
43
   
45
   

+ 33 - 10
src/Muzich/CoreBundle/Searcher/ElementSearcher.php 查看文件

59
   /**
59
   /**
60
    * Si id_limit est renseigné c'est que l'on veut trouver les elements
60
    * Si id_limit est renseigné c'est que l'on veut trouver les elements
61
    * plus vieux (ont utilise l'id comme référence) que l'id_limi passé.
61
    * plus vieux (ont utilise l'id comme référence) que l'id_limi passé.
62
+   * EDIT: Ou les éléments plus récents si $searchnew est a vrai
62
    * 
63
    * 
63
    * @var type int
64
    * @var type int
64
    */
65
    */
65
   protected $id_limit = null;
66
   protected $id_limit = null;
66
   
67
   
67
   /**
68
   /**
69
+   * Si searchnew est a vrai, c'est que l'on recherche les nouveau éléments 
70
+   * depuis id_limit.
71
+   * 
72
+   * @var type boolean
73
+   */
74
+  protected $searchnew = false;
75
+  
76
+  /**
68
    * @see SearcherInterface
77
    * @see SearcherInterface
69
    * @param array $params 
78
    * @param array $params 
70
    */
79
    */
77
     
86
     
78
     // Mise a jour des attributs
87
     // Mise a jour des attributs
79
     $this->setAttributes(array(
88
     $this->setAttributes(array(
80
-      'network', 'tags', 'count', 'user_id', 'group_id', 'favorite', 'id_limit'
89
+      'network', 'tags', 'count', 'user_id', 'group_id', 'favorite', 'id_limit', 'searchnew'
81
     ), $params);
90
     ), $params);
82
     
91
     
83
   }
92
   }
90
   {
99
   {
91
     // Mise a jour des attributs
100
     // Mise a jour des attributs
92
     $this->setAttributes(array(
101
     $this->setAttributes(array(
93
-      'network', 'tags', 'count', 'user_id', 'group_id', 'favorite', 'id_limit'
102
+      'network', 'tags', 'count', 'user_id', 'group_id', 'favorite', 'id_limit', 'searchnew'
94
     ), $params);
103
     ), $params);
95
   }
104
   }
96
   
105
   
178
    * Construction de l'objet Query
187
    * Construction de l'objet Query
179
    *
188
    *
180
    * @param Registry $doctrine
189
    * @param Registry $doctrine
190
+   * @param int $user_id
191
+   * @param string $exec_type
192
+   * 
181
    * @return collection
193
    * @return collection
182
    */
194
    */
183
-  protected function constructQueryObject(Registry $doctrine, $user_id)
195
+  protected function constructQueryObject(Registry $doctrine, $user_id, $exec_type = 'execute')
184
   {
196
   {
185
     $this->setQuery($doctrine
197
     $this->setQuery($doctrine
186
       ->getRepository('MuzichCoreBundle:Element')
198
       ->getRepository('MuzichCoreBundle:Element')
187
-      ->findBySearch($this, $user_id))
199
+      ->findBySearch($this, $user_id, $exec_type))
188
     ;
200
     ;
189
   }
201
   }
190
   
202
   
192
    * Retourne l'objet Query
204
    * Retourne l'objet Query
193
    * 
205
    * 
194
    * @param Registry $doctrine
206
    * @param Registry $doctrine
207
+   * @param int $user_id
208
+   * @param string $exec_type
209
+   * 
195
    * @return collection
210
    * @return collection
196
    */
211
    */
197
-  public function getQuery(Registry $doctrine, $user_id)
212
+  public function getQuery(Registry $doctrine, $user_id, $exec_type = 'execute')
198
   {
213
   {
199
-    if (!$this->query)
200
-    {
201
-      $this->constructQueryObject($doctrine, $user_id);
202
-    }
214
+    $this->constructQueryObject($doctrine, $user_id, $exec_type);
203
     return $this->query;
215
     return $this->query;
204
   }
216
   }
205
 
217
 
209
    * 
221
    * 
210
    * @param Registry $doctrine
222
    * @param Registry $doctrine
211
    * @param int $user_id
223
    * @param int $user_id
224
+   * @param string $exec_type Type d'execution
225
+   * 
212
    * @return collection
226
    * @return collection
213
    */
227
    */
214
   public function getElements(Registry $doctrine, $user_id, $exec_type = 'execute')
228
   public function getElements(Registry $doctrine, $user_id, $exec_type = 'execute')
215
   {
229
   {
216
-    $query = $this->getQuery($doctrine, $user_id);
230
+    $query = $this->getQuery($doctrine, $user_id, $exec_type);
217
     
231
     
218
     switch ($exec_type)
232
     switch ($exec_type)
219
     {
233
     {
221
         return $query->execute();
235
         return $query->execute();
222
       break;
236
       break;
223
     
237
     
238
+      case 'count':
239
+        return count($query->getArrayResult());
240
+      break;
241
+    
224
       default :
242
       default :
225
         throw new \Exception('Mode de récupération des Elements non supporté.');
243
         throw new \Exception('Mode de récupération des Elements non supporté.');
226
       break;
244
       break;
227
     }
245
     }
228
   }
246
   }
229
   
247
   
248
+  public function isSearchingNew()
249
+  {
250
+    return $this->searchnew;
251
+  }
252
+  
230
 }
253
 }

+ 1 - 1
src/Muzich/CoreBundle/Searcher/Searcher.php 查看文件

49
     $this->query = $query;
49
     $this->query = $query;
50
   }
50
   }
51
 
51
 
52
-  public function getQuery(Registry $doctrine, $user_id)
52
+  public function getQuery(Registry $doctrine, $user_id, $exec_type)
53
   {
53
   {
54
     return $this->query;
54
     return $this->query;
55
   }
55
   }

+ 6 - 1
src/Muzich/CoreBundle/lib/Controller.php 查看文件

40
   }
40
   }
41
   
41
   
42
   /**
42
   /**
43
-   * Retourn l'objet ElementSearcher en cours.
43
+   * @desc Retourn l'objet ElementSearcher en cours.
44
+   * 
45
+   * @param int $count Si renseigné impact le nombre d'éléments qui seront 
46
+   * récupérés
47
+   * @param boolean $force_new Si a vrai la méthode procéède comme si on 
48
+   * demandé un nouveau objet de recherche (basé sur les tags favoris donc).
44
    * 
49
    * 
45
    * @return  ElementSearcher
50
    * @return  ElementSearcher
46
    */
51
    */

+ 8 - 0
src/Muzich/HomeBundle/Resources/views/Home/index.html.twig 查看文件

37
     <input class="main button" type="submit" value="{{ 'filter.submit'|trans({}, 'userui') }}"/>
37
     <input class="main button" type="submit" value="{{ 'filter.submit'|trans({}, 'userui') }}"/>
38
   </form>
38
   </form>
39
 
39
 
40
+  <div class="display_more_elements" style="display: none;">
41
+    <span></span>
42
+  </div>
43
+
44
+  <div class="elements_loader_div">
45
+    <img class="elements_new_loader" style="display: none;" src="{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}" alt="loading" />
46
+  </div>
47
+
40
   {% include "MuzichCoreBundle:SearchElement:default.html.twig" with {'noelements_filter' : true }%}
48
   {% include "MuzichCoreBundle:SearchElement:default.html.twig" with {'noelements_filter' : true }%}
41
     
49
     
42
   <div class="elements_loader_div">
50
   <div class="elements_loader_div">

+ 6 - 0
web/bundles/muzichcore/css/main.css 查看文件

914
 #container a.element_edit_link
914
 #container a.element_edit_link
915
 {
915
 {
916
   text-decoration: none;
916
   text-decoration: none;
917
+}
918
+
919
+div.display_more_elements
920
+{
921
+  background-color: #D9F7FF;
922
+  text-align: center;
917
 }
923
 }

+ 83 - 0
web/bundles/muzichcore/js/muzich.js 查看文件

1029
         $('form[name="search"]').slideDown();
1029
         $('form[name="search"]').slideDown();
1030
       }
1030
       }
1031
       remove_tags('add');
1031
       remove_tags('add');
1032
+      recolorize_element_list();
1032
     }
1033
     }
1033
     else if (response.status == 'error')
1034
     else if (response.status == 'error')
1034
     {
1035
     {
1154
     
1155
     
1155
     return null;
1156
     return null;
1156
   }
1157
   }
1158
+  
1159
+  ////////////////////////////////////////
1160
+  /// Gestion de nouveaux éléments
1161
+  
1162
+  function check_new_elements()
1163
+  {
1164
+    var url = url_element_new_count
1165
+      +'/'
1166
+      +str_replace('element_', '', $('ul.elements li:first').attr('id'))
1167
+    ;
1168
+    $.getJSON(url, function(response){
1169
+      
1170
+      if (response.status == 'mustbeconnected')
1171
+      {
1172
+        $(location).attr('href', url_index);
1173
+      }
1174
+      
1175
+      if (response.status == 'success' && response.count)
1176
+      {
1177
+        $('div.display_more_elements').show();
1178
+        $('div.display_more_elements span').html(response.message);
1179
+      }
1180
+      
1181
+      setTimeout(check_new_elements, 300000);
1182
+    });
1183
+  }
1184
+  
1185
+  if ($('div.display_more_elements').length)
1186
+  {
1187
+    setTimeout(check_new_elements, 300000);
1188
+  }
1189
+  
1190
+  $('a.show_new_elements').live('click', function(){
1191
+    var url = url_element_new_get
1192
+      +'/'
1193
+      +str_replace('element_', '', $('ul.elements li:first').attr('id'))
1194
+    ;
1195
+    $('img.elements_new_loader').show();
1196
+    $.getJSON(url, function(response){
1197
+      
1198
+      if (response.status == 'mustbeconnected')
1199
+      {
1200
+        $(location).attr('href', url_index);
1201
+      }
1202
+      
1203
+      if (response.status == 'success')
1204
+      {
1205
+        if (response.count)
1206
+        {
1207
+          $('div.display_more_elements').show();
1208
+          $('div.display_more_elements span').html(response.message);
1209
+        }
1210
+        else
1211
+        {
1212
+          $('div.display_more_elements').hide();
1213
+        }
1214
+        
1215
+        $('ul.elements').prepend(response.html);
1216
+        recolorize_element_list();
1217
+      }
1218
+      
1219
+      $('img.elements_new_loader').hide();
1220
+    });
1221
+  });
1222
+
1223
+  function recolorize_element_list()
1224
+  {
1225
+    $('ul.elements li.element').each(function(index){
1226
+      if ((index & 1) == 1)
1227
+      {
1228
+        $(this).removeClass('even');
1229
+        $(this).removeClass('odd');
1230
+        $(this).addClass('odd');
1231
+      }
1232
+      else
1233
+      {
1234
+        $(this).removeClass('odd');
1235
+        $(this).removeClass('even');
1236
+        $(this).addClass('even');
1237
+      }
1238
+    });
1239
+  }
1157
    
1240
    
1158
  });
1241
  });