Sfoglia il codice sorgente

Evolution #164: Proposition de tag sur un élément

bastien 13 anni fa
parent
commit
1fe8c78c64

+ 7 - 0
app/Resources/translations/elements.fr.yml Vedi File

@@ -60,6 +60,13 @@ element:
60 60
       submit:           Proposer ces tags
61 61
       cancel:           Annuler
62 62
       description:      Proposez ci-dessous les tags que vous trouvez les plus appropriés pour ce partage
63
+  view_propositions:
64
+    link:               Voir les propositions de tags
65
+    description_one:    Un utilisateur vous propose cette configuration de tags
66
+    description_x:      Des utilisateurs vous propose ces configurations de tags
67
+    link_accept:        Accepter cette proposition
68
+    link_refuse_one:    Refuser les propositions
69
+    link_refuse_x:      Refuser les propositions
63 70
   
64 71
 comment:
65 72
   edit:

+ 137 - 9
src/Muzich/CoreBundle/Controller/ElementController.php Vedi File

@@ -529,15 +529,12 @@ class ElementController extends Controller
529 529
       'search_tags' => $search_tags
530 530
     ));
531 531
     
532
-    if ($this->getRequest()->isXmlHttpRequest())
533
-    {
534
-      return $this->jsonResponse(array(
535
-        'status'    => 'success',
536
-        'form_name' => 'element_tag_proposition_'.$element->getId(),
537
-        'tags'      => $search_tags,
538
-        'html'      => $response->getContent()
539
-      ));
540
-    }
532
+    return $this->jsonResponse(array(
533
+      'status'    => 'success',
534
+      'form_name' => 'element_tag_proposition_'.$element->getId(),
535
+      'tags'      => $search_tags,
536
+      'html'      => $response->getContent()
537
+    ));
541 538
   }
542 539
   
543 540
   public function proposeTagsProceedAction($element_id, $token)
@@ -608,4 +605,135 @@ class ElementController extends Controller
608 605
     ));
609 606
   }
610 607
   
608
+  public function proposedTagsViewAction($element_id)
609
+  {
610
+    if (($response = $this->mustBeConnected(true)))
611
+    {
612
+      return $response;
613
+    }
614
+    
615
+    if (!($element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
616
+      ->findOneById($element_id)))
617
+    {
618
+      return $this->jsonResponse(array(
619
+        'status' => 'error',
620
+        'errors' => array('NotFound')
621
+      ));
622
+    }
623
+    
624
+    if ($element->getOwner()->getId() != $this->getUserId())
625
+    {
626
+      return $this->jsonResponse(array(
627
+        'status' => 'error',
628
+        'errors' => array('NotAllowed')
629
+      ));
630
+    }
631
+    
632
+    // On récupére toute les propsotions pour cet élément
633
+    $propositions = $this->getDoctrine()->getEntityManager()->getRepository('MuzichCoreBundle:ElementTagsProposition')
634
+      ->findByElement($element->getId())
635
+    ;
636
+    
637
+    $response = $this->render('MuzichCoreBundle:Element:tag.propositions.html.twig', array(
638
+      'propositions' => $propositions,
639
+      'element_id'   => $element->getId()
640
+    ));
641
+    
642
+    return $this->jsonResponse(array(
643
+      'status'    => 'success',
644
+      'html'      => $response->getContent()
645
+    ));
646
+    
647
+  }
648
+  
649
+  public function proposedTagsAcceptAction($proposition_id, $token)
650
+  {
651
+    if (($response = $this->mustBeConnected(true)))
652
+    {
653
+      return $response;
654
+    }
655
+    
656
+    if (!($proposition = $this->getDoctrine()->getRepository('MuzichCoreBundle:ElementTagsProposition')
657
+      ->findOneById($proposition_id)) || $token != $this->getUser()->getPersonalHash())
658
+    {
659
+      return $this->jsonResponse(array(
660
+        'status' => 'error',
661
+        'errors' => array('NotFound')
662
+      ));
663
+    }
664
+    
665
+    // On commence par appliquer les nouveaux tags a l'élément
666
+    $element = $proposition->getElement();
667
+    $element->setTags(null);
668
+    foreach ($proposition->getTags() as $tag)
669
+    {
670
+      $element->addTag($tag);
671
+    }
672
+    $element->setHasTagProposition(false);
673
+    $this->getDoctrine()->getEntityManager()->persist($element);
674
+    
675
+    $propositions = $this->getDoctrine()->getEntityManager()->getRepository('MuzichCoreBundle:ElementTagsProposition')
676
+      ->findByElement($element->getId())
677
+    ;
678
+    
679
+    /*
680
+     * TODO: ARCHIVAGE (c avant ou aprés event déjà ?) (cf doc), notifs (event)
681
+     */
682
+    
683
+    // On supprime les proposition liés a cet élement
684
+    foreach ($propositions as $proposition)
685
+    {
686
+      $this->getDoctrine()->getEntityManager()->remove($proposition);
687
+    }
688
+    
689
+    $this->getDoctrine()->getEntityManager()->flush();
690
+    $element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
691
+      ->findOneById($element->getId())
692
+    ;
693
+    
694
+    // On récupère l'html de l'élément
695
+    $html = $this->render('MuzichCoreBundle:SearchElement:element.html.twig', array(
696
+      'element'     => $element
697
+    ))->getContent();
698
+    
699
+    return $this->jsonResponse(array(
700
+      'status' => 'success',
701
+      'html'   => $html
702
+    ));
703
+  }
704
+  
705
+  public function proposedTagsRefuseAction($element_id, $token)
706
+  {
707
+    if (($response = $this->mustBeConnected(true)))
708
+    {
709
+      return $response;
710
+    }
711
+    
712
+    if (!($element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
713
+      ->findOneById($element_id)) || $token != $this->getUser()->getPersonalHash())
714
+    {
715
+      return $this->jsonResponse(array(
716
+        'status' => 'error',
717
+        'errors' => array('NotFound')
718
+      ));
719
+    }
720
+    
721
+    // On supprime les proposition liés a cet élement
722
+    $propositions = $this->getDoctrine()->getEntityManager()->getRepository('MuzichCoreBundle:ElementTagsProposition')
723
+      ->findByElement($element->getId())
724
+    ;
725
+    foreach ($propositions as $proposition)
726
+    {
727
+      $this->getDoctrine()->getEntityManager()->remove($proposition);
728
+    }
729
+    // On spécifie qu'il n'y as plus de proposition
730
+    $element->setHasTagProposition(false);
731
+    $this->getDoctrine()->getEntityManager()->persist($element);
732
+    $this->getDoctrine()->getEntityManager()->flush();
733
+    
734
+    return $this->jsonResponse(array(
735
+      'status' => 'success'
736
+    ));
737
+  }
738
+  
611 739
 }

+ 1 - 1
src/Muzich/CoreBundle/Entity/ElementTagsProposition.php Vedi File

@@ -13,7 +13,7 @@ use Muzich\CoreBundle\Validator as MuzichAssert;
13 13
  * 
14 14
  * @ORM\Entity
15 15
  * @ORM\Table(name="element_tags_proposition")
16
- * @ORM\Entity(repositoryClass="Muzich\CoreBundle\Repository\ElementTagsProposition")
16
+ * @ORM\Entity(repositoryClass="Muzich\CoreBundle\Repository\ElementTagsPropositionRepository")
17 17
  * 
18 18
  */
19 19
 class ElementTagsProposition

+ 25 - 1
src/Muzich/CoreBundle/Repository/ElementTagsPropositionRepository.php Vedi File

@@ -6,5 +6,29 @@ use Doctrine\ORM\EntityRepository;
6 6
 
7 7
 class ElementTagsPropositionRepository extends EntityRepository
8 8
 {
9
-    
9
+  
10
+  public function findByElement($element_id)
11
+  {
12
+    return $this->getEntityManager()
13
+      ->createQuery('SELECT p FROM MuzichCoreBundle:ElementTagsProposition p 
14
+        JOIN p.user u
15
+        JOIN p.tags t
16
+        WHERE p.element = :eid')
17
+      ->setParameter('eid', $element_id)
18
+      ->getResult()
19
+    ;
20
+  }
21
+  
22
+  public function findOneById($id)
23
+  {
24
+    return $this->getEntityManager()
25
+      ->createQuery('SELECT p FROM MuzichCoreBundle:ElementTagsProposition p 
26
+        JOIN p.element e
27
+        JOIN p.tags t
28
+        WHERE p.id = :id')
29
+      ->setParameter('id', $id)
30
+      ->getSingleResult()
31
+    ;
32
+  }
33
+  
10 34
 }

+ 13 - 1
src/Muzich/CoreBundle/Resources/config/routing.yml Vedi File

@@ -120,4 +120,16 @@ ajax_element_propose_tags_open:
120 120
   
121 121
 ajax_element_propose_tags_proceed:
122 122
   pattern: /ajax/element/propose/tags/{element_id}/proceed/{token}
123
-  defaults: { _controller: MuzichCoreBundle:Element:proposeTagsProceed }
123
+  defaults: { _controller: MuzichCoreBundle:Element:proposeTagsProceed }
124
+  
125
+ajax_element_proposed_tags_view:
126
+  pattern: /ajax/element/proposed/tags/{element_id}/view
127
+  defaults: { _controller: MuzichCoreBundle:Element:proposedTagsView }
128
+  
129
+ajax_element_proposed_tags_accept:
130
+  pattern: /ajax/element/proposed/tags/accept/{proposition_id}/{token}
131
+  defaults: { _controller: MuzichCoreBundle:Element:proposedTagsAccept }
132
+  
133
+ajax_element_proposed_tags_refuse:
134
+  pattern: /ajax/element/proposed/tags/refuses/{element_id}/{token}
135
+  defaults: { _controller: MuzichCoreBundle:Element:proposedTagsRefuse }

+ 40 - 0
src/Muzich/CoreBundle/Resources/views/Element/tag.propositions.html.twig Vedi File

@@ -0,0 +1,40 @@
1
+<div class="tags_proposition_view">
2
+
3
+  <p>
4
+    {% if propositions|length > 1 %}
5
+      {{ 'element.view_propositions.description_x'|trans({}, 'elements') }}
6
+    {% else %}
7
+      {{ 'element.view_propositions.description_one'|trans({}, 'elements') }}
8
+    {% endif %}
9
+  </p>
10
+  
11
+  <ul class="tag_propositions">
12
+    {% for proposition in propositions %} 
13
+      <li class="tag_proposition">
14
+        <a href="{{ path('show_user', {'slug': proposition.user.slug}) }}" >
15
+          {{ proposition.user.name }}
16
+        </a>:
17
+        
18
+        {% for tag in proposition.tags %} 
19
+          <span class="button">{{ tag.name }}</span>
20
+        {% endfor %}
21
+          
22
+          <a class="accept_tag_propotision button button_green" href="{{ path('ajax_element_proposed_tags_accept', {'proposition_id':proposition.id,'token':app.user.getPersonalHash}) }}">
23
+            {{ 'element.view_propositions.link_accept'|trans({}, 'elements') }}
24
+          </a>
25
+          
26
+      </li>
27
+    {% endfor %}
28
+  </ul>
29
+  
30
+  {% if propositions|length > 1 %}
31
+    <a class="refuse_tag_propositions button" href="{{ path('ajax_element_proposed_tags_refuse', {'element_id':element_id,'token':app.user.getPersonalHash}) }}" >
32
+      {{ 'element.view_propositions.link_refuse_x'|trans({}, 'elements') }}
33
+    </a>
34
+  {% else %}
35
+    <a class="refuse_tag_propositions button" href="{{ path('ajax_element_proposed_tags_refuse', {'element_id':element_id,'token':app.user.getPersonalHash}) }}" >
36
+      {{ 'element.view_propositions.link_refuse_one'|trans({}, 'elements') }}
37
+    </a>
38
+  {% endif %}
39
+  
40
+</div>

+ 9 - 0
src/Muzich/CoreBundle/Resources/views/SearchElement/element.html.twig Vedi File

@@ -68,6 +68,15 @@
68 68
       {% endif %}
69 69
       
70 70
       {% if app.user.id == element.owner.id %}
71
+      
72
+        {% if element.hasTagProposition %}
73
+          <a title="{{ 'element.view_propositions.link'|trans({}, 'elements') }}" class="element_view_propositions_link" 
74
+             href="{{ path('ajax_element_proposed_tags_view', {'element_id' : element.id})  }}"
75
+          >
76
+            <img src="{{ asset('bundles/muzichcore/img/1333493527_tag_add.png') }}" alt="tags proposition" />
77
+          </a>
78
+        {% endif %}
79
+      
71 80
         <a title="{{ 'element.edit.link'|trans({}, 'elements') }}" class="element_edit_link" 
72 81
            href="{{ path('element_edit', {'element_id' : element.id})  }}" style="display: none;"
73 82
         >

+ 23 - 0
web/bundles/muzichcore/css/main.css Vedi File

@@ -1174,4 +1174,27 @@ div#events div.follows span
1174 1174
 ul#followers_users li.new
1175 1175
 {
1176 1176
   font-weight: bold;
1177
+}
1178
+
1179
+/*
1180
+*  Proposition de tags
1181
+*/ 
1182
+
1183
+li.tag_proposition span.button
1184
+{
1185
+  font-size: 95%;
1186
+  padding: 2px 4px;
1187
+}
1188
+
1189
+li.tag_proposition:hover
1190
+{
1191
+  background-color: #c0f2ff;
1192
+}
1193
+
1194
+
1195
+/* */
1196
+
1197
+.button_green
1198
+{
1199
+  background-color: #5ae959;
1177 1200
 }

BIN
web/bundles/muzichcore/img/1333493527_tag_add.png Vedi File


+ 84 - 0
web/bundles/muzichcore/js/muzich.js Vedi File

@@ -1779,11 +1779,95 @@ $(document).ready(function(){
1779 1779
   });
1780 1780
   
1781 1781
   // Annulation d'un formulaire de modification d'élément
1782
+  //
1783
+  //  TODO TODO TODO
1784
+  //    ca en dessous la: TODO neuu
1785
+  //
1782 1786
   $('form.edit_element input.cancel_edit').live('click', function(){
1783 1787
     var li = $(this).parent('form').parent('li');
1784 1788
     li.html(elements_edited[li.attr('id')]);
1785 1789
     delete(elements_edited[li.attr('id')]);
1786 1790
   });
1791
+  ///////
1792
+  
1793
+  $('a.element_view_propositions_link').live('click', function(){
1794
+    
1795
+    link = $(this);
1796
+    li = link.parent('td').parent('tr').parent().parent().parent('li.element');
1797
+    
1798
+    li.find('img.element_loader').show();
1799
+    
1800
+    $.getJSON($(this).attr('href'), function(response) {
1801
+      
1802
+      if (response.status == 'mustbeconnected')
1803
+      {
1804
+        $(location).attr('href', url_index);
1805
+      }
1806
+      
1807
+      li.find('img.element_loader').hide();
1808
+      
1809
+      if (response.status == 'success')
1810
+      {
1811
+        table = li.find('table:first');
1812
+        li.find('div.tags_proposition_view').remove();
1813
+        table.after(response.html);
1814
+      }
1815
+    });
1816
+    
1817
+    return false;
1818
+  });
1819
+  
1820
+  $('a.accept_tag_propotision').live('click', function(){
1821
+    
1822
+    link = $(this);
1823
+    li = link.parent('li.tag_proposition').parent('ul.tag_propositions')
1824
+      .parent('div.tags_proposition_view').parent('li.element');
1825
+    
1826
+    li.find('img.element_loader').show();
1827
+    
1828
+    $.getJSON($(this).attr('href'), function(response) {
1829
+      
1830
+      if (response.status == 'mustbeconnected')
1831
+      {
1832
+        $(location).attr('href', url_index);
1833
+      }
1834
+      
1835
+      li.find('img.element_loader').hide();
1836
+      
1837
+      if (response.status == 'success')
1838
+      {
1839
+        li.html(response.html);
1840
+      }
1841
+    });
1842
+    
1843
+    return false;
1844
+  });
1845
+  
1846
+  //
1847
+  $('a.refuse_tag_propositions').live('click', function(){
1848
+    
1849
+    link = $(this);
1850
+    li = link.parent('div.tags_proposition_view').parent('li.element');
1851
+    
1852
+    li.find('img.element_loader').show();
1853
+    
1854
+    $.getJSON($(this).attr('href'), function(response) {
1855
+      
1856
+      if (response.status == 'mustbeconnected')
1857
+      {
1858
+        $(location).attr('href', url_index);
1859
+      }
1860
+      
1861
+      li.find('img.element_loader').hide();
1862
+      
1863
+      if (response.status == 'success')
1864
+      {
1865
+        li.find('div.tags_proposition_view').remove();
1866
+      }
1867
+    });
1868
+    
1869
+    return false;
1870
+  });
1787 1871
   
1788 1872
   /*
1789 1873
    * Proposition de tag sur un élément FIN