Development

/branches/1.4/lib/helper/AssetHelper.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/helper/AssetHelper.php

Revision 33121, 19.2 kB (checked in by fabien, 3 years ago)

[1.4] fixed protocol relative URL in the asset helper (closes #9936)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004 David Heinemeier Hansson
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  * AssetHelper.
14  *
15  * @package    symfony
16  * @subpackage helper
17  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
18  * @author     David Heinemeier Hansson
19  * @version    SVN: $Id$
20  */
21
22 /**
23  * Returns a <link> tag that browsers and news readers
24  * can use to auto-detect a RSS or ATOM feed for the current page,
25  * to be included in the <head> section of a HTML document.
26  *
27  * <b>Options:</b>
28  * - rel - defaults to 'alternate'
29  * - type - defaults to 'application/rss+xml'
30  * - title - defaults to the feed type in upper case
31  *
32  * <b>Examples:</b>
33  * <code>
34  *  echo auto_discovery_link_tag('rss', 'module/feed');
35  *    => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.curenthost.com/module/feed" />
36  *  echo auto_discovery_link_tag('rss', 'module/feed', array('title' => 'My RSS'));
37  *    => <link rel="alternate" type="application/rss+xml" title="My RSS" href="http://www.curenthost.com/module/feed" />
38  * </code>
39  *
40  * @param string $type        feed type ('rss', 'atom')
41  * @param string $url         'module/action' or '@rule' of the feed
42  * @param array  $tag_options additional HTML compliant <link> tag parameters
43  *
44  * @return string XHTML compliant <link> tag
45  */
46 function auto_discovery_link_tag($type = 'rss', $url = '', $tag_options = array())
47 {
48   return tag('link', array(
49     'rel'   => isset($tag_options['rel']) ? $tag_options['rel'] : 'alternate',
50     'type'  => isset($tag_options['type']) ? $tag_options['type'] : 'application/'.$type.'+xml',
51     'title' => isset($tag_options['title']) ? $tag_options['title'] : ucfirst($type),
52     'href'  => url_for($url, true)
53   ));
54 }
55
56 /**
57  * Returns the path to a JavaScript asset.
58  *
59  * <b>Example:</b>
60  * <code>
61  *  echo javascript_path('myscript');
62  *    => /js/myscript.js
63  * </code>
64  *
65  * <b>Note:</b> The asset name can be supplied as a...
66  * - full path, like "/my_js/myscript.css"
67  * - file name, like "myscript.js", that gets expanded to "/js/myscript.js"
68  * - file name without extension, like "myscript", that gets expanded to "/js/myscript.js"
69  *
70  * @param string $source   asset name
71  * @param bool   $absolute return absolute path ?
72  *
73  * @return string file path to the JavaScript file
74  * @see    javascript_include_tag
75  */
76 function javascript_path($source, $absolute = false)
77 {
78   return _compute_public_path($source, sfConfig::get('sf_web_js_dir_name', 'js'), 'js', $absolute);
79 }
80
81 /**
82  * Returns a <script> include tag per source given as argument.
83  *
84  * <b>Examples:</b>
85  * <code>
86  *  echo javascript_include_tag('xmlhr');
87  *    => <script language="JavaScript" type="text/javascript" src="/js/xmlhr.js"></script>
88  *  echo javascript_include_tag('common.javascript', '/elsewhere/cools');
89  *    => <script language="JavaScript" type="text/javascript" src="/js/common.javascript"></script>
90  *       <script language="JavaScript" type="text/javascript" src="/elsewhere/cools.js"></script>
91  * </code>
92  *
93  * @param string asset names
94  * @param array additional HTML compliant <link> tag parameters
95  *
96  * @return string XHTML compliant <script> tag(s)
97  * @see    javascript_path
98  */
99 function javascript_include_tag()
100 {
101   $sources = func_get_args();
102   $sourceOptions = (func_num_args() > 1 && is_array($sources[func_num_args() - 1])) ? array_pop($sources) : array();
103
104   $html = '';
105   foreach ($sources as $source)
106   {
107     $absolute = false;
108     if (isset($sourceOptions['absolute']))
109     {
110       unset($sourceOptions['absolute']);
111       $absolute = true;
112     }
113
114     $condition = null;
115     if (isset($sourceOptions['condition']))
116     {
117       $condition = $sourceOptions['condition'];
118       unset($sourceOptions['condition']);
119     }
120
121     if (!isset($sourceOptions['raw_name']))
122     {
123       $source = javascript_path($source, $absolute);
124     }
125     else
126     {
127       unset($sourceOptions['raw_name']);
128     }
129
130     $options = array_merge(array('type' => 'text/javascript', 'src' => $source), $sourceOptions);
131     $tag = content_tag('script', '', $options);
132
133     if (null !== $condition)
134     {
135       $tag = comment_as_conditional($condition, $tag);
136     }
137
138     $html .= $tag."\n";
139   }
140
141   return $html;
142 }
143
144 /**
145  * Returns the path to a stylesheet asset.
146  *
147  * <b>Example:</b>
148  * <code>
149  *  echo stylesheet_path('style');
150  *    => /css/style.css
151  * </code>
152  *
153  * <b>Note:</b> The asset name can be supplied as a...
154  * - full path, like "/my_css/style.css"
155  * - file name, like "style.css", that gets expanded to "/css/style.css"
156  * - file name without extension, like "style", that gets expanded to "/css/style.css"
157  *
158  * @param string $source   asset name
159  * @param bool   $absolute return absolute path ?
160  *
161  * @return string file path to the stylesheet file
162  * @see    stylesheet_tag
163  */
164 function stylesheet_path($source, $absolute = false)
165 {
166   return _compute_public_path($source, sfConfig::get('sf_web_css_dir_name', 'css'), 'css', $absolute);
167 }
168
169 /**
170  * Returns a css <link> tag per source given as argument,
171  * to be included in the <head> section of a HTML document.
172  *
173  * <b>Options:</b>
174  * - rel - defaults to 'stylesheet'
175  * - type - defaults to 'text/css'
176  * - media - defaults to 'screen'
177  *
178  * <b>Examples:</b>
179  * <code>
180  *  echo stylesheet_tag('style');
181  *    => <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
182  *  echo stylesheet_tag('style', array('media' => 'all'));
183  *    => <link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />
184  *  echo stylesheet_tag('style', array('raw_name' => true));
185  *    => <link href="style" media="all" rel="stylesheet" type="text/css" />
186  *  echo stylesheet_tag('random.styles', '/css/stylish');
187  *    => <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />
188  *       <link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />
189  * </code>
190  *
191  * @param string asset names
192  * @param array  additional HTML compliant <link> tag parameters
193  *
194  * @return string XHTML compliant <link> tag(s)
195  * @see    stylesheet_path
196  */
197 function stylesheet_tag()
198 {
199   $sources = func_get_args();
200   $sourceOptions = (func_num_args() > 1 && is_array($sources[func_num_args() - 1])) ? array_pop($sources) : array();
201
202   $html = '';
203   foreach ($sources as $source)
204   {
205     $absolute = false;
206     if (isset($sourceOptions['absolute']))
207     {
208       unset($sourceOptions['absolute']);
209       $absolute = true;
210     }
211
212     $condition = null;
213     if (isset($sourceOptions['condition']))
214     {
215       $condition = $sourceOptions['condition'];
216       unset($sourceOptions['condition']);
217     }
218
219     if (!isset($sourceOptions['raw_name']))
220     {
221       $source = stylesheet_path($source, $absolute);
222     }
223     else
224     {
225       unset($sourceOptions['raw_name']);
226     }
227
228     $options = array_merge(array('rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'screen', 'href' => $source), $sourceOptions);
229     $tag = tag('link', $options);
230
231     if (null !== $condition)
232     {
233       $tag = comment_as_conditional($condition, $tag);
234     }
235
236     $html .= $tag."\n";
237   }
238
239   return $html;
240 }
241
242 /**
243  * Adds a stylesheet to the response object.
244  *
245  * @see sfResponse->addStylesheet()
246  */
247 function use_stylesheet($css, $position = '', $options = array())
248 {
249   sfContext::getInstance()->getResponse()->addStylesheet($css, $position, $options);
250 }
251
252 /**
253  * Adds a javascript to the response object.
254  *
255  * @see sfResponse->addJavascript()
256  */
257 function use_javascript($js, $position = '', $options = array())
258 {
259   sfContext::getInstance()->getResponse()->addJavascript($js, $position, $options);
260 }
261
262 /**
263  * Decorates the current template with a given layout.
264  *
265  * @param mixed $layout The layout name or path or false to disable the layout
266  */
267 function decorate_with($layout)
268 {
269   if (false === $layout)
270   {
271     sfContext::getInstance()->get('view_instance')->setDecorator(false);
272   }
273   else
274   {
275     sfContext::getInstance()->get('view_instance')->setDecoratorTemplate($layout);
276   }
277 }
278
279 /**
280  * Returns the path to an image asset.
281  *
282  * <b>Example:</b>
283  * <code>
284  *  echo image_path('foobar');
285  *    => /images/foobar.png
286  * </code>
287  *
288  * <b>Note:</b> The asset name can be supplied as a...
289  * - full path, like "/my_images/image.gif"
290  * - file name, like "rss.gif", that gets expanded to "/images/rss.gif"
291  * - file name without extension, like "logo", that gets expanded to "/images/logo.png"
292  *
293  * @param string $source   asset name
294  * @param bool   $absolute return absolute path ?
295  *
296  * @return string file path to the image file
297  * @see    image_tag
298  */
299 function image_path($source, $absolute = false)
300 {
301   return _compute_public_path($source, sfConfig::get('sf_web_images_dir_name', 'images'), 'png', $absolute);
302 }
303
304 /**
305  * Returns an <img> image tag for the asset given as argument.
306  *
307  * <b>Options:</b>
308  * - 'absolute' - to output absolute file paths, useful for embedded images in emails
309  * - 'alt'  - defaults to the file name part of the asset (capitalized and without the extension)
310  * - 'size' - Supplied as "XxY", so "30x45" becomes width="30" and height="45"
311  *
312  * <b>Examples:</b>
313  * <code>
314  *  echo image_tag('foobar');
315  *    => <img src="images/foobar.png" alt="Foobar" />
316  *  echo image_tag('/my_images/image.gif', array('alt' => 'Alternative text', 'size' => '100x200'));
317  *    => <img src="/my_images/image.gif" alt="Alternative text" width="100" height="200" />
318  * </code>
319  *
320  * @param string $source  image asset name
321  * @param array  $options additional HTML compliant <img> tag parameters
322  *
323  * @return string XHTML compliant <img> tag
324  * @see    image_path
325  */
326 function image_tag($source, $options = array())
327 {
328   if (!$source)
329   {
330     return '';
331   }
332
333   $options = _parse_attributes($options);
334
335   $absolute = false;
336   if (isset($options['absolute']))
337   {
338     unset($options['absolute']);
339     $absolute = true;
340   }
341
342   if (!isset($options['raw_name']))
343   {
344     $options['src'] = image_path($source, $absolute);
345   }
346   else
347   {
348     $options['src'] = $source;
349     unset($options['raw_name']);
350   }
351
352   if (isset($options['alt_title']))
353   {
354     // set as alt and title but do not overwrite explicitly set
355     if (!isset($options['alt']))
356     {
357       $options['alt'] = $options['alt_title'];
358     }
359     if (!isset($options['title']))
360     {
361       $options['title'] = $options['alt_title'];
362     }
363     unset($options['alt_title']);
364   }
365
366   if (isset($options['size']))
367   {
368     list($options['width'], $options['height']) = explode('x', $options['size'], 2);
369     unset($options['size']);
370   }
371
372   return tag('img', $options);
373 }
374
375 function _compute_public_path($source, $dir, $ext, $absolute = false)
376 {
377   if (strpos($source, '://') || strpos($source, '//') === 0)
378   {
379     return $source;
380   }
381
382   $request = sfContext::getInstance()->getRequest();
383   $sf_relative_url_root = $request->getRelativeUrlRoot();
384   if (0 !== strpos($source, '/'))
385   {
386     $source = $sf_relative_url_root.'/'.$dir.'/'.$source;
387   }
388
389   $query_string = '';
390   if (false !== $pos = strpos($source, '?'))
391   {
392     $query_string = substr($source, $pos);
393     $source = substr($source, 0, $pos);
394   }
395
396   if (false === strpos(basename($source), '.'))
397   {
398     $source .= '.'.$ext;
399   }
400
401   if ($sf_relative_url_root && 0 !== strpos($source, $sf_relative_url_root))
402   {
403     $source = $sf_relative_url_root.$source;
404   }
405
406   if ($absolute)
407   {
408     $source = 'http'.($request->isSecure() ? 's' : '').'://'.$request->getHost().$source;
409   }
410
411   return $source.$query_string;
412 }
413
414 /**
415  * Prints a set of <meta> tags according to the response attributes,
416  * to be included in the <head> section of a HTML document.
417  *
418  * <b>Examples:</b>
419  * <code>
420  *  include_metas();
421  *    => <meta name="title" content="symfony - open-source PHP5 web framework" />
422  *       <meta name="robots" content="index, follow" />
423  *       <meta name="description" content="symfony - open-source PHP5 web framework" />
424  *       <meta name="keywords" content="symfony, project, framework, php, php5, open-source, mit, symphony" />
425  *       <meta name="language" content="en" /><link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
426  * </code>
427  *
428  * <b>Note:</b> Modify the view.yml or use sfWebResponse::addMeta() to change, add or remove metas.
429  *
430  * @return string XHTML compliant <meta> tag(s)
431  * @see    include_http_metas
432  * @see    sfWebResponse::addMeta()
433  */
434 function include_metas()
435 {
436   $context = sfContext::getInstance();
437   $i18n = sfConfig::get('sf_i18n') ? $context->getI18N() : null;
438   foreach ($context->getResponse()->getMetas() as $name => $content)
439   {
440     echo tag('meta', array('name' => $name, 'content' => null === $i18n ? $content : $i18n->__($content)))."\n";
441   }
442 }
443
444 /**
445  * Returns a set of <meta http-equiv> tags according to the response attributes,
446  * to be included in the <head> section of a HTML document.
447  *
448  * <b>Examples:</b>
449  * <code>
450  *  include_http_metas();
451  *    => <meta http-equiv="content-type" content="text/html; charset=utf-8" />
452  * </code>
453  *
454  * <b>Note:</b> Modify the view.yml or use sfWebResponse::addHttpMeta() to change, add or remove HTTP metas.
455  *
456  * @return string XHTML compliant <meta> tag(s)
457  * @see    include_metas
458  * @see    sfWebResponse::addHttpMeta()
459  */
460 function include_http_metas()
461 {
462   foreach (sfContext::getInstance()->getResponse()->getHttpMetas() as $httpequiv => $value)
463   {
464     echo tag('meta', array('http-equiv' => $httpequiv, 'content' => $value))."\n";
465   }
466 }
467
468 /**
469  * Returns the title of the current page according to the response attributes,
470  * to be included in the <title> section of a HTML document.
471  *
472  * <b>Note:</b> Modify the sfResponse object or the view.yml to modify the title of a page.
473  *
474  * @return string page title
475  */
476 function include_title()
477 {
478   $title = sfContext::getInstance()->getResponse()->getTitle();
479
480   echo content_tag('title', $title)."\n";
481 }
482
483 /**
484  * Returns <script> tags for all javascripts configured in view.yml or added to the response object.
485  *
486  * You can use this helper to decide the location of javascripts in pages.
487  * By default, if you don't call this helper, symfony will automatically include javascripts before </head>.
488  * Calling this helper disables this behavior.
489  *
490  * @return string <script> tags
491  */
492 function get_javascripts()
493 {
494   $response = sfContext::getInstance()->getResponse();
495   sfConfig::set('symfony.asset.javascripts_included', true);
496
497   $html = '';
498   foreach ($response->getJavascripts() as $file => $options)
499   {
500     $html .= javascript_include_tag($file, $options);
501   }
502
503   return $html;
504 }
505
506 /**
507  * Prints <script> tags for all javascripts configured in view.yml or added to the response object.
508  *
509  * @see get_javascripts()
510  */
511 function include_javascripts()
512 {
513   echo get_javascripts();
514 }
515
516 /**
517  * Returns <link> tags for all stylesheets configured in view.yml or added to the response object.
518  *
519  * You can use this helper to decide the location of stylesheets in pages.
520  * By default, if you don't call this helper, symfony will automatically include stylesheets before </head>.
521  * Calling this helper disables this behavior.
522  *
523  * @return string <link> tags
524  */
525 function get_stylesheets()
526 {
527   $response = sfContext::getInstance()->getResponse();
528   sfConfig::set('symfony.asset.stylesheets_included', true);
529
530   $html = '';
531   foreach ($response->getStylesheets() as $file => $options)
532   {
533     $html .= stylesheet_tag($file, $options);
534   }
535
536   return $html;
537 }
538
539 /**
540  * Prints <link> tags for all stylesheets configured in view.yml or added to the response object.
541  *
542  * @see get_stylesheets()
543  */
544 function include_stylesheets()
545 {
546   echo get_stylesheets();
547 }
548
549 /**
550  * Returns a <script> include tag for the given internal URI.
551  *
552  * The helper automatically adds the sf_format to the internal URI, so you don't have to.
553  *
554  * @param string $uri      The internal URI for the dynamic javascript
555  * @param bool   $absolute Whether to generate an absolute URL
556  * @param array  $options  An array of options
557  *
558  * @return string XHTML compliant <script> tag(s)
559  * @see    javascript_include_tag
560  */
561 function dynamic_javascript_include_tag($uri, $absolute = false, $options = array())
562 {
563   $options['raw_name'] = true;
564
565   return javascript_include_tag(_dynamic_path($uri, 'js', $absolute), $options);
566 }
567
568 /**
569  * Adds a dynamic javascript to the response object.
570  *
571  * The first argument is an internal URI.
572  * The helper automatically adds the sf_format to the internal URI, so you don't have to.
573  *
574  * @see sfResponse->addJavascript()
575  */
576 function use_dynamic_javascript($js, $position = '', $options = array())
577 {
578   $options['raw_name'] = true;
579
580   return use_javascript(_dynamic_path($js, 'js'), $position, $options);
581 }
582
583 /**
584  * Adds a dynamic stylesheet to the response object.
585  *
586  * The first argument is an internal URI.
587  * The helper automatically adds the sf_format to the internal URI, so you don't have to.
588  *
589  * @see sfResponse->addStylesheet()
590  */
591 function use_dynamic_stylesheet($css, $position = '', $options = array())
592 {
593   $options['raw_name'] = true;
594
595   return use_stylesheet(_dynamic_path($css, 'css'), $position, $options);
596 }
597
598 function _dynamic_path($uri, $format, $absolute = false)
599 {
600   return url_for($uri.(false === strpos($uri, '?') ? '?' : '&').'sf_format='.$format, $absolute);
601 }
602
603 /**
604  * Returns <script> tags for all javascripts associated with the given form.
605  *
606  * The scripts are set by implementing the getJavaScripts() method in the
607  * corresponding widget.
608  *
609  * <code>
610  * class MyWidget extends sfWidgetForm
611  * {
612  *   public function getJavaScripts()
613  *   {
614  *     return array('/path/to/a/file.js');
615  *   }
616  * }
617  * </code>
618  *
619  * @return string <script> tags
620  */
621 function get_javascripts_for_form(sfForm $form)
622 {
623   $html = '';
624   foreach ($form->getJavascripts() as $file)
625   {
626     $html .= javascript_include_tag($file);
627   }
628
629   return $html;
630 }
631
632 /**
633  * Prints <script> tags for all javascripts associated with the given form.
634  *
635  * @see get_javascripts_for_form()
636  */
637 function include_javascripts_for_form(sfForm $form)
638 {
639   echo get_javascripts_for_form($form);
640 }
641
642 /**
643  * Adds javascripts from the supplied form to the response object.
644  *
645  * @param sfForm $form
646  */
647 function use_javascripts_for_form(sfForm $form)
648 {
649   $response = sfContext::getInstance()->getResponse();
650
651   foreach ($form->getJavascripts() as $file)
652   {
653     $response->addJavascript($file);
654   }
655 }
656
657 /**
658  * Returns <link> tags for all stylesheets associated with the given form.
659  *
660  * The stylesheets are set by implementing the getStyleSheets() method in the
661  * corresponding widget.
662  *
663  * <code>
664  * class MyWidget extends sfWidgetForm
665  * {
666  *   public function getStyleSheets()
667  *   {
668  *     return array('/path/to/a/file.css');
669  *   }
670  * }
671  * </code>
672  *
673  * @return string <link> tags
674  */
675 function get_stylesheets_for_form(sfForm $form)
676 {
677   $html = '';
678   foreach ($form->getStylesheets() as $file => $media)
679   {
680     $html .= stylesheet_tag($file, array('media' => $media));
681   }
682
683   return $html;
684 }
685
686 /**
687  * Prints <link> tags for all stylesheets associated with the given form.
688  *
689  * @see get_stylesheets_for_form()
690  */
691 function include_stylesheets_for_form(sfForm $form)
692 {
693   echo get_stylesheets_for_form($form);
694 }
695
696 /**
697  * Adds stylesheets from the supplied form to the response object.
698  *
699  * @param sfForm $form
700  */
701 function use_stylesheets_for_form(sfForm $form)
702 {
703   $response = sfContext::getInstance()->getResponse();
704
705   foreach ($form->getStylesheets() as $file => $media)
706   {
707     $response->addStylesheet($file, '', array('media' => $media));
708   }
709 }
710
Note: See TracBrowser for help on using the browser.