/[drupal]/contributions/modules/playlist/playlist.module
ViewVC logotype

Contents of /contributions/modules/playlist/playlist.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.31 - (show annotations) (download) (as text)
Sat Jul 8 20:54:15 2006 UTC (3 years, 4 months ago) by zirafa
Branch: MAIN
CVS Tags: HEAD
Changes since 1.30: +22 -8 lines
File MIME type: text/x-php
Added stack_order option to audio_playlist to specify if new audio should be added to the top or bottom of a playlist and fixed db_rewrite barf #72133
1 <?php
2
3 /**
4 *
5 * This module provides a set of helper functions to get in and out of the playlist_relate database.
6 * These commonly used functions can be used to create new playlist modules.
7 *
8 **/
9
10 // Define an easy to remember name for the path of this module, ex: include_once PLAYLIST_PATH.'/playlist.theme';
11 define('PLAYLIST_PATH', drupal_get_path('module', 'playlist'));
12
13 //include the theme functions
14 include_once PLAYLIST_PATH . '/playlist.theme';
15
16
17 /**
18 * Input a parent node id, and return an array of children id's ordered by their weight.
19 **/
20 function playlist_get_children($parent_id, $type) {
21 $children = array();
22 $result = db_query("SELECT child_id FROM {playlist_relate} WHERE parent_id = %d AND type = '%s' ORDER BY weight", $parent_id, $type);
23 while($row = db_fetch_object($result)) {
24 $children[] .= $row->child_id;
25 }
26 return $children;
27 }
28
29
30 /**
31 * Get parent nodes for a child node, user, or type.
32 * Input a child node id, a playlist type, or user id (or combination of three) and return the resulting parent nodes.
33 **/
34 function playlist_get_parents($param = array(), $order = null) {
35 foreach ($param as $key => $value) {
36 $prefix = $key == 'uid' ? 'n.' : 'p.';
37 $cond[] = $prefix . db_escape_string($key) ." = '%s'";
38 $arguments[] = $value;
39 }
40 $cond = implode(' AND ', $cond);
41 if($order) $order_sql = ' ORDER BY ' . $order;
42 $result = db_query(db_rewrite_sql('SELECT DISTINCT parent_id FROM {playlist_relate} p INNER JOIN {node} n ON n.nid = p.parent_id WHERE ' . $cond . $order_sql), $arguments);
43 $parents = array();
44 while($row = db_fetch_object($result)) {
45 $parents[] .= $row->parent_id;
46 }
47 return $parents;
48 }
49
50
51 /**
52 * Adds a new child to a parent id. It will be automatically assigned the next weight in the list. Returns true if successful.
53 * $stack_bottom = TRUE adds new children to the bottom of a playlist. If False it adds new chilrden to the top of the playlist.
54 **/
55 function playlist_add_child($child_id, $parent_id, $type, $stack_bottom = TRUE) {
56 $weight = playlist_get_next_weight($parent_id);
57 $exists = playlist_check(array('type' => $type, 'parent_id' => $parent_id, 'child_id' => $child_id));
58 if(!$exists) {
59 if(!$stack_bottom) {
60 // shift the weight of the current items down one, then add the new child to the top.
61 $playlist_items = playlist_get_children($parent_id, $type);
62 $first_weight = playlist_get_weight($parent_id, $playlist_items[0]);
63 $i = $first_weight + 1;
64 foreach ($playlist_items as $child_item) {
65 playlist_set_weight($parent_id, $child_item, $i++);
66 }
67 $result = db_query("INSERT INTO {playlist_relate} (type, parent_id, child_id, weight) VALUES ('%s', %d, %d, %d)", $type, $parent_id, $child_id, $first_weight);
68 }
69 else {
70 // add the new child to the bottom of the playlist
71 $result = db_query("INSERT INTO {playlist_relate} (type, parent_id, child_id, weight) VALUES ('%s', %d, %d, %d)", $type, $parent_id, $child_id, $weight);
72 }
73 }
74 return !$exists; // if it doesn't exist, return TRUE saying we added it if successful
75 }
76
77
78 /**
79 * Delete a child node from a given playlist. If no parent_id specified, it deletes the child from all playlists. Returns true if successful.
80 */
81 function playlist_remove_child($child_id, $parent_id = NULL) {
82 if(is_numeric($parent_id)) {
83 $filter = " AND parent_id = $parent_id";
84 }
85 $result = db_query("DELETE FROM {playlist_relate} WHERE child_id = %d" . $filter, $child_id);
86 return db_affected_rows($result);
87 }
88
89
90 /**
91 * Delete a playlist parent. Returns true if successful.
92 */
93 function playlist_remove($parent_id) {
94 $result = db_query("DELETE FROM {playlist_relate} WHERE parent_id = %d", $parent_id);
95 return db_affected_rows($result);
96 }
97
98
99 /**
100 * Delete all playlists of a given type. Returns true if successful.
101 */
102 function playlist_remove_by_type($type) {
103 $result = db_query("DELETE FROM {playlist_relate} WHERE type = '%s'", $type);
104 return db_affected_rows($result);
105 }
106
107
108 /**
109 * Swaps the weights of two children in a given playlist. Returns true if successful.
110 */
111 function playlist_swap_weight($parent_id, $child_id1, $child_id2) {
112 $weight1 = playlist_get_weight($parent_id, $child_id1);
113 $weight2 = playlist_get_weight($parent_id, $child_id2);
114 if(($weight1 > -1) && ($weight2 > -1)) {
115 playlist_set_weight($parent_id, $child_id1, $weight2);
116 playlist_set_weight($parent_id, $child_id2, $weight1);
117 return 1;
118 }
119 else {
120 return 0;
121 }
122 }
123
124 /**
125 * Set weight of a playlist item directly.
126 **/
127 function playlist_set_weight($parent_id, $child_id, $weight) {
128 $result = db_query("UPDATE {playlist_relate} SET weight = %d WHERE parent_id = %d AND child_id = %d", $weight, $parent_id, $child_id);
129 return db_affected_rows($result);
130 }
131
132
133 /**
134 * Get current weight of a playlist item.
135 **/
136 function playlist_get_weight($parent_id, $child_id) {
137 $weight = db_result(db_query("SELECT weight FROM {playlist_relate} WHERE parent_id = %d AND child_id = %d",$parent_id, $child_id));
138 return is_null($weight) ? -1 : $weight; //we return -1 as a FAIL status code since 0 is used as a weight.
139 }
140
141 /**
142 * Get next weight in a playlist, used in playlist_add_child.
143 **/
144 function playlist_get_next_weight($parent_id) {
145 $max = db_result(db_query("SELECT MAX(weight) FROM {playlist_relate} WHERE parent_id = %d LIMIT 1", $parent_id));
146 return (is_null($max)) ? 0 : ++$max;
147 }
148
149
150 /**
151 * Check to see if a playlist_relate row already exists, return true or false.
152 * You can specify what you are looking for, a type, a parent_id, a child_id, or a combination.
153 * Example: playlist_check('type' => 'audio_playlist', 'parent_id' => 23, 'child_id' => 54);
154 **/
155 function playlist_check($param = array()) {
156 foreach ($param as $key => $value) {
157 $cond[] = db_escape_string($key) ." = '%s'";
158 $arguments[] = $value;
159 }
160 $cond = implode(' AND ', $cond);
161
162 $result = db_query("SELECT * FROM {playlist_relate} WHERE " . $cond, $arguments);
163 return db_affected_rows($result);
164 }
165
166 /**
167 * Return an array of all playlist types in the playlist_relate table
168 **/
169 function playlist_get_types() {
170 $result = db_query("SELECT DISTINCT type FROM {playlist_relate}");
171 $types = array();
172 while($row = db_fetch_object($result)) {
173 $types[] .= $row->type;
174 }
175 return $types;
176 }
177
178
179 ////////////////////////////////////////////////////////////////////////////////////////////////
180 //
181 // Drupal Hooks
182 //
183 ///////////////////////////////////////////////////////////////////////////////////////////////
184
185 function playlist_help($section) {
186 switch ($section) {
187 case 'admin/modules#description':
188 // This description is shown in the listing at admin/modules.
189 return t('A module that provides helper functions to create playlists. This module does not do anything by itself.');
190 }
191 }
192
193 /**
194 * Implementation of hook_perm().
195 * We have to define a basic permission to "manage playlists" to protect the menu callbacks from being abused.
196 */
197 function playlist_perm() {
198 return array('manage playlists');
199 }
200
201 /**
202 * Implementation of hook_menu
203 **/
204 function playlist_menu($may_cache) {
205 global $user;
206
207 $items = array();
208
209 if ($may_cache) {
210 //AJAX save order
211 $items[] = array('path' => 'playlist/ajax/order', 'title' => t('Save playlist order'), //playlist/ajax/order/[playlist_id]
212 'callback' => '_playlist_save_order',
213 'access' => user_access('manage playlists'),
214 'type' => MENU_CALLBACK
215 );
216 $items[] = array('path' => 'playlist/manage', 'title' => t('manage playlist'), //playlist/manage/[type]/[playlist_id]/[op]/[child_id]
217 'callback' => '_playlist_manage',
218 'access' => user_access('manage playlists'),
219 'type' => MENU_LOCAL_TASK,
220 );
221 }
222 $items[] = array(
223 'path' => 'playlist/add', //playlist/add/[type]/[child_id]
224 'title' => t("Add or remove item from ".node_get_name(arg(2))."s"),
225 'access' => user_access('manage playlists'),
226 'callback' => playlist_add_item,
227 'type' => MENU_CALLBACK,
228 );
229 return $items;
230 }
231
232
233 /**
234 * Menu callback that saves the order of the audio files. Depends on javascript functions as well as list output.
235 * Called via AJAX
236 */
237 function _playlist_save_order(){
238 $parent_id = arg(3);
239 $playlist_items = $_REQUEST['list'];
240 foreach ($playlist_items as $child_id) {
241 playlist_set_weight($parent_id, (int)$child_id, $i++);
242 }
243 drupal_set_message("Your changes have been saved.");
244 print theme('status_messages');
245 }
246
247
248 /**
249 * Menu callback for deleting, adding, and swapping individual playlist items
250 * playlist/manage/[type]/[playlist_id]/[op]/[child_id]/[child_id2]/
251 */
252 function _playlist_manage() {
253 global $user;
254
255 $type = arg(2);
256 $parent_id = arg(3);
257 $op = arg(4);
258 $child_id = arg(5);
259 $child_id2 = arg(6);
260
261 //check to see if the user is allowed to update this playlist
262 if(node_access('update', node_load($parent_id), $user->uid)) {
263 switch($op) {
264 case 'add':
265 playlist_add_child($child_id, $parent_id, $type, variable_get($type.'_stack_bottom', 1));
266 drupal_set_message(t("Item added to playlist"));
267 drupal_goto($_SERVER["HTTP_REFERER"]);
268 break;
269 case 'delete':
270 playlist_remove_child($child_id, $parent_id);
271 drupal_set_message(t("Item deleted from playlist"));
272 drupal_goto($_SERVER["HTTP_REFERER"]);
273 break;
274 case 'swap':
275 playlist_swap_weight($parent_id, $child_id, $child_id2);
276 drupal_goto($_SERVER["HTTP_REFERER"]);
277 break;
278 }
279 } else {
280 drupal_set_message(t('You do not have permission to update this playlist.'));
281 }
282
283 return;
284 }
285
286
287 /**
288 * Menu callback that renders a form for adding a playlist item to a playlist
289 * //playlist/add/[type]/[child_id]
290 */
291 function playlist_add_item() {
292 global $user;
293
294 //check if this playlist node type sent is a real node type
295 $type = arg(2);
296
297 if(is_numeric(arg(3))) {
298 $child_id = arg(3);
299 }
300
301 $create_new = '<ul><li>'. l(t("Create a new " . node_get_name($type)), "node/add/$type") .'</li></ul>';
302
303 //get an array of playlists that a user has created
304 $result = db_query("SELECT nid FROM {node} WHERE type = '%s' AND uid = %d ORDER BY title", $type, $user->uid);
305 $playlists = array();
306 while($row = db_fetch_object($result)) {
307 $playlists[] .= $row->nid;
308 }
309 $selected = playlist_get_parents(array('child_id' => $child_id)); //get playlists where this item is already added
310 $child = node_load($child_id);
311 $form['items'] = array('#tree' => TRUE, '#type' => 'fieldset', '#title' => t("Add or remove <b>$child->title</b> from the following ".node_get_name($type)."s:"));
312 foreach($playlists as $playlist_id) {
313 $playlist_node = node_load($playlist_id);
314 //render the checkboxes
315 if (node_access('update', $playlist_node, $user->uid)) {
316 $checked = in_array($playlist_id, $selected) ? TRUE : FALSE;
317 $form['items'][$playlist_id] = array('#type' => 'checkbox', '#title' => l($playlist_node->title, 'node/'.$playlist_node->nid), '#default_value' => $checked, '#required' => FALSE);
318 }
319 }
320
321 $form['type'] = array('#type' => 'value', '#value' => $type);
322 $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
323 $output = $create_new . drupal_get_form('playlist_add_item', $form);
324
325 return $output;
326 }
327
328
329 /**
330 * Handle the data submitted by playlist_add_item form
331 */
332 function playlist_add_item_submit($form_id, $form_values) {
333 global $user;
334
335 $child_id = arg(3);
336 $child = node_load($child_id);
337
338 foreach($form_values['items'] as $playlist_id => $value) {
339 if($value) {
340 playlist_add_child($child_id, $playlist_id, $form_values['type'], variable_get($form_values['type'] . '_stack_bottom', 1));
341 } else {
342 playlist_remove_child($child_id, $playlist_id) > 0;
343 }
344 }
345 drupal_set_message("Your changes were saved.");
346 }
347
348

  ViewVC Help
Powered by ViewVC 1.1.2