Browse Source

Evolution #788: Ajouter un élément a sa playlist

Bastien Sevajol 10 years ago
parent
commit
8d5fa65326
28 changed files with 553 additions and 469 deletions
  1. 18 3
      app/Resources/translations/elements.en.yml
  2. 17 1
      app/Resources/translations/elements.fr.yml
  3. 3 1
      app/Resources/translations/flash.en.yml
  4. 2 0
      app/Resources/translations/flash.fr.yml
  5. 1 0
      app/Resources/translations/users.en.yml
  6. 1 0
      app/Resources/translations/users.fr.yml
  7. 4 2
      src/Muzich/CoreBundle/Controller/ElementController.php
  8. 60 10
      src/Muzich/CoreBundle/Entity/Element.php
  9. 24 0
      src/Muzich/CoreBundle/Form/Playlist/PrivateLinksForm.php
  10. 40 2
      src/Muzich/CoreBundle/Managers/PlaylistManager.php
  11. 19 332
      src/Muzich/CoreBundle/Repository/ElementRepository.php
  12. 1 1
      src/Muzich/CoreBundle/Resources/config/security.yml
  13. 22 0
      src/Muzich/CoreBundle/Resources/public/css/main.css
  14. 15 1
      src/Muzich/CoreBundle/Resources/public/js/muzich.js
  15. 51 41
      src/Muzich/CoreBundle/Resources/views/SearchElement/element.html.twig
  16. 14 1
      src/Muzich/CoreBundle/Searcher/ElementSearcher.php
  17. 10 0
      src/Muzich/CoreBundle/Searcher/ElementSearcherQueryBuilder.php
  18. 0 0
      src/Muzich/CoreBundle/Tests/Controller/ScoreTest.php
  19. 22 1
      src/Muzich/CoreBundle/Twig/Extensions/MyTwigExtension.php
  20. 3 1
      src/Muzich/CoreBundle/lib/Collection/ElementCollectionManager.php
  21. 18 12
      src/Muzich/CoreBundle/lib/Tag.php
  22. 66 0
      src/Muzich/PlaylistBundle/Controller/EditController.php
  23. 4 2
      src/Muzich/PlaylistBundle/Controller/ShowController.php
  24. 15 5
      src/Muzich/PlaylistBundle/Resources/config/routing.yml
  25. 32 0
      src/Muzich/PlaylistBundle/Resources/views/Edit/create.html.twig
  26. 83 53
      src/Muzich/PlaylistBundle/Resources/views/Show/show.html.twig
  27. 8 0
      src/Muzich/PlaylistBundle/Resources/views/Show/user.html.twig
  28. BIN
      web/img/icon_star_2_gray.png

+ 18 - 3
app/Resources/translations/elements.en.yml View File

@@ -142,9 +142,24 @@ playlist:
142 142
   contained:             Music already in playlist
143 143
   not_contained:         Music not already in playlist
144 144
   how_add_element:       |
145
-                          To add music in your playlists you have to use share buttons (at top right).
146
-                          You will choose or create playlist for the music.
145
+                          To add music in your playlists you have to use share buttons 
146
+                          (at top right in shares).
147
+                          You will choose or create playlist to add music in. You can also
148
+                          add private songs in playlists: When you add private songs 
149
+                          (youtube, soundcloud, ...) they are not publish in muzi.ch public network.
150
+                          
147 151
   edit:                  Edit
148 152
   update_submit:         Update
153
+  create_submit:         Create
149 154
   goback:                Back
150
-  edit_title:            Edit "%playlist_name%"
155
+  edit_title:            Edit "%playlist_name%"
156
+  create_title:          New playlist
157
+  add_private_links:     Add "privates" musics
158
+  add_private_links_help: |
159
+                          Add here your musics links (http://youtube... , http://soundcloud..., etc) to add them in
160
+                          the playlist. You can add multiples links (one by line).
161
+  add_private_links_submit: Add these links
162
+  add_private_links_cancel: Cancel
163
+  no_links_added:         No musics added
164
+  links_added:            Musics added
165
+  links_added_witherr:    Musics added but wom links was not useable

+ 17 - 1
app/Resources/translations/elements.fr.yml View File

@@ -143,8 +143,24 @@ playlist:
143 143
   how_add_element:       |
144 144
                           Pour ajouter de la musique à vos listes de lectures vous devez utiliser
145 145
                           les boutons disponibles en haut à droite des partages. Vous pourrez ensuite
146
-                          choisir à quelle liste ajouter la musique en question.
146
+                          choisir à quelle liste ajouter la musique en question. Vous pouvez aussi
147
+                          constituer des playlists avec des liens "privés": C'est à dire que vous 
148
+                          pouvez ajouter des musiques (youtube, soundcloud, ...) afin de constituer 
149
+                          une liste de lecture sans que ces musiques ne soit ajoutés dans le réseau 
150
+                          publique de muzi.ch.
147 151
   edit:                  Modifier
148 152
   update_submit:         Mettre à jour
153
+  create_submit:         Créer
149 154
   goback:                Retour
150 155
   edit_title:            Modification de "%playlist_name%"
156
+  create_title:          Nouvelle liste de lecture
157
+  add_private_links:     Ajouter des musiques "privées"
158
+  add_private_links_help: |
159
+                          Saisissez ici les liens (http://) vers les pages (youtube, soundcloud, etc)
160
+                          des musiques à ajouter a cette liste de lecture. Vous pouvez en saisir
161
+                          plusieurs (une par ligne).
162
+  add_private_links_submit: Ajouter ces liens
163
+  add_private_links_cancel: Annuler
164
+  no_links_added:         Aucune musiques n'ont été ajoutés
165
+  links_added:            Les musiques ont été ajoutés
166
+  links_added_witherr:    Des musiques ont été ajoutés mais certains liens n'ont pu être interprétés

+ 3 - 1
app/Resources/translations/flash.en.yml View File

@@ -50,4 +50,6 @@ playlist:
50 50
   delete:
51 51
     success:       Playlist deleted
52 52
   update:
53
-    success:       Playlist updaded
53
+    success:       Playlist updaded
54
+  create:
55
+    success:       Playlist created

+ 2 - 0
app/Resources/translations/flash.fr.yml View File

@@ -54,3 +54,5 @@ playlist:
54 54
     success:       Playlist supprimée
55 55
   update:
56 56
     success:       La liste de lecture a été mise à jour
57
+  create:
58
+    success:       La liste de lecture a été créée

+ 1 - 0
app/Resources/translations/users.en.yml View File

@@ -7,6 +7,7 @@ user:
7 7
   view_profile:                 See profile
8 8
   stop_follow:                  Stop follow
9 9
   view_playlists:               Playlists
10
+  new_playlist:                 Create new playlist
10 11
   show:
11 12
     title:                      %name% shares
12 13
   reputation:

+ 1 - 0
app/Resources/translations/users.fr.yml View File

@@ -7,6 +7,7 @@ user:
7 7
   view_profile:                 Profil
8 8
   stop_follow:                  Ne plus suivre
9 9
   view_playlists:               Listes de lectures
10
+  new_playlist:                 Créer une nouvelle liste
10 11
   show:
11 12
     title:                      Diffusions de %name%
12 13
   reputation:

+ 4 - 2
src/Muzich/CoreBundle/Controller/ElementController.php View File

@@ -1081,7 +1081,8 @@ class ElementController extends Controller
1081 1081
   {
1082 1082
     $es = new ElementSearcher();
1083 1083
     $es->init(array(
1084
-      'ids' => array($element_id)
1084
+      'ids'              => array($element_id),
1085
+      'display_privates' => true
1085 1086
     ));
1086 1087
     
1087 1088
     if (!($element = $es->getElements($this->getDoctrine(), $this->getUserId(true), 'single')))
@@ -1130,7 +1131,8 @@ class ElementController extends Controller
1130 1131
     // On prépare la récupèration de l'élèment
1131 1132
     $es = new ElementSearcher();
1132 1133
     $es->init(array(
1133
-      'ids' => array($element_id)
1134
+      'ids'              => array($element_id),
1135
+      'display_privates' => true
1134 1136
     ));
1135 1137
     
1136 1138
     if (!($element = $es->getElements($this->getDoctrine(), $this->getUserId(true), 'single')))

+ 60 - 10
src/Muzich/CoreBundle/Entity/Element.php View File

@@ -188,7 +188,7 @@ class Element
188 188
    * 
189 189
    * @ORM\Column(type = "string", length = 128)
190 190
    * @Assert\NotBlank(message = "error.element.name.notblank")
191
-   * @Assert\Length(min = 3, max = 84, minMessage = "error.element.name.toshort", maxMessage = "error.element.name.tolong")
191
+   * @Assert\Length(min = 3, max = 128, minMessage = "error.element.name.toshort", maxMessage = "error.element.name.tolong")
192 192
    * @var type string
193 193
    */
194 194
   protected $name;
@@ -200,6 +200,11 @@ class Element
200 200
   protected $slug;
201 201
   
202 202
   /**
203
+   * @ORM\Column(type="boolean")
204
+   */
205
+  protected $private = false;
206
+  
207
+  /**
203 208
    * Code d'embed
204 209
    * 
205 210
    * @ORM\Column(type="text", nullable=true)
@@ -260,27 +265,18 @@ class Element
260 265
   protected $count_report;
261 266
   
262 267
   /**
263
-<<<<<<< HEAD
264
-<<<<<<< Updated upstream
265
-=======
266
-=======
267
->>>>>>> feature/v0.9.8.2/score
268 268
    * @ORM\Column(type="integer", nullable=true)
269 269
    * @var int 
270 270
    */
271 271
   protected $count_favorited;
272 272
   
273 273
   /**
274
-<<<<<<< HEAD
275 274
    * @ORM\Column(type="integer", nullable=true)
276 275
    * @var int 
277 276
    */
278 277
   protected $count_playlisted;
279 278
   
280 279
   /**
281
->>>>>>> Stashed changes
282
-=======
283
->>>>>>> feature/v0.9.8.2/score
284 280
    * @ORM\Column(type="boolean", nullable=false)
285 281
    * @var int 
286 282
    */
@@ -1129,4 +1125,58 @@ class Element
1129 1125
     $this->setCountPlaylisted($this->getCountPlaylisted()-1);
1130 1126
   }
1131 1127
   
1128
+  public function isPrivate()
1129
+  {
1130
+    return ($this->private)?true:false;
1131
+  }
1132
+  
1133
+  public function getPrivate()
1134
+  {
1135
+    return $this->isPrivate();
1136
+  }
1137
+  
1138
+  public function setPrivate($private)
1139
+  {
1140
+    $this->private = ($private)?true:false;
1141
+  }
1142
+  
1143
+  public function setNameWithData($clean = true)
1144
+  {
1145
+    $name = '';
1146
+    if (($title = $this->getData(self::DATA_TITLE)))
1147
+    {
1148
+      if (($artist = $this->getData(self::DATA_ARTIST)))
1149
+      {
1150
+        $name = $title.' - '.$artist;
1151
+      }
1152
+      else
1153
+      {
1154
+        $name = $title;
1155
+      }
1156
+    }
1157
+    
1158
+    if ($clean)
1159
+    {
1160
+      if (strlen($name) < 3)
1161
+      {
1162
+        try
1163
+        {
1164
+          $str = file_get_contents($this->getUrl());
1165
+          if (strlen($str) > 0)
1166
+          {
1167
+            preg_match("/\<title\>(.*)\<\/title\>/",$str,$title);
1168
+            $name = $title[1];
1169
+          }
1170
+        }
1171
+        catch (\Exception $e)
1172
+        {
1173
+          $name = $this->getUrl();
1174
+        }
1175
+      }
1176
+      $name = substr($name, 0, 128);
1177
+    }
1178
+    
1179
+    $this->setName($name);
1180
+  }
1181
+  
1132 1182
 }

+ 24 - 0
src/Muzich/CoreBundle/Form/Playlist/PrivateLinksForm.php View File

@@ -0,0 +1,24 @@
1
+<?php
2
+
3
+namespace Muzich\CoreBundle\Form\Playlist;
4
+
5
+use Symfony\Component\Form\AbstractType;
6
+use Symfony\Component\Form\FormBuilderInterface;
7
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
8
+
9
+class PrivateLinksForm extends AbstractType
10
+{
11
+  public function buildForm(FormBuilderInterface $builder, array $options)
12
+  {
13
+    $builder->add('links', 'textarea', array(
14
+      'required' => true,
15
+    ));
16
+  }
17
+
18
+  public function getName()
19
+  {
20
+    return 'playlist_private_links_form';
21
+  }
22
+}
23
+
24
+

+ 40 - 2
src/Muzich/CoreBundle/Managers/PlaylistManager.php View File

@@ -9,6 +9,8 @@ use Muzich\CoreBundle\Entity\Element;
9 9
 use Muzich\CoreBundle\Entity\UserPlaylistPicked;
10 10
 use \Doctrine\Common\Collections\ArrayCollection;
11 11
 use Muzich\CoreBundle\lib\Tag as TagLib;
12
+use Muzich\CoreBundle\Managers\ElementManager;
13
+use Symfony\Component\DependencyInjection\Container;
12 14
 
13 15
 class PlaylistManager
14 16
 {
@@ -73,11 +75,11 @@ class PlaylistManager
73 75
     ;
74 76
   }
75 77
   
76
-  public function getPlaylistElements(Playlist $playlist, $offset = null)
78
+  public function getPlaylistElements(Playlist $playlist, $offset = null, $user_id = null)
77 79
   {
78 80
     $element_ids = $playlist->getElementsIds();
79 81
     $query_builder = $this->entity_manager->getRepository('MuzichCoreBundle:Element')
80
-      ->getElementsWithIdsOrderingQueryBuilder($element_ids)
82
+      ->getElementsWithIdsOrderingQueryBuilder($element_ids, true, $user_id)
81 83
     ;
82 84
     
83 85
     if ($offset)
@@ -253,4 +255,40 @@ class PlaylistManager
253 255
       ->findById($playlist->getElementsIds());
254 256
   }
255 257
   
258
+  public function addPrivateLinks(Playlist $playlist, User $user, $links, Container $container)
259
+  {
260
+    // Pour le moment on le fait ici car le ElementManager est mal pensé.
261
+    $count_added = 0;
262
+    if (count($links))
263
+    {
264
+      foreach ($links as $link)
265
+      {
266
+        $link = trim($link);
267
+        if (filter_var($link, FILTER_VALIDATE_URL) !== false)
268
+        {
269
+          $element = new Element();
270
+          $element->setUrl($link);
271
+          $element->setType('none');
272
+          $element->setPrivate(true);
273
+
274
+          $factory = new ElementManager($element, $this->entity_manager, $container);
275
+          $factory->proceedFill($user);
276
+          
277
+          $element->setNameWithData(true);
278
+          
279
+          $this->entity_manager->persist($element);
280
+          $this->entity_manager->flush();
281
+          $this->addElementToPlaylist($element, $playlist);
282
+          
283
+          $count_added += 1;
284
+        }
285
+      }
286
+    }
287
+    
288
+    $this->entity_manager->persist($playlist);
289
+    $this->entity_manager->flush();
290
+    
291
+    return $count_added;
292
+  }
293
+  
256 294
 }

+ 19 - 332
src/Muzich/CoreBundle/Repository/ElementRepository.php View File

@@ -21,6 +21,7 @@ class ElementRepository extends EntityRepository
21 21
     return $this->getEntityManager()
22 22
       ->createQuery('
23 23
         SELECT e FROM MuzichCoreBundle:Element e 
24
+        WHERE e.private = 0
24 25
         ORDER BY e.name ASC'
25 26
       )
26 27
       ->getResult()
@@ -39,7 +40,7 @@ class ElementRepository extends EntityRepository
39 40
         ->createQuery("SELECT e FROM MuzichCoreBundle:Element e WHERE 1 = 2")
40 41
       ;
41 42
     }
42
-     
43
+    
43 44
     $esqb = new ElementSearcherQueryBuilder($this->getEntityManager(), $searcher, $user_id, $params);
44 45
     
45 46
     // Si on demande une comptabilisation, on retourne juste la requete qui selectionne les ids
@@ -52,335 +53,6 @@ class ElementRepository extends EntityRepository
52 53
     return $esqb->getElementsQuery();
53 54
   }
54 55
   
55
-  
56
-  
57
-//  /**
58
-//   * TODO: Faire un bel objet pour gérer tout ça =)
59
-//   * => Utiliser l'objet ElementSearcher (ou du moin réorganiser ça en plusieurs 
60
-//   * objets)
61
-//   * 
62
-//   * 
63
-//   * @param ElementSearcher $searcher
64
-//   * @return Doctrine\ORM\Query
65
-//   */
66
-//  public function findBySearchOLD(ElementSearcher $searcher, $user_id, $exec_type = 'execute', $params = array())
67
-//  {
68
-//    // Tableaux des paramétres
69
-//    $params_ids = array();
70
-//    $params_select = array();
71
-//    $params_select['uid'] = $user_id;
72
-//    $order_by = "ORDER BY e_.created DESC, e_.id DESC";
73
-//    
74
-//    // Première chose, si on impose les element_ids on a pas besoin de faire 
75
-//    // le filtrage
76
-//    if ($searcher->hasIds())
77
-//    {
78
-//      // Dans ce cas ou les ids sont déjà donné, on ne peut pas avoir de nouveaux
79
-//      // éléments
80
-//      if ($searcher->isSearchingNew())
81
-//      {
82
-//        return $query = $this->getEntityManager()
83
-//          ->createQuery("SELECT e FROM MuzichCoreBundle:Element e WHERE 1 = 2")
84
-//        ;
85
-//      }
86
-//      
87
-//      if (($id_limit = $searcher->getIdLimit()))
88
-//      {
89
-//        return $this->getSelectElementForSearchQuery($params_select, $user_id, $searcher->getIds(), $id_limit, $searcher->getCount(), $searcher->getIdsDisplay());
90
-//      }
91
-//      return $this->getSelectElementForSearchQuery($params_select, $user_id, $searcher->getIds(), null, null, $searcher->getIdsDisplay());
92
-//    }
93
-//    
94
-//    // Booléen nous permettant de savoir si un where a déjà été écrit
95
-//    $is_where = false;
96
-//    
97
-//    // Si c'est une recherche string, les autres paramètres ne sont pas nécéssaire
98
-//    // TODO: Dans la nouvelle version ourquoi pas !!
99
-//    // TODOOO: Pas encore dans new version (string)
100
-//    $where_string = '';
101
-//    if (($string = $searcher->getString()))
102
-//    {
103
-//      // On prépare notre liste de mots
104
-//      $words = array_unique(array_merge(
105
-//        explode(' ', $string),
106
-//        explode('-', $string),
107
-//        explode('- ', $string),
108
-//        explode(' -', $string),
109
-//        explode(' - ', $string),
110
-//        explode(',', $string),
111
-//        explode(', ', $string),
112
-//        explode(' ,', $string),
113
-//        explode(' , ', $string)
114
-//      ));
115
-//      
116
-//      // On récupère les ids des elements correspondants
117
-//      $word_min_length = 0;
118
-//      if (isset($params['word_min_length']))
119
-//      {
120
-//        $word_min_length = $params['word_min_length'];
121
-//      }
122
-//      foreach ($words as $i => $word)
123
-//      {
124
-//        if (strlen($word) >= $word_min_length)
125
-//        {
126
-//          if ($where_string === '')
127
-//          {
128
-//            $where_string = ($is_where) ? ' AND (' : ' WHERE (';
129
-//            $is_where = true;
130
-//            $where_string .= "UPPER(e_.name) LIKE :str".$i;
131
-//          }
132
-//          else
133
-//          {
134
-//            $where_string .= " OR UPPER(e_.name) LIKE :str".$i;
135
-//          }
136
-//          $params_ids['str'.$i] = '%'.strtoupper($word).'%';
137
-//        }
138
-//      }
139
-//      $where_string .= ')';
140
-//      
141
-//    }
142
-//    
143
-//    
144
-//    // Construction des conditions pour la selection d'ids
145
-//    $where_tags = '';
146
-//    $join_tags  = '';
147
-//    
148
-//    /*
149
-//     * des fois on se retrouve avec un string au lieu d'un tableau
150
-//     */
151
-//    $tags = $searcher->getTags();
152
-//    
153
-//    if (!is_array($tags))
154
-//    {
155
-//      $tags_decoded = json_decode($tags);
156
-//      $tags = array();
157
-//      foreach ($tags_decoded as $tag_id)
158
-//      {
159
-//        $tags[$tag_id] = $tag_id;
160
-//      }
161
-//    }
162
-//    
163
-//    if (count($tags))
164
-//    {
165
-//      foreach ($tags as $tag_id => $tag_name)
166
-//      {
167
-//        // LEFT JOIN car un element n'est pas obligatoirement lié a un/des tags
168
-//        $join_tags = " LEFT JOIN e_.tags t_";
169
-//
170
-//        // Construction du chere pour les tags
171
-//        if ($where_tags == '')
172
-//        {
173
-//          $where_tags .= ' WHERE (t_.id = :tid'.$tag_id;
174
-//        }
175
-//        else
176
-//        {
177
-//          $where_tags .= ' OR t_.id = :tid'.$tag_id;
178
-//        }
179
-//        $params_ids['tid'.$tag_id] = $tag_id;
180
-//      }
181
-//      // Fermeture de la parenthése qui isole la condition des tags
182
-//      $where_tags .= ')';
183
-//      $is_where = true;
184
-//    }
185
-//    
186
-//    // Construction de la condition network
187
-//    $join_network  = '';
188
-//    $where_network = '';
189
-//    if ($searcher->getNetwork() == ElementSearcher::NETWORK_PERSONAL)
190
-//    {
191
-//      $join_network = 
192
-//        " JOIN e_.owner o_"
193
-//      // LEFT JOIN car l'element n'est pas obligatoirement lié a un groupe
194
-//      . " LEFT JOIN e_.group g_"
195
-//      // LEFT JOIN car owner n'est pas obligatoirement lié a des followers
196
-//      . " LEFT JOIN o_.followers_users f_"
197
-//      // LEFT JOIN car le groupe n'est pas obligatoirement lié a des followers
198
-//      . " LEFT JOIN g_.followers gf_"
199
-//      ;
200
-//      $where_network = ($is_where) ? ' AND' : ' WHERE';
201
-//      $is_where = true;
202
-//      // Le filtre applique: Soit le proprio fait partis des followeds de l'utilisateur
203
-//      // soit l'element est ajouté dans un groupe que l'utilisateur follow.
204
-//      $where_network .= ' (f_.follower = :userid OR gf_.follower = :useridg)';
205
-//      $params_ids['userid'] = $user_id;
206
-//      $params_ids['useridg'] = $user_id;
207
-//    }
208
-//    
209
-//    // ajout du filtre sur un user si c'est le cas
210
-//    $where_user = '';
211
-//    //                                                  Si c'est une recherche 
212
-//    //                de favoris, on ne filtre pas sur le proprio de l'element
213
-//    if (($search_user_id = $searcher->getUserId()) && !$searcher->isFavorite())
214
-//    {
215
-//      $where_user = ($is_where) ? ' AND' : ' WHERE';
216
-//      $is_where = true;
217
-//      $where_user .= ' e_.owner = :suid';
218
-//      $params_ids['suid'] = $search_user_id;
219
-//    }
220
-//    
221
-//    // ajout du filtre sur un user si c'est le cas
222
-//    $where_group = '';
223
-//    //                                                 Si c'est une recherche 
224
-//    //               de favoris, on ne filtre pas sur le proprio de l'element
225
-//    if (($search_group_id = $searcher->getGroupId()) && !$searcher->isFavorite())
226
-//    {
227
-//      $where_group = ($is_where) ? ' AND' : ' WHERE';
228
-//      $is_where = true;
229
-//      $where_group .= ' e_.group = :sgid';
230
-//      $params_ids['sgid'] = $search_group_id;
231
-//    }
232
-//    
233
-//    // Filtre pour afficher uniquement les elements mis en favoris
234
-//    $join_favorite = ''; 
235
-//    $where_favorite = '';
236
-//    if ($searcher->isFavorite())
237
-//    {
238
-//      $where_favorite = ($is_where) ? ' AND' : ' WHERE';
239
-//      $is_where = true;
240
-//      if (($favorite_user_id = $searcher->getUserId()) && !$searcher->getGroupId())
241
-//      {
242
-//        // Pas de LEFT JOIN car on ne veut que les elements mis en favoris
243
-//        $join_favorite = 'JOIN e_.elements_favorites fav2_';
244
-//        $where_favorite .= ' fav2_.user = :fuid';
245
-//        $params_ids['fuid'] = $favorite_user_id;
246
-//      }
247
-//      else if (($favorite_group_id = $searcher->getGroupId()) && !$searcher->getUserId())
248
-//      {
249
-//        // TODO: Faire en sorte que ça affiche les favoris des gens suivant
250
-//        // le groupe
251
-//      }
252
-//      else
253
-//      {
254
-//        throw new Exception('For use favorite search element, you must specify an user_id or group_id');
255
-//      }
256
-//    }
257
-//    
258
-//    // Si id_limit est précisé c'est que l'on demande "la suite" ou "les nouveaux"
259
-//    $where_id_limit = '';
260
-//    if (($id_limit = $searcher->getIdLimit()) && !$searcher->isSearchingNew())
261
-//    {
262
-//      $where_id_limit = ($is_where) ? ' AND' : ' WHERE';
263
-//      $is_where = true;
264
-//      $where_id_limit .= " e_.id < :id_limit";
265
-//      $params_ids['id_limit'] = $id_limit;
266
-//    }
267
-//    elseif ($id_limit && $searcher->isSearchingNew())
268
-//    {
269
-//      $where_id_limit = ($is_where) ? ' AND' : ' WHERE';
270
-//      $is_where = true;
271
-//      $where_id_limit .= " e_.id > :id_limit";
272
-//      $params_ids['id_limit'] = $id_limit;
273
-//      // Pour pouvoir charger les x nouveaux on doit organiser la liste 
274
-//      // de manière croissante
275
-//      $order_by = "ORDER BY e_.created ASC, e_.id ASC";
276
-//    }
277
-//    
278
-//    
279
-//    // Recherche strict ou non ?
280
-//    $where_tag_strict = '';
281
-//    if ($searcher->getTagStrict() && count($tags))
282
-//    {
283
-//      // On a besoin de récupérer la liste des element_id qui ont les tags
284
-//      // demandés.
285
-//      $tag_ids = '';
286
-//      foreach ($tags as $tag_id => $tag_name)
287
-//      {
288
-//        if ($tag_ids === '')
289
-//        {
290
-//          $tag_ids .= (int)$tag_id;
291
-//        }
292
-//        else
293
-//        {
294
-//          $tag_ids .= ','.(int)$tag_id;
295
-//        }
296
-//      }
297
-//      
298
-//      $sql = "SELECT et.element_id FROM elements_tag et "
299
-//      ."WHERE et.tag_id IN ($tag_ids) group by et.element_id "
300
-//      ."having count(distinct et.tag_id) = ".count($tags);
301
-//      $rsm = new \Doctrine\ORM\Query\ResultSetMapping;
302
-//      $rsm->addScalarResult('element_id', 'element_id');
303
-//      
304
-//      $strict_element_ids_result = $this->getEntityManager()
305
-//        ->createNativeQuery($sql, $rsm)
306
-//        //->setParameter('ids', $tag_ids)
307
-//        ->getScalarResult()
308
-//      ;
309
-//      
310
-//      $strict_element_ids = array();
311
-//      foreach ($strict_element_ids_result as $strict_id)
312
-//      {
313
-//        $strict_element_ids[] = $strict_id['element_id'];
314
-//      }
315
-//      
316
-//      if (count($strict_element_ids))
317
-//      {
318
-//        $where_tag_strict = ($is_where) ? ' AND' : ' WHERE';
319
-//        $where_tag_strict .= ' e_.id IN (:tag_strict_ids)';
320
-//        $params_ids['tag_strict_ids'] = $strict_element_ids;
321
-//      }
322
-//      // Ce else palie au bug du au cas ou $strict_element_ids est egal a array();
323
-//      else
324
-//      {
325
-//        $where_tag_strict = ($is_where) ? ' AND' : ' WHERE';
326
-//        $where_tag_strict .= ' 1 = 2';
327
-//      }
328
-//    }
329
-//    
330
-//    // Requête qui selectionnera les ids en fonction des critéres
331
-//    $id_query = $this->getEntityManager()
332
-//      ->createQuery(
333
-//        "SELECT e_.id
334
-//        FROM MuzichCoreBundle:Element e_
335
-//        $join_tags
336
-//        $join_network
337
-//        $join_favorite
338
-//        $where_tags
339
-//        $where_network
340
-//        $where_user
341
-//        $where_group
342
-//        $where_favorite
343
-//        $where_tag_strict
344
-//        $where_string
345
-//        $where_id_limit
346
-//        GROUP BY e_.id
347
-//        $order_by")
348
-//     ->setParameters($params_ids)
349
-//    ;
350
-//    
351
-//    // Si on a précisé que l'on voulait un count, pas de limite
352
-//    if ($exec_type != 'count')
353
-//    {
354
-//      $id_query->setMaxResults($searcher->getCount());
355
-//    }
356
-//    
357
-//    // si l'on a demandé un count
358
-//    if ($exec_type == 'count')
359
-//    {
360
-//      // On retourne cette query
361
-//      return $id_query;
362
-//    }
363
-//    
364
-//    $r_ids = $id_query->getArrayResult();
365
-//    
366
-//    $ids = array();
367
-//    
368
-//    if (count($r_ids))
369
-//    {
370
-//      foreach ($r_ids as $r_id)
371
-//      {
372
-//        $ids[] = $r_id['id'];
373
-//      }
374
-//
375
-//      return $this->getSelectElementForSearchQuery($params_select, $user_id, $ids);
376
-//    }
377
-//    
378
-//    // Il faut retourner une Query
379
-//    return $query = $this->getEntityManager()
380
-//      ->createQuery("SELECT e FROM MuzichCoreBundle:Element e WHERE 1 = 2")
381
-//    ;
382
-//  }
383
-  
384 56
   protected function getSelectElementForSearchQuery($params_select, $user_id, $ids, $id_limit = null, $count_limit = null, $ids_display = null)
385 57
   {
386 58
     $where = "";
@@ -408,6 +80,7 @@ class ElementRepository extends EntityRepository
408 80
       $left_join
409 81
       JOIN e.owner o
410 82
       WHERE e.id IN (:ids) $where
83
+      AND WHERE e.private = 0
411 84
       ORDER BY e.created DESC, e.id DESC"
412 85
     ;
413 86
 
@@ -443,6 +116,7 @@ class ElementRepository extends EntityRepository
443 116
         JOIN e.group g
444 117
         JOIN e.tags t
445 118
         WHERE u.id = :uid
119
+        AND WHERE e.private = 0
446 120
         ORDER BY e.created DESC'
447 121
       )
448 122
       ->setParameter('uid', $user_id)
@@ -467,6 +141,7 @@ class ElementRepository extends EntityRepository
467 141
         JOIN e.group g
468 142
         JOIN e.tags t
469 143
         WHERE g.id = :gid
144
+        AND WHERE e.private = 0
470 145
         ORDER BY e.created DESC'
471 146
       )
472 147
       ->setParameter('gid', $group_id)
@@ -513,20 +188,32 @@ class ElementRepository extends EntityRepository
513 188
   /**
514 189
    * WARNING: Seulement compatibel avec MySQL !!
515 190
    */
516
-  public function getElementsWithIdsOrderingQueryBuilder($element_ids)
191
+  public function getElementsWithIdsOrderingQueryBuilder($element_ids, $show_privates = false, $user_id = true)
517 192
   {
518 193
     $doctrineConfig = $this->getEntityManager()->getConfiguration();
519 194
     $doctrineConfig->addCustomStringFunction('FIELD', 'Muzich\CoreBundle\DoctrineExtensions\Query\Mysql\Field');
520 195
     
521 196
     if (count($element_ids))
522 197
     {
523
-      return $this->getEntityManager()->createQueryBuilder()
198
+      $qb =  $this->getEntityManager()->createQueryBuilder()
524 199
         ->select('e, field(e.id, ' . implode(', ', $element_ids) . ') as HIDDEN field')
525 200
         ->from('MuzichCoreBundle:Element', 'e')
526 201
         ->where('e.id IN (:element_ids)')
527 202
         ->setParameter('element_ids', $element_ids)
528 203
         ->orderBy('field')
529 204
       ;
205
+      
206
+      if (!$show_privates)
207
+      {
208
+        $qb->andWhere('e.private = 0');
209
+      }
210
+      else if ($user_id)
211
+      {
212
+        $qb->andWhere('(e.private = 0 OR (e.private = 1 AND e.owner = :owner_id))');
213
+        $qb->setParameter('owner_id', $user_id);
214
+      }
215
+      
216
+      return $qb;
530 217
     }
531 218
     
532 219
     return $this->getEntityManager()->createQueryBuilder()

+ 1 - 1
src/Muzich/CoreBundle/Resources/config/security.yml View File

@@ -109,7 +109,7 @@ security:
109 109
         - { path: ^/(?:fr|en)/user, role: IS_AUTHENTICATED_ANONYMOUSLY }
110 110
         - { path: ^/(?:fr|en)/group, role: IS_AUTHENTICATED_ANONYMOUSLY }
111 111
         - { path: ^/(?:fr|en)/search, role: IS_AUTHENTICATED_ANONYMOUSLY }
112
-        - { path: ^/(?:fr|en)/playlist, role: IS_AUTHENTICATED_ANONYMOUSLY }
112
+        #- { path: ^/(?:fr|en)/playlist, role: IS_AUTHENTICATED_ANONYMOUSLY }
113 113
         - { path: ^/(?:fr|en)/my-groups/add, role: IS_AUTHENTICATED_ANONYMOUSLY }  
114 114
         - { path: ^/(?:fr|en)/song, role: IS_AUTHENTICATED_ANONYMOUSLY }                  
115 115
           

+ 22 - 0
src/Muzich/CoreBundle/Resources/public/css/main.css View File

@@ -2533,6 +2533,28 @@ div.social_buttons ul li.googleplus {
2533 2533
     margin-left: -25px;
2534 2534
 }
2535 2535
 
2536
+a.button.toplist:visited
2537
+{
2538
+  color: white;
2539
+}
2540
+
2541
+a.button.toplist
2542
+{
2543
+  float: right;
2544
+}
2545
+
2546
+div.private_links form div.inputs
2547
+{
2548
+  float: right;
2549
+}
2550
+
2551
+div.private_links textarea
2552
+{
2553
+  height: 60px;
2554
+  width: 435px;
2555
+}
2556
+
2557
+
2536 2558
 /*
2537 2559
 *
2538 2560
 *

+ 15 - 1
src/Muzich/CoreBundle/Resources/public/js/muzich.js View File

@@ -1328,7 +1328,7 @@ $(document).ready(function(){
1328 1328
         elements.prepend(response.html);
1329 1329
         $('div#share_from_content').append(elements);
1330 1330
         $('div#share_from_message').text(response.message);
1331
-        //$('form[name="add"]').append($('<input type="hidden" name="shared_from_finished" id="shared_from_finished" value="1" />'));
1331
+        $('form[name="add"]').append($('<input type="hidden" name="shared_from_finished" id="shared_from_finished" value="1" />'));
1332 1332
       }
1333 1333
       
1334 1334
       return true;
@@ -3370,6 +3370,20 @@ $(document).ready(function(){
3370 3370
     window.sidebar_topsticked = true;
3371 3371
   }
3372 3372
   
3373
+  /*
3374
+   * Playlist private links lien privés
3375
+   * 
3376
+   */
3377
+  
3378
+  $('a.open_playlist_private_links').click(function(){
3379
+    $('div.private_links').slideDown();
3380
+  });
3381
+  
3382
+  $('div.private_links input.cancel').click(function(){
3383
+    $('div.private_links').slideUp();
3384
+  });
3385
+  
3386
+  
3373 3387
 });
3374 3388
 
3375 3389
 function open_ajax_popin(url, callback, data)

+ 51 - 41
src/Muzich/CoreBundle/Resources/views/SearchElement/element.html.twig View File

@@ -1,6 +1,9 @@
1 1
 {% if display_edit_actions is not defined %}
2 2
   {% set display_edit_actions = true %}
3 3
 {% endif %}
4
+{% if display_social_buttons is not defined %}
5
+  {% set display_social_buttons = true %}
6
+{% endif %}
4 7
 {% if display_player is not defined %}
5 8
   {% set display_player = true %}
6 9
 {% endif %}
@@ -86,20 +89,24 @@
86 89
               {% endif %}
87 90
             </li>
88 91
         <li class="star">
89
-          {% if app.user %}
90
-            {% if element.hasFavoriteUser(app.user.id) %}
91
-              <a class="favorite_link" href="{{ path('favorite_remove', { 'id': element.id, 'token': app.user.personalHash(element.id) }) }}" >
92
-                <img id="favorite_{{ element.id }}_is" src="{{ asset('img/icon_star_2_red.png') }}" title="{{ 'element.favorite.remove'|trans({}, 'elements') }}" alt="{{ 'element.favorite.remove'|trans({}, 'elements') }}"/>
93
-              </a>
92
+          {% if not element.private %}
93
+            {% if app.user %}
94
+              {% if element.hasFavoriteUser(app.user.id) %}
95
+                <a class="favorite_link" href="{{ path('favorite_remove', { 'id': element.id, 'token': app.user.personalHash(element.id) }) }}" >
96
+                  <img id="favorite_{{ element.id }}_is" src="{{ asset('img/icon_star_2_red.png') }}" title="{{ 'element.favorite.remove'|trans({}, 'elements') }}" alt="{{ 'element.favorite.remove'|trans({}, 'elements') }}"/>
97
+                </a>
98
+              {% else %}
99
+                <a class="favorite_link" href="{{ path('favorite_add', { 'id': element.id, 'token': app.user.personalHash(element.id) }) }}" >
100
+                  <img id="favorite_{{ element.id }}_isnot" src="{{ asset('img/icon_star_2.png') }}" title="{{ 'element.favorite.add'|trans({}, 'elements') }}" alt="{{ 'element.favorite.add'|trans({}, 'elements') }}" />
101
+                </a>
102
+              {% endif %}
94 103
             {% else %}
95
-              <a class="favorite_link" href="{{ path('favorite_add', { 'id': element.id, 'token': app.user.personalHash(element.id) }) }}" >
96
-                <img id="favorite_{{ element.id }}_isnot" src="{{ asset('img/icon_star_2.png') }}" title="{{ 'element.favorite.add'|trans({}, 'elements') }}" alt="{{ 'element.favorite.add'|trans({}, 'elements') }}" />
104
+              <a class="mustbeconnected" href="#" >
105
+                <img src="{{ asset('img/icon_star_2.png') }}" title="{{ 'element.favorite.add'|trans({}, 'elements') }}" alt="{{ 'element.favorite.add'|trans({}, 'elements') }}" />
97 106
               </a>
98 107
             {% endif %}
99 108
           {% else %}
100
-            <a class="mustbeconnected" href="#" >
101
-              <img src="{{ asset('img/icon_star_2.png') }}" title="{{ 'element.favorite.add'|trans({}, 'elements') }}" alt="{{ 'element.favorite.add'|trans({}, 'elements') }}" />
102
-            </a>
109
+            <img src="{{ asset('img/icon_star_2_gray.png') }}" alt="favorite" />
103 110
           {% endif %}
104 111
         </li>
105 112
       </ul>
@@ -270,6 +277,7 @@
270 277
           </li>
271 278
         {% endif %}
272 279
         
280
+        {% if not element.private %} 
273 281
         <li>
274 282
           <a
275 283
             class="add_to_playlist"
@@ -279,6 +287,7 @@
279 287
             <img src="{{ asset('/img/playlist_add_gray.png') }}" alt="add to playlist" />
280 288
           </a>
281 289
         </li>
290
+        {% endif %}
282 291
         
283 292
       </ul>
284 293
       
@@ -403,37 +412,38 @@
403 412
       
404 413
       {% endif %}
405 414
       
406
-      
407
-      <div class="social_buttons">
408
-        <ul>
409
-          <li class="facebook">
410
-            {{ facebookButton( {
411
-              'locale': 'fr_FR', 
412
-              'url': 'http:' ~ url('element_show_one', {
413
-                'element_id' : element.id,
414
-                'element_slug' : element.slug
415
-              }, true) })
416
-            }}
417
-          </li>
418
-          <li class="twitter">
419
-            {{ twitterButton( {
420
-              'locale': 'fr_FR', 
421
-              'url': 'http:' ~ url('element_show_one', {
422
-                'element_id' : element.id
423
-              }, true) }) 
424
-            }}
425
-          </li>
426
-          <li class="googleplus">
427
-            {{ googlePlusButton( {
428
-              'locale': 'fr_FR', 'url': 
429
-              'http:' ~ url('element_show_one', {
430
-                'element_id' : element.id,
431
-                'element_slug' : element.slug
432
-              }, true) }) 
433
-            }}
434
-          </li>
435
-        </ul>
436
-      </div>
415
+      {% if display_social_buttons %}
416
+        <div class="social_buttons">
417
+          <ul>
418
+            <li class="facebook">
419
+              {{ facebookButton( {
420
+                'locale': 'fr_FR', 
421
+                'url': 'http:' ~ url('element_show_one', {
422
+                  'element_id' : element.id,
423
+                  'element_slug' : element.slug
424
+                }, true) })
425
+              }}
426
+            </li>
427
+            <li class="twitter">
428
+              {{ twitterButton( {
429
+                'locale': 'fr_FR', 
430
+                'url': 'http:' ~ url('element_show_one', {
431
+                  'element_id' : element.id
432
+                }, true) }) 
433
+              }}
434
+            </li>
435
+            <li class="googleplus">
436
+              {{ googlePlusButton( {
437
+                'locale': 'fr_FR', 'url': 
438
+                'http:' ~ url('element_show_one', {
439
+                  'element_id' : element.id,
440
+                  'element_slug' : element.slug
441
+                }, true) }) 
442
+              }}
443
+            </li>
444
+          </ul>
445
+        </div>
446
+      {% endif %}
437 447
       
438 448
     </td>
439 449
   </tr>

+ 14 - 1
src/Muzich/CoreBundle/Searcher/ElementSearcher.php View File

@@ -115,6 +115,8 @@ class ElementSearcher extends Searcher implements SearcherInterface
115 115
    */
116 116
   protected $need_tags = false;
117 117
   
118
+  protected $display_privates = false;
119
+  
118 120
   /**
119 121
    * @see SearcherInterface
120 122
    * @param array $params 
@@ -159,7 +161,8 @@ class ElementSearcher extends Searcher implements SearcherInterface
159 161
       'ids_display' => $this->getIdsDisplay(),
160 162
       'tag_strict'  => $this->getTagStrict(),
161 163
       'need_tags'   => $this->getNeedTags(),
162
-      'string'      => $this->getString()
164
+      'string'      => $this->getString(),
165
+      'display_privates' => $this->getDisplayPrivates()
163 166
     );
164 167
   }
165 168
   
@@ -382,4 +385,14 @@ class ElementSearcher extends Searcher implements SearcherInterface
382 385
     $this->network = $network;
383 386
   }
384 387
   
388
+  public function getDisplayPrivates()
389
+  {
390
+    return ($this->display_privates)?true:false;
391
+  }
392
+  
393
+  public function setDisplayPrivates($display)
394
+  {
395
+    $this->display_privates = ($display)?true:false;
396
+  }
397
+  
385 398
 }

+ 10 - 0
src/Muzich/CoreBundle/Searcher/ElementSearcherQueryBuilder.php View File

@@ -319,6 +319,16 @@ class ElementSearcherQueryBuilder
319 319
       ->addOrderBy('e.id', 'DESC')
320 320
     ;
321 321
     
322
+    if ($this->es->getDisplayPrivates() && $this->user_id)
323
+    {
324
+      $this->query_ids->andWhere('(e.private = 0 OR (e.private = 1 AND e.owner = :owner_id))');
325
+      $this->parameters_ids['owner_id'] = $this->user_id;
326
+    }
327
+    else
328
+    {
329
+      $this->query_ids->andWhere('e.private = 0');
330
+    }
331
+    
322 332
     if (!$disable_limit)
323 333
     {
324 334
       $this->query_ids->setMaxResults($this->es->getCount());

+ 0 - 0
src/Muzich/CoreBundle/Tests/Controller/ScoreTest.php View File


+ 22 - 1
src/Muzich/CoreBundle/Twig/Extensions/MyTwigExtension.php View File

@@ -7,6 +7,7 @@ use Muzich\CoreBundle\Entity\Event;
7 7
 use Symfony\Component\Form\FormView;
8 8
 use Symfony\Component\DependencyInjection\Container;
9 9
 use Muzich\CoreBundle\Entity\User;
10
+use Muzich\CoreBundle\Entity\Playlist;
10 11
 
11 12
 class MyTwigExtension extends \Twig_Extension {
12 13
 
@@ -43,7 +44,8 @@ class MyTwigExtension extends \Twig_Extension {
43 44
       'token'                  => new \Twig_Function_Method($this, 'token'),
44 45
       'path_token'             => new \Twig_Function_Method($this, 'path_token'),
45 46
       'token'                  => new \Twig_Function_Method($this, 'getToken'),
46
-      'token_or_unknow'        => new \Twig_Function_Method($this, 'getTokenOrUnknown')
47
+      'token_or_unknow'        => new \Twig_Function_Method($this, 'getTokenOrUnknown'),
48
+      'playlist_element_displayable' => new \Twig_Function_Method($this, 'displayElementPlaylist')
47 49
     );
48 50
   }
49 51
   
@@ -269,4 +271,23 @@ class MyTwigExtension extends \Twig_Extension {
269 271
     return 'unknown';
270 272
   }
271 273
   
274
+  public function displayElementPlaylist(Playlist $playlist, $user_id, $element_data)
275
+  {
276
+    if (!$playlist->isPublic() && $playlist->getOwner()->getId() != $user_id)
277
+      return false;
278
+    
279
+    if (!$playlist->isPublic() && $playlist->getOwner()->getId() == $user_id)
280
+      return true;
281
+    
282
+    if ($playlist->isPublic() && !array_key_exists('private', $element_data))
283
+      return true;
284
+    
285
+    if ($playlist->isPublic() && array_key_exists('private', $element_data))
286
+    {
287
+      if ($element_data['private'] && $playlist->getOwner()->getId() != $user_id)
288
+        return false;
289
+      return true;
290
+    }
291
+  }
292
+  
272 293
 }

+ 3 - 1
src/Muzich/CoreBundle/lib/Collection/ElementCollectionManager.php View File

@@ -8,12 +8,14 @@ class ElementCollectionManager extends CollectionManager
8 8
   const ATTRIBUTE_ID   = 'Id';
9 9
   const ATTRIBUTE_NAME = 'Name';
10 10
   const ATTRIBUTE_TYPE = 'Type';
11
+  const ATTRIBUTE_PRIVATE = 'Private';
11 12
   
12 13
   protected $allow_duplicates = true;
13 14
   protected $schema = array(
14 15
     self::ATTRIBUTE_ID,
15 16
     self::ATTRIBUTE_NAME,
16
-    self::ATTRIBUTE_TYPE
17
+    self::ATTRIBUTE_TYPE,
18
+    self::ATTRIBUTE_PRIVATE
17 19
   );
18 20
   
19 21
   protected $object_reference_attribute = self::ATTRIBUTE_ID;

+ 18 - 12
src/Muzich/CoreBundle/lib/Tag.php View File

@@ -21,18 +21,21 @@ class Tag
21 21
     
22 22
     foreach ($elements as $element)
23 23
     {
24
-      foreach ($element->getTags() as $tag)
24
+      if (count($element->getTags()))
25 25
       {
26
-        // Si on a déjà un compteur pour ce tag
27
-        if (array_key_exists($tag->getId(), $tags_count))
26
+        foreach ($element->getTags() as $tag)
28 27
         {
29
-          // On incrémente
30
-          $tags_count[$tag->getId()] = $tags_count[$tag->getId()] + 1;
31
-        }
32
-        else
33
-        {
34
-          // On commence le compteur
35
-          $tags_count[$tag->getId()] = 1;
28
+          // Si on a déjà un compteur pour ce tag
29
+          if (array_key_exists($tag->getId(), $tags_count))
30
+          {
31
+            // On incrémente
32
+            $tags_count[$tag->getId()] = $tags_count[$tag->getId()] + 1;
33
+          }
34
+          else
35
+          {
36
+            // On commence le compteur
37
+            $tags_count[$tag->getId()] = 1;
38
+          }
36 39
         }
37 40
       }
38 41
     }
@@ -62,9 +65,12 @@ class Tag
62 65
     $tags_ordered = array();
63 66
     foreach ($elements as $element)
64 67
     {
65
-      foreach ($element->getTags() as $tag)
68
+      if (count($element->getTags()))
66 69
       {
67
-        $tags[$tag->getId()] = $tag;
70
+        foreach ($element->getTags() as $tag)
71
+        {
72
+          $tags[$tag->getId()] = $tag;
73
+        }
68 74
       }
69 75
     }
70 76
     

+ 66 - 0
src/Muzich/PlaylistBundle/Controller/EditController.php View File

@@ -6,6 +6,7 @@ use Muzich\CoreBundle\lib\Controller;
6 6
 use Symfony\Component\HttpFoundation\Request;
7 7
 use Muzich\CoreBundle\Security\Context as SecurityContext;
8 8
 use Muzich\CoreBundle\Propagator\EventElement;
9
+use Muzich\CoreBundle\Form\Playlist\PrivateLinksForm;
9 10
 
10 11
 class EditController extends Controller
11 12
 {
@@ -33,6 +34,10 @@ class EditController extends Controller
33 34
       return $this->jsonNotFoundResponse();
34 35
     
35 36
     $element = $playlist_manager->getElementWithIndex($playlist, $index);
37
+    
38
+    if (!$element)
39
+      return $this->jsonNotFoundResponse();
40
+    
36 41
     $playlist_manager->removePlaylistElementWithIndex($playlist, $index);
37 42
     
38 43
     $event = new EventElement($this->container);
@@ -178,6 +183,32 @@ class EditController extends Controller
178 183
     return $this->redirect($this->generateUrl('playlists_user', array('user_slug' => $this->getUser()->getSlug())));
179 184
   }
180 185
   
186
+  public function createAction(Request $request)
187
+  {
188
+    $playlist_form = $this->getPlaylistForm($this->getPlaylistManager()
189
+      ->getNewPlaylist($this->getUser()));
190
+    
191
+    if ($request->getMethod() == 'POST')
192
+    {
193
+      $playlist_form->bind($request);
194
+      if ($playlist_form->isValid())
195
+      {
196
+        $this->persist($playlist_form->getData());
197
+        $this->flush();
198
+        
199
+        $this->setFlash('success', $this->trans('playlist.create.success', array(), 'flash'));
200
+        return $this->redirect($this->generateUrl('playlist', array(
201
+          'user_slug'   => $this->getUser()->getSlug(),
202
+          'playlist_id' => $playlist_form->getData()->getId()
203
+        )));
204
+      }
205
+    }
206
+    
207
+    return $this->render('MuzichPlaylistBundle:Edit:create.html.twig', array(
208
+      'form'          => $playlist_form->createView()
209
+    ));
210
+  }
211
+  
181 212
   public function editAction($playlist_id)
182 213
   {
183 214
     if (!($playlist = $this->getPlaylistManager()->findOwnedPlaylistWithId($playlist_id, $this->getUser())))
@@ -223,4 +254,39 @@ class EditController extends Controller
223 254
     ));
224 255
   }
225 256
   
257
+  public function addPrivateLinksAction(Request $request, $playlist_id)
258
+  {
259
+    if (!($playlist = $this->getPlaylistManager()->findOneAccessiblePlaylistWithId($playlist_id, $this->getUser())))
260
+      throw $this->createNotFoundException();
261
+    
262
+    $form = $this->createForm(new PrivateLinksForm());
263
+    $form->bind($request);
264
+    $data = $form->getData();
265
+    
266
+    if (!$data['links'])
267
+    {
268
+      $this->setFlash('warning', $this->trans('playlist.no_links_added', array(), 'elements'));
269
+      return $this->redirect($this->generateUrl('playlist', array(
270
+        'user_slug'   => $this->getUser()->getSlug(),
271
+        'playlist_id' => $playlist_id
272
+      )));
273
+    }
274
+    
275
+    $count_added = $this->getPlaylistManager()->addPrivateLinks($playlist, $this->getUser(), explode("\n", $data['links']), $this->container);
276
+    
277
+    if ($count_added == count(explode("\n", $data['links'])))
278
+    {
279
+      $this->setFlash('success', $this->trans('playlist.links_added', array(), 'elements'));
280
+    }
281
+    else
282
+    {
283
+      $this->setFlash('warning', $this->trans('playlist.links_added_witherr', array(), 'elements'));
284
+    }
285
+    
286
+    return $this->redirect($this->generateUrl('playlist', array(
287
+      'user_slug'   => $this->getUser()->getSlug(),
288
+      'playlist_id' => $playlist_id
289
+    )));
290
+  }
291
+  
226 292
 }

+ 4 - 2
src/Muzich/PlaylistBundle/Controller/ShowController.php View File

@@ -5,6 +5,7 @@ namespace Muzich\PlaylistBundle\Controller;
5 5
 use Muzich\CoreBundle\lib\Controller;
6 6
 use Muzich\CoreBundle\lib\AutoplayManager;
7 7
 use Muzich\CoreBundle\Security\Context as SecurityContext;
8
+use Muzich\CoreBundle\Form\Playlist\PrivateLinksForm;
8 9
 
9 10
 class ShowController extends Controller
10 11
 {
@@ -36,7 +37,8 @@ class ShowController extends Controller
36 37
     
37 38
     return $this->render('MuzichPlaylistBundle:Show:show.html.twig', array(
38 39
       'playlist'    => $playlist,
39
-      'viewed_user' => $viewed_user
40
+      'viewed_user' => $viewed_user,
41
+      'links_form'  => $this->createForm(new PrivateLinksForm())->createView()
40 42
     ));
41 43
   }
42 44
   
@@ -49,7 +51,7 @@ class ShowController extends Controller
49 51
     if (!($playlist = $playlist_manager->findOneAccessiblePlaylistWithId($playlist_id, $this->getUserOrNullIfVisitor())))
50 52
       return $this->jsonNotFoundResponse();
51 53
     
52
-    $autoplaym = new AutoplayManager($playlist_manager->getPlaylistElements($playlist, $offset), $this->container);
54
+    $autoplaym = new AutoplayManager($playlist_manager->getPlaylistElements($playlist, $offset, $this->getUserId(true)), $this->container);
53 55
     
54 56
     if ($shuffle)
55 57
       $autoplaym->shuffle();

+ 15 - 5
src/Muzich/PlaylistBundle/Resources/config/routing.yml View File

@@ -5,27 +5,37 @@ playlists_user:
5 5
 playlist:
6 6
   pattern: /user/{user_slug}/playlist/{playlist_id}
7 7
   defaults: { _controller: MuzichPlaylistBundle:Show:show }
8
+  requirements:
9
+    playlist_id:  \d+
10
+
11
+playlist_new:
12
+  pattern: /private/user/{user_slug}/playlist/new
13
+  defaults: { _controller: MuzichPlaylistBundle:Edit:create }
8 14
 
9 15
 playlist_edit:
10
-  pattern: /user/{user_slug}/playlist/{playlist_id}/edit
16
+  pattern: /private/user/{user_slug}/playlist/{playlist_id}/edit
11 17
   defaults: { _controller: MuzichPlaylistBundle:Edit:edit }
12 18
   
13 19
 playlist_update:
14
-  pattern: /user/{user_slug}/playlist/{playlist_id}/update
20
+  pattern: /private/user/{user_slug}/playlist/{playlist_id}/update
15 21
   defaults: { _controller: MuzichPlaylistBundle:Edit:update }
16 22
 
17 23
 playlist_delete:
18
-  pattern: /playlist/delete/{playlist_id}/{token}
24
+  pattern: /private/playlist/delete/{playlist_id}/{token}
19 25
   defaults: { _controller: MuzichPlaylistBundle:Edit:delete }
20 26
 
21 27
 playlist_unpick:
22
-  pattern: /playlist/unpick/{playlist_id}/{token}/{redirect_owner}
28
+  pattern: /private/playlist/unpick/{playlist_id}/{token}/{redirect_owner}
23 29
   defaults: { _controller: MuzichPlaylistBundle:Edit:unpick, redirect_owner: false }
24 30
 
25 31
 playlist_pick:
26
-  pattern: /playlist/pick/{playlist_id}/{token}/{redirect_owner}
32
+  pattern: /private/playlist/pick/{playlist_id}/{token}/{redirect_owner}
27 33
   defaults: { _controller: MuzichPlaylistBundle:Edit:pick, redirect_owner: false }
28 34
 
35
+playlist_add_private_links:
36
+  pattern: /private/playlist/add-private-links/{playlist_id}
37
+  defaults: { _controller: MuzichPlaylistBundle:Edit:addPrivateLinks }
38
+  
29 39
 playlist_datas_for_autoplay:
30 40
   pattern: /ajax/autoplay/playlist/datas/{playlist_id}/{offset}
31 41
   defaults: { _controller: MuzichPlaylistBundle:Show:getAutoplayData, offset: null, shuffle: false }

+ 32 - 0
src/Muzich/PlaylistBundle/Resources/views/Edit/create.html.twig View File

@@ -0,0 +1,32 @@
1
+{% extends "MuzichFavoriteBundle::layout.html.twig" %}
2
+
3
+{% block title %}{{ 'playlist.create_title'|trans({}, 'elements') }}{% endblock %}
4
+{% block mainbox_classes %}{% endblock %}
5
+
6
+{% block content %}
7
+  
8
+  <div class="top_tools">
9
+    <div class="show_options">
10
+      
11
+      <a class="button darkbutton" href="{{ path('playlists_user', {
12
+        'user_slug' : app.user.slug,
13
+      }) }}" >
14
+        {{ 'playlist.goback'|trans({}, 'elements') }}
15
+      </a>
16
+      
17
+    </div>
18
+    
19
+    <h1>{{ 'playlist.create_title'|trans({}, 'elements') }}</h1>
20
+    
21
+    <form class="playlist_create playlist_edit" action="{{ path('playlist_new', {
22
+      'user_slug' : app.user.slug
23
+    }) }}" method="post">
24
+      {% include 'MuzichPlaylistBundle:Show:form.html.twig' with {
25
+        'display_public_widget' : true,
26
+        'submit_value'          : 'playlist.create_submit'|trans({}, 'elements')
27
+      } %}
28
+    </form>
29
+  
30
+  </div>
31
+  
32
+{% endblock %}

+ 83 - 53
src/Muzich/PlaylistBundle/Resources/views/Show/show.html.twig View File

@@ -60,71 +60,101 @@
60 60
       {% endif %}
61 61
     {% endif %}
62 62
     
63
-    
63
+    {% if app.user %}
64
+      {% if playlist.owned(app.user) %}
65
+        <a class="button darkbutton toplist open_playlist_private_links" href="#" >
66
+          {{ 'playlist.add_private_links'|trans({}, 'elements') }}
67
+        </a>
68
+      {% endif %}
69
+    {% endif %}
70
+        
64 71
     {% include "MuzichCoreBundle:Tag:tag_cloud.html.twig" with {
65 72
       'tags' : playlist.tags
66 73
     } %}
74
+        
75
+    {% if app.user %}
76
+      {% if playlist.owned(app.user) %}
77
+        <div class="private_links" style="display: none;">
78
+          <form action="{{ path_token('playlist_add_private_links', { 'playlist_id' : playlist.id }) }}" method="post">
79
+
80
+            <p class="help">{{ 'playlist.add_private_links_help'|trans({}, 'elements') }}</p>
81
+
82
+            <div class="inputs">
83
+              <input class="button" type="submit" value="{{ 'playlist.add_private_links_submit'|trans({}, 'elements') }}" />
84
+              <br />
85
+              <input class="button cancel" type="button" value="{{ 'playlist.add_private_links_cancel'|trans({}, 'elements') }}" />
86
+            </div>
87
+
88
+            {{ form_widget(links_form.links) }}
89
+            {{ form_rest(links_form) }}
90
+
91
+          </form>
92
+        </div>
93
+      {% endif %}
94
+    {% endif %}
67 95
     
68 96
     {% if playlist.elements|length %}
69 97
       <form action="{{ path_token('playlist_update_order', { 'playlist_id' : playlist.id }) }}" method="post">
70 98
         <ul class="playlist_elements {% if app.user%}{% if playlist.owned(app.user) %}owned{% endif %}{% endif %}">
71 99
           {% for element in playlist.elements %}
72
-            <li class="playlist_element">
73
-              
74
-              <input type="hidden" name="elements[]"  value="{{ element.id }}" />
75
-              
76
-              
77
-              <div class="actions">
78
-                
79
-                {% if app.user%}
80
-                  {% if playlist.owned(app.user) %}
81
-                    <a class="drag" href="#">
82
-                      <img src="{{ asset('/img/drag3.png') }}" alt="drag" />
83
-                    </a>
100
+            {% if playlist_element_displayable(playlist, app.user|userId, element) %}
101
+              <li class="playlist_element">
102
+
103
+                <input type="hidden" name="elements[]"  value="{{ element.id }}" />
104
+
105
+
106
+                <div class="actions">
107
+
108
+                  {% if app.user%}
109
+                    {% if playlist.owned(app.user) %}
110
+                      <a class="drag" href="#">
111
+                        <img src="{{ asset('/img/drag3.png') }}" alt="drag" />
112
+                      </a>
113
+                    {% endif %}
84 114
                   {% endif %}
85
-                {% endif %}
86
-                
87
-                {% if element.type|can_autoplay_type %}
88
-                  <a class="autoplay_playlist" 
89
-                    href="{{ path('playlist_datas_for_autoplay', { 'playlist_id' : playlist.id, 'offset' : loop.index0 }) }}"
90
-                    title="{{ 'playlist.start_here'|trans({}, 'elements') }}"
91
-                  >
92
-                    <img src="{{ asset('/img/1361037350_control_play.png') }}" alt="playlist" />
93
-                  </a>
94
-                {% else %}
95
-                  <img class="autoplay_off" src="{{ asset('/img/1361037350_control_play_off.png') }}" alt="playlist" />
96
-                {% endif %}
97
-                
98
-                {% if app.user%}
99
-                  {% if playlist.owned(app.user) %}
100
-                    <a 
101
-                      class="remove_element" 
102
-                      href="{{ path_token('playlist_remove_element', { 'playlist_id' : playlist.id, 'index' : loop.index0 }) }}"
103
-                      title="{{ 'playlist.remove_element'|trans({}, 'elements') }}"
115
+
116
+                  {% if element.type|can_autoplay_type %}
117
+                    <a class="autoplay_playlist" 
118
+                      href="{{ path('playlist_datas_for_autoplay', { 'playlist_id' : playlist.id, 'offset' : loop.index0 }) }}"
119
+                      title="{{ 'playlist.start_here'|trans({}, 'elements') }}"
104 120
                     >
105
-                      <img src="{{ asset('/img/icon_close_2.png') }}" alt="delete" />
121
+                      <img src="{{ asset('/img/1361037350_control_play.png') }}" alt="playlist" />
106 122
                     </a>
123
+                  {% else %}
124
+                    <img class="autoplay_off" src="{{ asset('/img/1361037350_control_play_off.png') }}" alt="playlist" />
107 125
                   {% endif %}
108
-                {% endif %}
109
-              </div>
110
-              
111
-              <div class="actions_right">
112
-                <a 
113
-                  class="open_element" 
114
-                  href="{{ path('element_get_one', { 'element_id' : element.id }) }}" data-id="{{ element.id }}"
115
-                  title="{{ 'playlist.open'|trans({}, 'elements') }}"
116
-                  >
117
-                  <img src="{{ asset('/img/icon_more_2.png') }}" alt="open" />
118
-                </a>
119
-              </div>
120
-              
121
-              <div class="title">
122
-                {{ element.name }}
123
-              </div>
124
-              
125
-              <div class="content_opened"></div>
126
-              
127
-            </li>
126
+
127
+                  {% if app.user%}
128
+                    {% if playlist.owned(app.user) %}
129
+                      <a 
130
+                        class="remove_element" 
131
+                        href="{{ path_token('playlist_remove_element', { 'playlist_id' : playlist.id, 'index' : loop.index0 }) }}"
132
+                        title="{{ 'playlist.remove_element'|trans({}, 'elements') }}"
133
+                      >
134
+                        <img src="{{ asset('/img/icon_close_2.png') }}" alt="delete" />
135
+                      </a>
136
+                    {% endif %}
137
+                  {% endif %}
138
+                </div>
139
+
140
+                <div class="actions_right">
141
+                  <a 
142
+                    class="open_element" 
143
+                    href="{{ path('element_get_one', { 'element_id' : element.id }) }}" data-id="{{ element.id }}"
144
+                    title="{{ 'playlist.open'|trans({}, 'elements') }}"
145
+                    >
146
+                    <img src="{{ asset('/img/icon_more_2.png') }}" alt="open" />
147
+                  </a>
148
+                </div>
149
+
150
+                <div class="title">
151
+                  {{ element.name }}
152
+                </div>
153
+
154
+                <div class="content_opened"></div>
155
+
156
+              </li>
157
+            {% endif %}
128 158
           {% endfor %}
129 159
         </ul>
130 160
       </form>

+ 8 - 0
src/Muzich/PlaylistBundle/Resources/views/Show/user.html.twig View File

@@ -9,6 +9,14 @@
9 9
     
10 10
     <div class="show_options">
11 11
       
12
+      {% if app.user %}
13
+        {% if viewed_user.id == app.user.id %}
14
+          <a class="button darkbutton" href="{{ path('playlist_new', {'user_slug' : app.user.slug}) }}" >
15
+            {{ 'user.new_playlist'|trans({}, 'users') }}
16
+          </a>
17
+        {% endif %}
18
+      {% endif %}
19
+      
12 20
       <a class="button darkbutton" href="{{ path('show_user', {'slug' : viewed_user.slug}) }}" >
13 21
         {{ 'user.view_profile'|trans({}, 'users') }}
14 22
       </a>

BIN
web/img/icon_star_2_gray.png View File