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

Contents of /contributions/modules/ajax_views/ajax_views.module

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


Revision 1.6 - (show annotations) (download) (as text)
Wed May 21 16:38:59 2008 UTC (18 months, 1 week ago) by febbraro
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +19 -14 lines
File MIME type: text/x-php
Fixes #256101: Thanks to magoo for getting the argument handling code up to snuff
1 <?php
2
3 /**
4 * Implementation of hook_views_style_plugins.
5 *
6 * Add this type to the view style drop down (adds to both Page and Block type)
7 */
8 function ajax_views_views_style_plugins() {
9 return array(
10 'ajax_view' => array(
11 'name' => t('AJAX Paging Block View'),
12 'theme' => 'views_ajax',
13 'validate' => 'ajax_views_plugin_validate',
14 'weight' => -12,
15 ),
16
17 );
18 }
19
20 /**
21 * Add this argument to the arguments drop down.
22 */
23 function ajax_views_views_arguments() {
24 $arguments = array(
25 'ajax_response' => array(
26 'name' => t('AJAX Views: AJAX Selector'),
27 'handler' => 'views_handler_arg_ajax',
28 'option' => 'string',
29 'help' => t('This argument specifies an AJAX selector (/ajax).'),
30 ),
31 );
32 return $arguments;
33 }
34
35 /**
36 * Ajax views validation callback.
37 *
38 * Makes sure that the Paged Block is only specifed on the Block group.
39 */
40 function ajax_views_plugin_validate($type, $view, $form) {
41 // Ensure AJAX Block is not specified as a Page Type
42 if ($view['page_type'] == 'ajax_view') {
43 form_error($form["$type-info"]['page_type'], t('AJAX Paging Block View can only be specified on a Block.'));
44 }
45
46 // Ensure AJAX Block is specified as a Block Type, that the AJAX Selector is also specified
47 if ($view['block_type'] == 'ajax_view') {
48 $has_ajax_argument = false;
49 foreach ($view['argument'] as $argument) {
50 if($argument['type'] == 'ajax_response') {
51 $has_ajax_argument = true;
52 break;
53 }
54 }
55
56 if(!$has_ajax_argument) {
57 form_error($form["$type-info"]['block_type'], t('If you specify AJAX Paging Block View, then you must also add the AJAX Selector as an argument.'));
58 }
59 }
60 }
61
62 /**
63 * Handler for our own ajax_views argument; mimics the feed selector
64 */
65 function views_handler_arg_ajax($op, &$query, $argtype, $arg = '') {
66 switch($op) {
67 case 'summary':
68 case 'sort':
69 case 'link':
70 case 'title':
71 break;
72 case 'filter':
73 // This is a clone of the default selector, but it just invokes ours
74 // rather than calling all of them.
75 ajax_views_ajax_argument('argument', $GLOBALS['current_view'], $arg, $argtype);
76 }
77 }
78
79 /**
80 * Ajax/Feed argument hook that will convert us to an Ajax page or RSS Feed.
81 * the 4th argument isn't part of the hook, but we use it to differentiate
82 * when called as a hook or when called manually from views_rss_views_post_view
83 */
84 function ajax_views_ajax_argument($op, &$view, $arg, $argdata = NULL) {
85 if ($op == 'argument' && $arg == 'ajax') {
86 if($arg == 'ajax') {
87 $view->page_type = 'ajax_view';
88 $view->pager_limit = $view->nodes_per_block;
89 }
90
91 if ($argdata['options']) {
92 $view->description = $argdata['options'];
93 }
94
95 // reset the 'real url' to the URL without the ajax argument.
96 $view_args = array();
97 $max = count($view->args);
98 foreach ($view->args as $id => $view_arg) {
99 ++$count;
100 if ($view_arg == $arg && $view->argument[$id]['id'] == $argdata['id']) {
101 if ($count != $max) {
102 $view_args[] = $argdata['wildcard'];
103 }
104 }
105 else {
106 $view_args[] = $view_arg;
107 }
108 }
109 $view->feed_url = views_get_url($view, $view_args);
110 }
111 }
112
113 /**
114 * Main theme function for ajax views. This will get called for any block that has
115 * the AJAX View type specified, or for any page with the AJAX View Argument (/ajax)
116 * specified. So this is a traffic cop to render both the block wrapper, and the ajax
117 * content that is held within the wrapper.
118 *
119 * You can simply override views_ajax_block or views_ajax_page to control the style
120 * of these rendering across the entire site, or you can append the view name to the
121 * end to customize specific renderings, for example: views_ajax_page_press_releases for
122 * a view with the name press_releases.
123 *
124 * @param $view The View
125 * @param $nodes An array of nodes to render
126 * @param $type The type of view (in this case 'page')
127 * @return The themed content.
128 */
129 function theme_views_ajax($view, $nodes, $type) {
130
131 if($type == 'block') {
132 $function = 'views_ajax_block';
133 }
134 else if($type == 'page') {
135 $function = 'views_ajax_page';
136 }
137 else {
138 return;
139 }
140
141 if (!($func = theme_get_function($function . "_" . $view->name))) {
142 $func = theme_get_function($function);
143 }
144
145 if ($func) {
146 $args = func_get_args();
147 return call_user_func_array($func, $args);
148 }
149 return;
150 }
151
152 /**
153 * Generate the appropriate ajax url, inserting wildcards for all things
154 * except our ajax selector.
155 */
156 function _generate_ajax_url($view) {
157 $url .= "$view->url";
158 $i = 0;
159 foreach ($view->argument as $argument) {
160 if($argument['type'] == 'ajax_response') {
161 $url .= "/ajax";
162 }
163 else if ($view->args[$i]){
164 $url .= '/' . $view->args[$i];
165 }
166 else if ($argument['wildcard']) {
167 $url .= '/' . $argument['wildcard'];
168 }
169 else {
170 $url .= "/*";
171 }
172 $i++;
173 }
174 return url($url);
175 }
176
177 /**
178 * Theme function to render the body of the ajax-ified block. This default returns a div
179 * and some javascript to load the first page via jQuery.
180 *
181 * @param $view The View
182 * @param $nodes An array of nodes to render
183 * @param $type The type of view (in this case 'page')
184 * @return The content of the block.
185 */
186 function theme_views_ajax_block($view, $nodes, $type) {
187
188 $ajax_url = _generate_ajax_url($view);
189 $view_css = views_css_safe("ajax-view-block-$view->name");
190 drupal_add_css(drupal_get_path('module', 'ajax_views') . '/ajax_views.css');
191 drupal_add_js(drupal_get_path('module', 'ajax_views') . '/ajax_views.js');
192 drupal_add_js("$(document).ready(function() {
193 $.get('$ajax_url', {page: 0}, function(data, status) {
194 $('.$view_css').html(data);
195 });
196 })", "inline");
197
198 $output .= "<div class='$view_css'>";
199 $output .= theme_image('misc/progress.gif', 'Progress') . "&nbsp;&nbsp; Loading content for $view->page_title";
200 $output .= "</div>";
201 return $output;
202 }
203
204 /**
205 * Theme function to render the dynamic ajax page that is served to the block. This function
206 * exits so it will not get wrapped by page.tpl.php.
207 *
208 * @param $view The View
209 * @param $nodes An array of nodes to render
210 * @param $type The type of view (in this case 'page')
211 */
212 function theme_views_ajax_page($view, $nodes, $type) {
213 //$output .= '<pre>' . print_r($view->args, true) . '</pre>';
214
215 $output .= '<div class="ajax_views_headers">';
216 $output .= '<div class="title">' . l($view->page_title, $view->url) . '</div>';
217 if ( _has_feed_argument($view) ) {
218 $output .= '<div class="rss">' . theme_image('misc/feed.png') . '&nbsp;' . l("RSS", "$view->url/feed") . '</div>';
219 }
220 $output .= '<div style="clear:both;"></div>';
221 $output .= '</div>';
222
223 $output .= "<div class='ajax_views_body'>";
224 if (count($nodes)) {
225
226 $function = "views_ajax_page_item";
227 if (!($func = theme_get_function($function . "_" . $view->name))) {
228 $func = theme_get_function($function);
229 }
230
231 $rendered_nodes = array();
232 foreach($nodes as $node) {
233 $current = node_load($node->nid);
234 $rendered_nodes[] = call_user_func($func, $current);
235 }
236
237 $output .= theme('item_list', $rendered_nodes);
238 }
239 else
240 $output .= views_get_textarea($view, 'block', 'empty');
241
242 $output .= "</div>";
243
244 $output .= theme('views_ajax_block_pager', $view);
245
246 drupal_set_header('Content-Type: text/html; charset=utf-8');
247 print $output;
248 module_invoke_all('exit');
249 exit;
250 }
251
252 /**
253 * Theme function to render the dynamic ajax page individual items that are served to the block.
254 *
255 * @param $node The nodes to render
256 */
257 function theme_views_ajax_page_item($node) {
258 //return '<pre>' . print_r($node, true) . '</pre>';
259 return l($node->title, "node/$node->nid");
260 }
261
262 function theme_views_ajax_block_pager($view) {
263
264 $ajax_url = _generate_ajax_url($view);
265 $view_css = views_css_safe("ajax-view-block-$view->name");
266 $total_pages = ceil($view->total_rows / $view->pager_limit);
267 $current_page = isset($_GET['page']) ? $_GET['page'] : 0;
268
269 $output .= '<div class="ajax_views_footers">';
270 $output .= '<div class="ajax_pager_link ajax_prev">&nbsp;';
271 if ($current_page > 0) {
272 $onclick = "return fetchPage('.$view_css', '$ajax_url', " . ($current_page - 1) . ")";
273 $output .= l(t('< Previous'), '', array('onclick' => $onclick));
274 }
275 $output .= '</div>';
276
277 $output .= "<div class='ajax_pages'>&nbsp;";
278 if ($total_pages > 1) {
279 $readable_page = $current_page + 1;
280 $output .= "$readable_page of $total_pages";
281 }
282 $output .= "</div>";
283
284 $output .= '<div class="ajax_pager_link ajax_next">&nbsp;';
285 if ($current_page + 1 < $total_pages) {
286 $onclick = "return fetchPage('.$view_css', '$ajax_url', " . ($current_page + 1) . ")";
287 $output .= l(t('Next >'), '', array('onclick' => $onclick));
288 }
289 $output .= '</div>';
290 $output .= '</div>';
291 return $output;
292 }
293
294 /**
295 * Returns true if the provided view has the rss_feed argument configured.
296 */
297 function _has_feed_argument($view) {
298
299 foreach ($view->argument as $argument) {
300 if($argument['type'] == 'rss_feed') {
301 return true;
302 }
303 }
304 return false;
305 }

  ViewVC Help
Powered by ViewVC 1.1.2