diff options
301 files changed, 17705 insertions, 17700 deletions
@@ -1,2 +1,2 @@ # GNU/GPL v3 or later -see misc/license.txt
\ No newline at end of file +see misc/license.txt @@ -52,4 +52,4 @@ you can edit the number of visits to generate, the number of actions per visit, Contact ======= http://piwik.org -hello@piwik.org
\ No newline at end of file +hello@piwik.org diff --git a/config/config.ini.sample.php b/config/config.ini.sample.php index 33bc599e7c..9773615e72 100644 --- a/config/config.ini.sample.php +++ b/config/config.ini.sample.php @@ -15,4 +15,4 @@ username = databaseLogin password = datatabasePassword dbname = databaseName adapter = PDO_MYSQL ; PDO_MYSQL or MYSQLI -tables_prefix = piwik_
\ No newline at end of file +tables_prefix = piwik_ diff --git a/core/API/Request.php b/core/API/Request.php index aea6371410..fad7011683 100644 --- a/core/API/Request.php +++ b/core/API/Request.php @@ -137,4 +137,4 @@ class Piwik_API_Request return $a; } -}
\ No newline at end of file +} diff --git a/core/Access.php b/core/Access.php index 36a91f5c77..c9c7bc98d0 100644 --- a/core/Access.php +++ b/core/Access.php @@ -341,4 +341,4 @@ class Piwik_Access * @package Piwik */ class Piwik_Access_NoAccessException extends Exception -{}
\ No newline at end of file +{} diff --git a/core/Archive/Array/IndexedByDate.php b/core/Archive/Array/IndexedByDate.php index a396838df8..57ab78bb1c 100644 --- a/core/Archive/Array/IndexedByDate.php +++ b/core/Archive/Array/IndexedByDate.php @@ -115,4 +115,4 @@ class Piwik_Archive_Array_IndexedByDate extends Piwik_Archive_Array } return $tableArray; } -}
\ No newline at end of file +} diff --git a/core/Archive/Array/IndexedBySite.php b/core/Archive/Array/IndexedBySite.php index a9017263f6..1a27c10ce5 100644 --- a/core/Archive/Array/IndexedBySite.php +++ b/core/Archive/Array/IndexedBySite.php @@ -105,4 +105,4 @@ class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array { return $this->getFirstArchive()->archiveProcessing->getTableArchiveNumericName(); } -}
\ No newline at end of file +} diff --git a/core/Controller.php b/core/Controller.php index e544796d58..8c34079534 100644 --- a/core/Controller.php +++ b/core/Controller.php @@ -286,4 +286,4 @@ abstract class Piwik_Controller } exit; } -}
\ No newline at end of file +} diff --git a/core/DataTable/Filter/ColumnCallbackAddColumnPercentage.php b/core/DataTable/Filter/ColumnCallbackAddColumnPercentage.php index 7779a14482..191caab0bf 100644 --- a/core/DataTable/Filter/ColumnCallbackAddColumnPercentage.php +++ b/core/DataTable/Filter/ColumnCallbackAddColumnPercentage.php @@ -45,4 +45,4 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnPercentage extends Piwik_Dat $row->addColumn($this->columnNamePercentageToAdd, $percentage); } } -}
\ No newline at end of file +} diff --git a/core/DataTable/Renderer/Csv.php b/core/DataTable/Renderer/Csv.php index d311981c51..5d7d78774f 100644 --- a/core/DataTable/Renderer/Csv.php +++ b/core/DataTable/Renderer/Csv.php @@ -251,4 +251,4 @@ class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer } return $str; } -}
\ No newline at end of file +} diff --git a/core/DataTable/Renderer/Json.php b/core/DataTable/Renderer/Json.php index 729f2af98d..b147fcdee1 100644 --- a/core/DataTable/Renderer/Json.php +++ b/core/DataTable/Renderer/Json.php @@ -49,4 +49,4 @@ class Piwik_DataTable_Renderer_Json extends Piwik_DataTable_Renderer } return $str; } -}
\ No newline at end of file +} diff --git a/core/DataTable/Renderer/Php.php b/core/DataTable/Renderer/Php.php index fee43640f1..f59b7f4dcd 100644 --- a/core/DataTable/Renderer/Php.php +++ b/core/DataTable/Renderer/Php.php @@ -200,4 +200,4 @@ class Piwik_DataTable_Renderer_Php extends Piwik_DataTable_Renderer } return $array; } -}
\ No newline at end of file +} diff --git a/core/DataTable/Renderer/Xml.php b/core/DataTable/Renderer/Xml.php index 1b3a77866d..9a227fe19e 100644 --- a/core/DataTable/Renderer/Xml.php +++ b/core/DataTable/Renderer/Xml.php @@ -310,4 +310,4 @@ class Piwik_DataTable_Renderer_Xml extends Piwik_DataTable_Renderer $xml = '<?xml version="1.0" encoding="utf-8" ?>' . "\n" . $xml; return $xml; } -}
\ No newline at end of file +} diff --git a/core/Form.php b/core/Form.php index 4b931c9ec6..386c41b80d 100644 --- a/core/Form.php +++ b/core/Form.php @@ -98,4 +98,4 @@ function Piwik_Form_fieldHaveSameValue($element, $value, $arg) function Piwik_Form_isValidEmailString( $element, $value ) { return Piwik::isValidEmailString($value); -}
\ No newline at end of file +} diff --git a/core/Period/Range.php b/core/Period/Range.php index d2cfb8dcf9..d3cdc1982a 100644 --- a/core/Period/Range.php +++ b/core/Period/Range.php @@ -161,4 +161,4 @@ class Piwik_Period_Range extends Piwik_Period } return $range; } -}
\ No newline at end of file +} diff --git a/core/SmartyPlugins/modifier.translate.php b/core/SmartyPlugins/modifier.translate.php index 923b06654c..d6bde072c2 100644 --- a/core/SmartyPlugins/modifier.translate.php +++ b/core/SmartyPlugins/modifier.translate.php @@ -37,4 +37,4 @@ function smarty_modifier_translate($stringToken) } return vsprintf($stringTranslated, $aValues); } -
\ No newline at end of file + diff --git a/core/Tracker/Generator/Tracker.php b/core/Tracker/Generator/Tracker.php index 4344e2a515..051be3fa8d 100644 --- a/core/Tracker/Generator/Tracker.php +++ b/core/Tracker/Generator/Tracker.php @@ -54,4 +54,4 @@ class Piwik_Tracker_Generator_Tracker extends Piwik_Tracker { return; } -}
\ No newline at end of file +} diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php index d7f3b38726..c5e8dc215b 100644 --- a/core/Tracker/GoalManager.php +++ b/core/Tracker/GoalManager.php @@ -186,4 +186,4 @@ class Piwik_Tracker_GoalManager //$idlog_goal = Piwik_Tracker::getDatabase()->lastInsertId(); } } -}
\ No newline at end of file +} diff --git a/core/Tracker/javascriptTag.tpl b/core/Tracker/javascriptTag.tpl index 29f06a56b4..2387689008 100644 --- a/core/Tracker/javascriptTag.tpl +++ b/core/Tracker/javascriptTag.tpl @@ -10,4 +10,4 @@ piwik_url = pkBaseURL + "piwik.php"; piwik_log(piwik_action_name, piwik_idsite, piwik_url); </script> <object><noscript><p>{$hrefTitle} <img src="http://{$piwikUrl}piwik.php?idsite={$idSite}" style="border:0" alt=""/></p></noscript></object></a> -<!-- End Piwik Tag -->
\ No newline at end of file +<!-- End Piwik Tag --> diff --git a/core/Updates/0.2.12.php b/core/Updates/0.2.12.php index 5f15022f0d..308bbd1466 100644 --- a/core/Updates/0.2.12.php +++ b/core/Updates/0.2.12.php @@ -22,4 +22,4 @@ if($error) When you have executed these queries, you can manually edit the ". Piwik::prefixTable('option')." table in your Piwik database, ". " and set the piwik_version value to 0.2.12. "; throw new UpdateErrorException($message); -}
\ No newline at end of file +} diff --git a/core/View.php b/core/View.php index 7a1a6479c2..4beb317f69 100644 --- a/core/View.php +++ b/core/View.php @@ -144,4 +144,4 @@ class Piwik_View implements Piwik_iView $this->smarty->caching = $caching; } */ -}
\ No newline at end of file +} diff --git a/core/ViewDataTable/GenerateGraphData/ChartPie.php b/core/ViewDataTable/GenerateGraphData/ChartPie.php index 85c15f2b00..d26d8e74a5 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartPie.php +++ b/core/ViewDataTable/GenerateGraphData/ChartPie.php @@ -20,4 +20,4 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartPie extends Piwik_ViewDataTable require_once "Visualization/ChartPie.php"; $this->view = new Piwik_Visualization_ChartPie; } -}
\ No newline at end of file +} diff --git a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php b/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php index 9e3a372d39..3f20dbfde7 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php +++ b/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php @@ -20,4 +20,4 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar extends Piwik_ViewD require_once "Visualization/ChartVerticalBar.php"; $this->view = new Piwik_Visualization_ChartVerticalBar; } -}
\ No newline at end of file +} diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php index 98fa9323a8..c169cdcf26 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php @@ -48,4 +48,4 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat { $this->setParametersToModify( array('columns' => $columnsNames) ); } -}
\ No newline at end of file +} diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartPie.php b/core/ViewDataTable/GenerateGraphHTML/ChartPie.php index 39e744fd0b..6e94e998cf 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartPie.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartPie.php @@ -17,4 +17,4 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartPie extends Piwik_ViewDataTable { return 'generateDataChartPie'; } -}
\ No newline at end of file +} diff --git a/core/Visualization/Chart.php b/core/Visualization/Chart.php index a80ac489db..d9ecc64adb 100644 --- a/core/Visualization/Chart.php +++ b/core/Visualization/Chart.php @@ -84,4 +84,4 @@ abstract class Piwik_Visualization_Chart extends Piwik_Visualization_OpenFlashCh } } -}
\ No newline at end of file +} diff --git a/core/Visualization/ChartPie.php b/core/Visualization/ChartPie.php index 08dc54beb0..3cb67fa9a1 100644 --- a/core/Visualization/ChartPie.php +++ b/core/Visualization/ChartPie.php @@ -38,4 +38,4 @@ class Piwik_Visualization_ChartPie extends Piwik_Visualization_Chart } -}
\ No newline at end of file +} diff --git a/core/Visualization/ChartVerticalBar.php b/core/Visualization/ChartVerticalBar.php index bfb820f586..d030f8fda3 100644 --- a/core/Visualization/ChartVerticalBar.php +++ b/core/Visualization/ChartVerticalBar.php @@ -35,4 +35,4 @@ class Piwik_Visualization_ChartVerticalBar extends Piwik_Visualization_Chart $this->bar_filled( 50, '#3B5AA9', '#063E7E', 'visits', 10 ); } -}
\ No newline at end of file +} diff --git a/core/Visualization/OpenFlashChart.php b/core/Visualization/OpenFlashChart.php index 1e85492c5c..bfa6a70689 100644 --- a/core/Visualization/OpenFlashChart.php +++ b/core/Visualization/OpenFlashChart.php @@ -1644,4 +1644,4 @@ class point } // PIWIK SPECIAL ALIAS HACK - when updating Open Flash Chart, leave this line unchanged -class graph extends Piwik_Visualization_OpenFlashChart {}
\ No newline at end of file +class graph extends Piwik_Visualization_OpenFlashChart {} diff --git a/core/iView.php b/core/iView.php index 82bb01bcd3..04c93c6600 100644 --- a/core/iView.php +++ b/core/iView.php @@ -24,4 +24,4 @@ interface Piwik_iView * */ function render(); -}
\ No newline at end of file +} diff --git a/lang/ca.php b/lang/ca.php index cf760b2ade..56ee8bbb48 100644 --- a/lang/ca.php +++ b/lang/ca.php @@ -615,4 +615,4 @@ Podeu configurar els seus permisos a dalt.', 'General_ColumnUniquePageviews' => 'Visualitzacions de pàgina úniques', 'General_DisplayNormalTable' => 'Mostra una taula normal', 'General_DisplayMoreData' => 'Mostra més dades', -);
\ No newline at end of file +); diff --git a/lang/cn.php b/lang/cn.php index ff48d09a95..6cf250c429 100644 --- a/lang/cn.php +++ b/lang/cn.php @@ -592,4 +592,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => '语系代码', 'TranslationsAdmin_Export' => '汇出语系', 'TranslationsAdmin_Import' => '汇入语系', -);
\ No newline at end of file +); diff --git a/lang/de.php b/lang/de.php index 6727967d70..9f3d693ed1 100644 --- a/lang/de.php +++ b/lang/de.php @@ -594,4 +594,4 @@ $translations = array( 'VisitTime_SubmenuTimes' => 'Zeiten', 'VisitTime_NHour' => '%sh', 'Installation_ContinueToPiwik' => '', -);
\ No newline at end of file +); diff --git a/lang/en.php b/lang/en.php index a9de42d8f7..6908d35c82 100644 --- a/lang/en.php +++ b/lang/en.php @@ -607,4 +607,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Language code', 'TranslationsAdmin_Export' => 'Export language', 'TranslationsAdmin_Import' => 'Import language', -);
\ No newline at end of file +); diff --git a/lang/es.php b/lang/es.php index 2073e0181a..3879d81e3b 100644 --- a/lang/es.php +++ b/lang/es.php @@ -534,4 +534,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Código de idioma', 'TranslationsAdmin_Export' => 'Exportar idioma', 'TranslationsAdmin_Import' => 'Importar idioma', -);
\ No newline at end of file +); diff --git a/lang/ja.php b/lang/ja.php index 53e03fc2dd..facfa20680 100644 --- a/lang/ja.php +++ b/lang/ja.php @@ -590,4 +590,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => '言語コード', 'TranslationsAdmin_Export' => '言語のエクスポート', 'TranslationsAdmin_Import' => '言語のインポート', -);
\ No newline at end of file +); diff --git a/lang/nl.php b/lang/nl.php index 6337235da0..6a88e12d3f 100644 --- a/lang/nl.php +++ b/lang/nl.php @@ -591,4 +591,4 @@ $translations = array( 'VisitsSummary_WidgetLastVisitors' => 'Recente unieke bezoekers', 'VisitsSummary_WidgetOverviewGraph' => 'Totalen', 'VisitsSummary_SubmenuOverview' => 'Totalen', -);
\ No newline at end of file +); diff --git a/lang/no.php b/lang/no.php index ad24945631..0dd233c9ea 100644 --- a/lang/no.php +++ b/lang/no.php @@ -611,4 +611,4 @@ $translations = array( 'VisitsSummary_WidgetLastVisitors' => 'Siste unike beslkende', 'VisitsSummary_WidgetOverviewGraph' => 'Oversikt med grafikk', 'VisitsSummary_SubmenuOverview' => 'Oversikt', -);
\ No newline at end of file +); diff --git a/lang/pl.php b/lang/pl.php index d48ee6591c..2cd8180242 100644 --- a/lang/pl.php +++ b/lang/pl.php @@ -542,4 +542,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Kod języka', 'TranslationsAdmin_Export' => 'Eksportuj język', 'TranslationsAdmin_Import' => 'Importuj język', -);
\ No newline at end of file +); diff --git a/lang/pt.php b/lang/pt.php index e1900a5723..96b4b9d0be 100644 --- a/lang/pt.php +++ b/lang/pt.php @@ -544,4 +544,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Código do Idioma', 'TranslationsAdmin_Export' => 'Exportar Idioma', 'TranslationsAdmin_Import' => 'Importar Idioma', -);
\ No newline at end of file +); diff --git a/lang/ru.php b/lang/ru.php index d85128b326..a2e45600ef 100644 --- a/lang/ru.php +++ b/lang/ru.php @@ -544,4 +544,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Код языка', 'TranslationsAdmin_Export' => 'Экспорт языкового файла', 'TranslationsAdmin_Import' => 'Импорт языкового файла', -);
\ No newline at end of file +); diff --git a/lang/sk.php b/lang/sk.php index f5c156dfc8..935a6f6273 100644 --- a/lang/sk.php +++ b/lang/sk.php @@ -614,4 +614,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Kód jazyka', 'TranslationsAdmin_Export' => 'Exportovať jazyk', 'TranslationsAdmin_Import' => 'Importovať jazyk', -);
\ No newline at end of file +); diff --git a/lang/sr.php b/lang/sr.php index 3c36d9e320..e4982f5ec5 100644 --- a/lang/sr.php +++ b/lang/sr.php @@ -611,4 +611,4 @@ $translations = array( 'General_Settings' => 'Podešavanja', 'General_GiveUsYourFeedback' => 'Recite nam šta mislite!', 'General_YouAreCurrentlyViewingDemoOfPiwik' => 'Trenutno koristite demo verziju %s; %spreuzmite%s punu verziju! Posetite %s', -);
\ No newline at end of file +); diff --git a/lang/sv.php b/lang/sv.php index 6269b6e7cc..1b6f797968 100644 --- a/lang/sv.php +++ b/lang/sv.php @@ -605,4 +605,4 @@ $translations = array( 'VisitTime_WidgetServerTime' => 'Besök efter servertid', 'VisitTime_SubmenuTimes' => 'Tider', 'VisitTime_NHour' => '%sh', -);
\ No newline at end of file +); diff --git a/lang/tw.php b/lang/tw.php index 2ac02b57e3..393b8d0e87 100644 --- a/lang/tw.php +++ b/lang/tw.php @@ -605,4 +605,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => '語系代碼', 'TranslationsAdmin_Export' => '匯出語系', 'TranslationsAdmin_Import' => '匯入語系', -);
\ No newline at end of file +); diff --git a/lang/uk.php b/lang/uk.php index d5faaf1acb..59fe6cd2fd 100644 --- a/lang/uk.php +++ b/lang/uk.php @@ -534,4 +534,4 @@ $translations = array( 'TranslationsAdmin_LanguageCode' => 'Код мови', 'TranslationsAdmin_Export' => 'Експортувати мову', 'TranslationsAdmin_Import' => 'Імпортувати мову', -);
\ No newline at end of file +); diff --git a/libs/Event/Dispatcher.php b/libs/Event/Dispatcher.php index 5cfee865ae..fe64305875 100755 --- a/libs/Event/Dispatcher.php +++ b/libs/Event/Dispatcher.php @@ -475,4 +475,4 @@ class Event_Dispatcher } } -?>
\ No newline at end of file +?> diff --git a/libs/Event/Notification.php b/libs/Event/Notification.php index 6a42e5a312..58d08fa4cf 100755 --- a/libs/Event/Notification.php +++ b/libs/Event/Notification.php @@ -191,4 +191,4 @@ class Event_Notification return ($this->_notificationState === EVENT_NOTIFICATION_STATE_CANCELLED); } } -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm.php b/libs/HTML/QuickForm.php index ff5f8395dc..d589c9b4cf 100755 --- a/libs/HTML/QuickForm.php +++ b/libs/HTML/QuickForm.php @@ -2051,4 +2051,4 @@ class HTML_QuickForm_Error extends PEAR_Error { // }}} } // end class HTML_QuickForm_Error -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Renderer/Array.php b/libs/HTML/QuickForm/Renderer/Array.php index fd2fefc60e..1f5f7253d1 100755 --- a/libs/HTML/QuickForm/Renderer/Array.php +++ b/libs/HTML/QuickForm/Renderer/Array.php @@ -337,4 +337,4 @@ class HTML_QuickForm_Renderer_Array extends HTML_QuickForm_Renderer } } } -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Renderer/ArraySmarty.php b/libs/HTML/QuickForm/Renderer/ArraySmarty.php index 6eb06dc2c8..4a7a4c8601 100755 --- a/libs/HTML/QuickForm/Renderer/ArraySmarty.php +++ b/libs/HTML/QuickForm/Renderer/ArraySmarty.php @@ -399,4 +399,4 @@ class HTML_QuickForm_Renderer_ArraySmarty extends HTML_QuickForm_Renderer_Array $this->_error = $template; } // end func setErrorTemplate } -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Rule.php b/libs/HTML/QuickForm/Rule.php index 4870ad1720..18442b2ded 100755 --- a/libs/HTML/QuickForm/Rule.php +++ b/libs/HTML/QuickForm/Rule.php @@ -79,4 +79,4 @@ class HTML_QuickForm_Rule return array('', ''); } } -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Rule/Callback.php b/libs/HTML/QuickForm/Rule/Callback.php index d5dec846a6..4589da9012 100755 --- a/libs/HTML/QuickForm/Rule/Callback.php +++ b/libs/HTML/QuickForm/Rule/Callback.php @@ -121,4 +121,4 @@ class HTML_QuickForm_Rule_Callback extends HTML_QuickForm_Rule } // end func getValidationScript } // end class HTML_QuickForm_Rule_Callback -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Rule/Email.php b/libs/HTML/QuickForm/Rule/Email.php index 06ca30f172..97e0ca18ac 100755 --- a/libs/HTML/QuickForm/Rule/Email.php +++ b/libs/HTML/QuickForm/Rule/Email.php @@ -70,4 +70,4 @@ class HTML_QuickForm_Rule_Email extends HTML_QuickForm_Rule } // end func getValidationScript } // end class HTML_QuickForm_Rule_Email -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Rule/Range.php b/libs/HTML/QuickForm/Rule/Range.php index 76f1837a3e..40cce15c2c 100755 --- a/libs/HTML/QuickForm/Rule/Range.php +++ b/libs/HTML/QuickForm/Rule/Range.php @@ -72,4 +72,4 @@ class HTML_QuickForm_Rule_Range extends HTML_QuickForm_Rule } // end func getValidationScript } // end class HTML_QuickForm_Rule_Range -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/Rule/Regex.php b/libs/HTML/QuickForm/Rule/Regex.php index 2417a022e2..0607a44ae9 100755 --- a/libs/HTML/QuickForm/Rule/Regex.php +++ b/libs/HTML/QuickForm/Rule/Regex.php @@ -98,4 +98,4 @@ class HTML_QuickForm_Rule_Regex extends HTML_QuickForm_Rule } // end func getValidationScript } // end class HTML_QuickForm_Rule_Regex -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/date.php b/libs/HTML/QuickForm/date.php index 9e897a3e3a..15781ac59b 100755 --- a/libs/HTML/QuickForm/date.php +++ b/libs/HTML/QuickForm/date.php @@ -508,4 +508,4 @@ class HTML_QuickForm_date extends HTML_QuickForm_group // }}} } -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/element.php b/libs/HTML/QuickForm/element.php index 9fbe41ef1f..1312a18e84 100755 --- a/libs/HTML/QuickForm/element.php +++ b/libs/HTML/QuickForm/element.php @@ -491,4 +491,4 @@ class HTML_QuickForm_element extends HTML_Common // }}} } // end class HTML_QuickForm_element -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/group.php b/libs/HTML/QuickForm/group.php index f90641b7d9..0a7d661630 100755 --- a/libs/HTML/QuickForm/group.php +++ b/libs/HTML/QuickForm/group.php @@ -585,4 +585,4 @@ class HTML_QuickForm_group extends HTML_QuickForm_element // }}} } //end class HTML_QuickForm_group -?>
\ No newline at end of file +?> diff --git a/libs/HTML/QuickForm/hierselect.php b/libs/HTML/QuickForm/hierselect.php index 89a9500806..2e9d111006 100755 --- a/libs/HTML/QuickForm/hierselect.php +++ b/libs/HTML/QuickForm/hierselect.php @@ -590,4 +590,4 @@ JAVASCRIPT; // }}} } // end class HTML_QuickForm_hierselect -?>
\ No newline at end of file +?> diff --git a/libs/Smarty/Config_File.class.php b/libs/Smarty/Config_File.class.php index 425afcbfe7..83c1708887 100755 --- a/libs/Smarty/Config_File.class.php +++ b/libs/Smarty/Config_File.class.php @@ -1,393 +1,393 @@ -<?php
-
-/**
- * Config_File class.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For questions, help, comments, discussion, etc., please join the
- * Smarty mailing list. Send a blank e-mail to
- * smarty-discussion-subscribe@googlegroups.com
- *
- * @link http://www.smarty.net/
- * @version 2.6.22
- * @copyright Copyright: 2001-2005 New Digital Group, Inc.
- * @author Andrei Zmievski <andrei@php.net>
- * @access public
- * @package Smarty
- */
-
-/* $Id$ */
-
-/**
- * Config file reading class
- * @package Smarty
- */
-class Config_File {
- /**#@+
- * Options
- * @var boolean
- */
- /**
- * Controls whether variables with the same name overwrite each other.
- */
- var $overwrite = true;
-
- /**
- * Controls whether config values of on/true/yes and off/false/no get
- * converted to boolean values automatically.
- */
- var $booleanize = true;
-
- /**
- * Controls whether hidden config sections/vars are read from the file.
- */
- var $read_hidden = true;
-
- /**
- * Controls whether or not to fix mac or dos formatted newlines.
- * If set to true, \r or \r\n will be changed to \n.
- */
- var $fix_newlines = true;
- /**#@-*/
-
- /** @access private */
- var $_config_path = "";
- var $_config_data = array();
- /**#@-*/
-
- /**
- * Constructs a new config file class.
- *
- * @param string $config_path (optional) path to the config files
- */
- function Config_File($config_path = NULL)
- {
- if (isset($config_path))
- $this->set_path($config_path);
- }
-
-
- /**
- * Set the path where configuration files can be found.
- *
- * @param string $config_path path to the config files
- */
- function set_path($config_path)
- {
- if (!empty($config_path)) {
- if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
- $this->_trigger_error_msg("Bad config file path '$config_path'");
- return;
- }
- if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
- $config_path .= DIRECTORY_SEPARATOR;
- }
-
- $this->_config_path = $config_path;
- }
- }
-
-
- /**
- * Retrieves config info based on the file, section, and variable name.
- *
- * @param string $file_name config file to get info for
- * @param string $section_name (optional) section to get info for
- * @param string $var_name (optional) variable to get info for
- * @return string|array a value or array of values
- */
- function get($file_name, $section_name = NULL, $var_name = NULL)
- {
- if (empty($file_name)) {
- $this->_trigger_error_msg('Empty config file name');
- return;
- } else {
- $file_name = $this->_config_path . $file_name;
- if (!isset($this->_config_data[$file_name]))
- $this->load_file($file_name, false);
- }
-
- if (!empty($var_name)) {
- if (empty($section_name)) {
- return $this->_config_data[$file_name]["vars"][$var_name];
- } else {
- if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
- return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
- else
- return array();
- }
- } else {
- if (empty($section_name)) {
- return (array)$this->_config_data[$file_name]["vars"];
- } else {
- if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
- return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
- else
- return array();
- }
- }
- }
-
-
- /**
- * Retrieves config info based on the key.
- *
- * @param $file_name string config key (filename/section/var)
- * @return string|array same as get()
- * @uses get() retrieves information from config file and returns it
- */
- function &get_key($config_key)
- {
- list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
- $result = &$this->get($file_name, $section_name, $var_name);
- return $result;
- }
-
- /**
- * Get all loaded config file names.
- *
- * @return array an array of loaded config file names
- */
- function get_file_names()
- {
- return array_keys($this->_config_data);
- }
-
-
- /**
- * Get all section names from a loaded file.
- *
- * @param string $file_name config file to get section names from
- * @return array an array of section names from the specified file
- */
- function get_section_names($file_name)
- {
- $file_name = $this->_config_path . $file_name;
- if (!isset($this->_config_data[$file_name])) {
- $this->_trigger_error_msg("Unknown config file '$file_name'");
- return;
- }
-
- return array_keys($this->_config_data[$file_name]["sections"]);
- }
-
-
- /**
- * Get all global or section variable names.
- *
- * @param string $file_name config file to get info for
- * @param string $section_name (optional) section to get info for
- * @return array an array of variables names from the specified file/section
- */
- function get_var_names($file_name, $section = NULL)
- {
- if (empty($file_name)) {
- $this->_trigger_error_msg('Empty config file name');
- return;
- } else if (!isset($this->_config_data[$file_name])) {
- $this->_trigger_error_msg("Unknown config file '$file_name'");
- return;
- }
-
- if (empty($section))
- return array_keys($this->_config_data[$file_name]["vars"]);
- else
- return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
- }
-
-
- /**
- * Clear loaded config data for a certain file or all files.
- *
- * @param string $file_name file to clear config data for
- */
- function clear($file_name = NULL)
- {
- if ($file_name === NULL)
- $this->_config_data = array();
- else if (isset($this->_config_data[$file_name]))
- $this->_config_data[$file_name] = array();
- }
-
-
- /**
- * Load a configuration file manually.
- *
- * @param string $file_name file name to load
- * @param boolean $prepend_path whether current config path should be
- * prepended to the filename
- */
- function load_file($file_name, $prepend_path = true)
- {
- if ($prepend_path && $this->_config_path != "")
- $config_file = $this->_config_path . $file_name;
- else
- $config_file = $file_name;
-
- ini_set('track_errors', true);
- $fp = @fopen($config_file, "r");
- if (!is_resource($fp)) {
- $this->_trigger_error_msg("Could not open config file '$config_file'");
- return false;
- }
-
- $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
- fclose($fp);
-
- $this->_config_data[$config_file] = $this->parse_contents($contents);
- return true;
- }
-
- /**
- * Store the contents of a file manually.
- *
- * @param string $config_file file name of the related contents
- * @param string $contents the file-contents to parse
- */
- function set_file_contents($config_file, $contents)
- {
- $this->_config_data[$config_file] = $this->parse_contents($contents);
- return true;
- }
-
- /**
- * parse the source of a configuration file manually.
- *
- * @param string $contents the file-contents to parse
- */
- function parse_contents($contents)
- {
- if($this->fix_newlines) {
- // fix mac/dos formatted newlines
- $contents = preg_replace('!\r\n?!', "\n", $contents);
- }
-
- $config_data = array();
- $config_data['sections'] = array();
- $config_data['vars'] = array();
-
- /* reference to fill with data */
- $vars =& $config_data['vars'];
-
- /* parse file line by line */
- preg_match_all('!^.*\r?\n?!m', $contents, $match);
- $lines = $match[0];
- for ($i=0, $count=count($lines); $i<$count; $i++) {
- $line = $lines[$i];
- if (empty($line)) continue;
-
- if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
- /* section found */
- if (substr($match[1], 0, 1) == '.') {
- /* hidden section */
- if ($this->read_hidden) {
- $section_name = substr($match[1], 1);
- } else {
- /* break reference to $vars to ignore hidden section */
- unset($vars);
- $vars = array();
- continue;
- }
- } else {
- $section_name = $match[1];
- }
- if (!isset($config_data['sections'][$section_name]))
- $config_data['sections'][$section_name] = array('vars' => array());
- $vars =& $config_data['sections'][$section_name]['vars'];
- continue;
- }
-
- if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
- /* variable found */
- $var_name = rtrim($match[1]);
- if (strpos($match[2], '"""') === 0) {
- /* handle multiline-value */
- $lines[$i] = substr($match[2], 3);
- $var_value = '';
- while ($i<$count) {
- if (($pos = strpos($lines[$i], '"""')) === false) {
- $var_value .= $lines[$i++];
- } else {
- /* end of multiline-value */
- $var_value .= substr($lines[$i], 0, $pos);
- break;
- }
- }
- $booleanize = false;
-
- } else {
- /* handle simple value */
- $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
- $booleanize = $this->booleanize;
-
- }
- $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
- }
- /* else unparsable line / means it is a comment / means ignore it */
- }
- return $config_data;
- }
-
- /**#@+ @access private */
- /**
- * @param array &$container
- * @param string $var_name
- * @param mixed $var_value
- * @param boolean $booleanize determines whether $var_value is converted to
- * to true/false
- */
- function _set_config_var(&$container, $var_name, $var_value, $booleanize)
- {
- if (substr($var_name, 0, 1) == '.') {
- if (!$this->read_hidden)
- return;
- else
- $var_name = substr($var_name, 1);
- }
-
- if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
- $this->_trigger_error_msg("Bad variable name '$var_name'");
- return;
- }
-
- if ($booleanize) {
- if (preg_match("/^(on|true|yes)$/i", $var_value))
- $var_value = true;
- else if (preg_match("/^(off|false|no)$/i", $var_value))
- $var_value = false;
- }
-
- if (!isset($container[$var_name]) || $this->overwrite)
- $container[$var_name] = $var_value;
- else {
- settype($container[$var_name], 'array');
- $container[$var_name][] = $var_value;
- }
- }
-
- /**
- * @uses trigger_error() creates a PHP warning/error
- * @param string $error_msg
- * @param integer $error_type one of
- */
- function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
- {
- trigger_error("Config_File error: $error_msg", $error_type);
- }
- /**#@-*/
-}
-
-?>
+<?php + +/** + * Config_File class. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For questions, help, comments, discussion, etc., please join the + * Smarty mailing list. Send a blank e-mail to + * smarty-discussion-subscribe@googlegroups.com + * + * @link http://www.smarty.net/ + * @version 2.6.22 + * @copyright Copyright: 2001-2005 New Digital Group, Inc. + * @author Andrei Zmievski <andrei@php.net> + * @access public + * @package Smarty + */ + +/* $Id$ */ + +/** + * Config file reading class + * @package Smarty + */ +class Config_File { + /**#@+ + * Options + * @var boolean + */ + /** + * Controls whether variables with the same name overwrite each other. + */ + var $overwrite = true; + + /** + * Controls whether config values of on/true/yes and off/false/no get + * converted to boolean values automatically. + */ + var $booleanize = true; + + /** + * Controls whether hidden config sections/vars are read from the file. + */ + var $read_hidden = true; + + /** + * Controls whether or not to fix mac or dos formatted newlines. + * If set to true, \r or \r\n will be changed to \n. + */ + var $fix_newlines = true; + /**#@-*/ + + /** @access private */ + var $_config_path = ""; + var $_config_data = array(); + /**#@-*/ + + /** + * Constructs a new config file class. + * + * @param string $config_path (optional) path to the config files + */ + function Config_File($config_path = NULL) + { + if (isset($config_path)) + $this->set_path($config_path); + } + + + /** + * Set the path where configuration files can be found. + * + * @param string $config_path path to the config files + */ + function set_path($config_path) + { + if (!empty($config_path)) { + if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { + $this->_trigger_error_msg("Bad config file path '$config_path'"); + return; + } + if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { + $config_path .= DIRECTORY_SEPARATOR; + } + + $this->_config_path = $config_path; + } + } + + + /** + * Retrieves config info based on the file, section, and variable name. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @param string $var_name (optional) variable to get info for + * @return string|array a value or array of values + */ + function get($file_name, $section_name = NULL, $var_name = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) + $this->load_file($file_name, false); + } + + if (!empty($var_name)) { + if (empty($section_name)) { + return $this->_config_data[$file_name]["vars"][$var_name]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) + return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; + else + return array(); + } + } else { + if (empty($section_name)) { + return (array)$this->_config_data[$file_name]["vars"]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) + return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; + else + return array(); + } + } + } + + + /** + * Retrieves config info based on the key. + * + * @param $file_name string config key (filename/section/var) + * @return string|array same as get() + * @uses get() retrieves information from config file and returns it + */ + function &get_key($config_key) + { + list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); + $result = &$this->get($file_name, $section_name, $var_name); + return $result; + } + + /** + * Get all loaded config file names. + * + * @return array an array of loaded config file names + */ + function get_file_names() + { + return array_keys($this->_config_data); + } + + + /** + * Get all section names from a loaded file. + * + * @param string $file_name config file to get section names from + * @return array an array of section names from the specified file + */ + function get_section_names($file_name) + { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + return array_keys($this->_config_data[$file_name]["sections"]); + } + + + /** + * Get all global or section variable names. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @return array an array of variables names from the specified file/section + */ + function get_var_names($file_name, $section = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + if (empty($section)) + return array_keys($this->_config_data[$file_name]["vars"]); + else + return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); + } + + + /** + * Clear loaded config data for a certain file or all files. + * + * @param string $file_name file to clear config data for + */ + function clear($file_name = NULL) + { + if ($file_name === NULL) + $this->_config_data = array(); + else if (isset($this->_config_data[$file_name])) + $this->_config_data[$file_name] = array(); + } + + + /** + * Load a configuration file manually. + * + * @param string $file_name file name to load + * @param boolean $prepend_path whether current config path should be + * prepended to the filename + */ + function load_file($file_name, $prepend_path = true) + { + if ($prepend_path && $this->_config_path != "") + $config_file = $this->_config_path . $file_name; + else + $config_file = $file_name; + + ini_set('track_errors', true); + $fp = @fopen($config_file, "r"); + if (!is_resource($fp)) { + $this->_trigger_error_msg("Could not open config file '$config_file'"); + return false; + } + + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; + fclose($fp); + + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * Store the contents of a file manually. + * + * @param string $config_file file name of the related contents + * @param string $contents the file-contents to parse + */ + function set_file_contents($config_file, $contents) + { + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * parse the source of a configuration file manually. + * + * @param string $contents the file-contents to parse + */ + function parse_contents($contents) + { + if($this->fix_newlines) { + // fix mac/dos formatted newlines + $contents = preg_replace('!\r\n?!', "\n", $contents); + } + + $config_data = array(); + $config_data['sections'] = array(); + $config_data['vars'] = array(); + + /* reference to fill with data */ + $vars =& $config_data['vars']; + + /* parse file line by line */ + preg_match_all('!^.*\r?\n?!m', $contents, $match); + $lines = $match[0]; + for ($i=0, $count=count($lines); $i<$count; $i++) { + $line = $lines[$i]; + if (empty($line)) continue; + + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { + /* section found */ + if (substr($match[1], 0, 1) == '.') { + /* hidden section */ + if ($this->read_hidden) { + $section_name = substr($match[1], 1); + } else { + /* break reference to $vars to ignore hidden section */ + unset($vars); + $vars = array(); + continue; + } + } else { + $section_name = $match[1]; + } + if (!isset($config_data['sections'][$section_name])) + $config_data['sections'][$section_name] = array('vars' => array()); + $vars =& $config_data['sections'][$section_name]['vars']; + continue; + } + + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { + /* variable found */ + $var_name = rtrim($match[1]); + if (strpos($match[2], '"""') === 0) { + /* handle multiline-value */ + $lines[$i] = substr($match[2], 3); + $var_value = ''; + while ($i<$count) { + if (($pos = strpos($lines[$i], '"""')) === false) { + $var_value .= $lines[$i++]; + } else { + /* end of multiline-value */ + $var_value .= substr($lines[$i], 0, $pos); + break; + } + } + $booleanize = false; + + } else { + /* handle simple value */ + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); + $booleanize = $this->booleanize; + + } + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); + } + /* else unparsable line / means it is a comment / means ignore it */ + } + return $config_data; + } + + /**#@+ @access private */ + /** + * @param array &$container + * @param string $var_name + * @param mixed $var_value + * @param boolean $booleanize determines whether $var_value is converted to + * to true/false + */ + function _set_config_var(&$container, $var_name, $var_value, $booleanize) + { + if (substr($var_name, 0, 1) == '.') { + if (!$this->read_hidden) + return; + else + $var_name = substr($var_name, 1); + } + + if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { + $this->_trigger_error_msg("Bad variable name '$var_name'"); + return; + } + + if ($booleanize) { + if (preg_match("/^(on|true|yes)$/i", $var_value)) + $var_value = true; + else if (preg_match("/^(off|false|no)$/i", $var_value)) + $var_value = false; + } + + if (!isset($container[$var_name]) || $this->overwrite) + $container[$var_name] = $var_value; + else { + settype($container[$var_name], 'array'); + $container[$var_name][] = $var_value; + } + } + + /** + * @uses trigger_error() creates a PHP warning/error + * @param string $error_msg + * @param integer $error_type one of + */ + function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Config_File error: $error_msg", $error_type); + } + /**#@-*/ +} + +?> diff --git a/libs/Smarty/Smarty.class.php b/libs/Smarty/Smarty.class.php index bca967f219..4a3a7cde2c 100755 --- a/libs/Smarty/Smarty.class.php +++ b/libs/Smarty/Smarty.class.php @@ -1,1962 +1,1962 @@ -<?php
-
-/**
- * Project: Smarty: the PHP compiling template engine
- * File: Smarty.class.php
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For questions, help, comments, discussion, etc., please join the
- * Smarty mailing list. Send a blank e-mail to
- * smarty-discussion-subscribe@googlegroups.com
- *
- * @link http://www.smarty.net/
- * @copyright 2001-2005 New Digital Group, Inc.
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Andrei Zmievski <andrei@php.net>
- * @package Smarty
- * @version 2.6.22
- */
-
-/* $Id$ */
-
-/**
- * DIR_SEP isn't used anymore, but third party apps might
- */
-if(!defined('DIR_SEP')) {
- define('DIR_SEP', DIRECTORY_SEPARATOR);
-}
-
-/**
- * set SMARTY_DIR to absolute path to Smarty library files.
- * if not defined, include_path will be used. Sets SMARTY_DIR only if user
- * application has not already defined it.
- */
-
-if (!defined('SMARTY_DIR')) {
- define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
-}
-
-if (!defined('SMARTY_CORE_DIR')) {
- define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
-}
-
-define('SMARTY_PHP_PASSTHRU', 0);
-define('SMARTY_PHP_QUOTE', 1);
-define('SMARTY_PHP_REMOVE', 2);
-define('SMARTY_PHP_ALLOW', 3);
-
-/**
- * @package Smarty
- */
-class Smarty
-{
- /**#@+
- * Smarty Configuration Section
- */
-
- /**
- * The name of the directory where templates are located.
- *
- * @var string
- */
- var $template_dir = 'templates';
-
- /**
- * The directory where compiled templates are located.
- *
- * @var string
- */
- var $compile_dir = 'templates_c';
-
- /**
- * The directory where config files are located.
- *
- * @var string
- */
- var $config_dir = 'configs';
-
- /**
- * An array of directories searched for plugins.
- *
- * @var array
- */
- var $plugins_dir = array('plugins');
-
- /**
- * If debugging is enabled, a debug console window will display
- * when the page loads (make sure your browser allows unrequested
- * popup windows)
- *
- * @var boolean
- */
- var $debugging = false;
-
- /**
- * When set, smarty does uses this value as error_reporting-level.
- *
- * @var boolean
- */
- var $error_reporting = null;
-
- /**
- * This is the path to the debug console template. If not set,
- * the default one will be used.
- *
- * @var string
- */
- var $debug_tpl = '';
-
- /**
- * This determines if debugging is enable-able from the browser.
- * <ul>
- * <li>NONE => no debugging control allowed</li>
- * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
- * </ul>
- * @link http://www.foo.dom/index.php?SMARTY_DEBUG
- * @var string
- */
- var $debugging_ctrl = 'NONE';
-
- /**
- * This tells Smarty whether to check for recompiling or not. Recompiling
- * does not need to happen unless a template or config file is changed.
- * Typically you enable this during development, and disable for
- * production.
- *
- * @var boolean
- */
- var $compile_check = true;
-
- /**
- * This forces templates to compile every time. Useful for development
- * or debugging.
- *
- * @var boolean
- */
- var $force_compile = false;
-
- /**
- * This enables template caching.
- * <ul>
- * <li>0 = no caching</li>
- * <li>1 = use class cache_lifetime value</li>
- * <li>2 = use cache_lifetime in cache file</li>
- * </ul>
- * @var integer
- */
- var $caching = 0;
-
- /**
- * The name of the directory for cache files.
- *
- * @var string
- */
- var $cache_dir = 'cache';
-
- /**
- * This is the number of seconds cached content will persist.
- * <ul>
- * <li>0 = always regenerate cache</li>
- * <li>-1 = never expires</li>
- * </ul>
- *
- * @var integer
- */
- var $cache_lifetime = 3600;
-
- /**
- * Only used when $caching is enabled. If true, then If-Modified-Since headers
- * are respected with cached content, and appropriate HTTP headers are sent.
- * This way repeated hits to a cached page do not send the entire page to the
- * client every time.
- *
- * @var boolean
- */
- var $cache_modified_check = false;
-
- /**
- * This determines how Smarty handles "<?php ... ?>" tags in templates.
- * possible values:
- * <ul>
- * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
- * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li>
- * <li>SMARTY_PHP_REMOVE -> remove php tags</li>
- * <li>SMARTY_PHP_ALLOW -> execute php tags</li>
- * </ul>
- *
- * @var integer
- */
- var $php_handling = SMARTY_PHP_PASSTHRU;
-
- /**
- * This enables template security. When enabled, many things are restricted
- * in the templates that normally would go unchecked. This is useful when
- * untrusted parties are editing templates and you want a reasonable level
- * of security. (no direct execution of PHP in templates for example)
- *
- * @var boolean
- */
- var $security = false;
-
- /**
- * This is the list of template directories that are considered secure. This
- * is used only if {@link $security} is enabled. One directory per array
- * element. {@link $template_dir} is in this list implicitly.
- *
- * @var array
- */
- var $secure_dir = array();
-
- /**
- * These are the security settings for Smarty. They are used only when
- * {@link $security} is enabled.
- *
- * @var array
- */
- var $security_settings = array(
- 'PHP_HANDLING' => false,
- 'IF_FUNCS' => array('array', 'list',
- 'isset', 'empty',
- 'count', 'sizeof',
- 'in_array', 'is_array',
- 'true', 'false', 'null'),
- 'INCLUDE_ANY' => false,
- 'PHP_TAGS' => false,
- 'MODIFIER_FUNCS' => array('count'),
- 'ALLOW_CONSTANTS' => false
- );
-
- /**
- * This is an array of directories where trusted php scripts reside.
- * {@link $security} is disabled during their inclusion/execution.
- *
- * @var array
- */
- var $trusted_dir = array();
-
- /**
- * The left delimiter used for the template tags.
- *
- * @var string
- */
- var $left_delimiter = '{';
-
- /**
- * The right delimiter used for the template tags.
- *
- * @var string
- */
- var $right_delimiter = '}';
-
- /**
- * The order in which request variables are registered, similar to
- * variables_order in php.ini E = Environment, G = GET, P = POST,
- * C = Cookies, S = Server
- *
- * @var string
- */
- var $request_vars_order = 'EGPCS';
-
- /**
- * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
- * are uses as request-vars or $_*[]-vars. note: if
- * request_use_auto_globals is true, then $request_vars_order has
- * no effect, but the php-ini-value "gpc_order"
- *
- * @var boolean
- */
- var $request_use_auto_globals = true;
-
- /**
- * Set this if you want different sets of compiled files for the same
- * templates. This is useful for things like different languages.
- * Instead of creating separate sets of templates per language, you
- * set different compile_ids like 'en' and 'de'.
- *
- * @var string
- */
- var $compile_id = null;
-
- /**
- * This tells Smarty whether or not to use sub dirs in the cache/ and
- * templates_c/ directories. sub directories better organized, but
- * may not work well with PHP safe mode enabled.
- *
- * @var boolean
- *
- */
- var $use_sub_dirs = false;
-
- /**
- * This is a list of the modifiers to apply to all template variables.
- * Put each modifier in a separate array element in the order you want
- * them applied. example: <code>array('escape:"htmlall"');</code>
- *
- * @var array
- */
- var $default_modifiers = array();
-
- /**
- * This is the resource type to be used when not specified
- * at the beginning of the resource path. examples:
- * $smarty->display('file:index.tpl');
- * $smarty->display('db:index.tpl');
- * $smarty->display('index.tpl'); // will use default resource type
- * {include file="file:index.tpl"}
- * {include file="db:index.tpl"}
- * {include file="index.tpl"} {* will use default resource type *}
- *
- * @var array
- */
- var $default_resource_type = 'file';
-
- /**
- * The function used for cache file handling. If not set, built-in caching is used.
- *
- * @var null|string function name
- */
- var $cache_handler_func = null;
-
- /**
- * This indicates which filters are automatically loaded into Smarty.
- *
- * @var array array of filter names
- */
- var $autoload_filters = array();
-
- /**#@+
- * @var boolean
- */
- /**
- * This tells if config file vars of the same name overwrite each other or not.
- * if disabled, same name variables are accumulated in an array.
- */
- var $config_overwrite = true;
-
- /**
- * This tells whether or not to automatically booleanize config file variables.
- * If enabled, then the strings "on", "true", and "yes" are treated as boolean
- * true, and "off", "false" and "no" are treated as boolean false.
- */
- var $config_booleanize = true;
-
- /**
- * This tells whether hidden sections [.foobar] are readable from the
- * tempalates or not. Normally you would never allow this since that is
- * the point behind hidden sections: the application can access them, but
- * the templates cannot.
- */
- var $config_read_hidden = false;
-
- /**
- * This tells whether or not automatically fix newlines in config files.
- * It basically converts \r (mac) or \r\n (dos) to \n
- */
- var $config_fix_newlines = true;
- /**#@-*/
-
- /**
- * If a template cannot be found, this PHP function will be executed.
- * Useful for creating templates on-the-fly or other special action.
- *
- * @var string function name
- */
- var $default_template_handler_func = '';
-
- /**
- * The file that contains the compiler class. This can a full
- * pathname, or relative to the php_include path.
- *
- * @var string
- */
- var $compiler_file = 'Smarty_Compiler.class.php';
-
- /**
- * The class used for compiling templates.
- *
- * @var string
- */
- var $compiler_class = 'Smarty_Compiler';
-
- /**
- * The class used to load config vars.
- *
- * @var string
- */
- var $config_class = 'Config_File';
-
-/**#@+
- * END Smarty Configuration Section
- * There should be no need to touch anything below this line.
- * @access private
- */
- /**
- * where assigned template vars are kept
- *
- * @var array
- */
- var $_tpl_vars = array();
-
- /**
- * stores run-time $smarty.* vars
- *
- * @var null|array
- */
- var $_smarty_vars = null;
-
- /**
- * keeps track of sections
- *
- * @var array
- */
- var $_sections = array();
-
- /**
- * keeps track of foreach blocks
- *
- * @var array
- */
- var $_foreach = array();
-
- /**
- * keeps track of tag hierarchy
- *
- * @var array
- */
- var $_tag_stack = array();
-
- /**
- * configuration object
- *
- * @var Config_file
- */
- var $_conf_obj = null;
-
- /**
- * loaded configuration settings
- *
- * @var array
- */
- var $_config = array(array('vars' => array(), 'files' => array()));
-
- /**
- * md5 checksum of the string 'Smarty'
- *
- * @var string
- */
- var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f';
-
- /**
- * Smarty version number
- *
- * @var string
- */
- var $_version = '2.6.22';
-
- /**
- * current template inclusion depth
- *
- * @var integer
- */
- var $_inclusion_depth = 0;
-
- /**
- * for different compiled templates
- *
- * @var string
- */
- var $_compile_id = null;
-
- /**
- * text in URL to enable debug mode
- *
- * @var string
- */
- var $_smarty_debug_id = 'SMARTY_DEBUG';
-
- /**
- * debugging information for debug console
- *
- * @var array
- */
- var $_smarty_debug_info = array();
-
- /**
- * info that makes up a cache file
- *
- * @var array
- */
- var $_cache_info = array();
-
- /**
- * default file permissions
- *
- * @var integer
- */
- var $_file_perms = 0644;
-
- /**
- * default dir permissions
- *
- * @var integer
- */
- var $_dir_perms = 0771;
-
- /**
- * registered objects
- *
- * @var array
- */
- var $_reg_objects = array();
-
- /**
- * table keeping track of plugins
- *
- * @var array
- */
- var $_plugins = array(
- 'modifier' => array(),
- 'function' => array(),
- 'block' => array(),
- 'compiler' => array(),
- 'prefilter' => array(),
- 'postfilter' => array(),
- 'outputfilter' => array(),
- 'resource' => array(),
- 'insert' => array());
-
-
- /**
- * cache serials
- *
- * @var array
- */
- var $_cache_serials = array();
-
- /**
- * name of optional cache include file
- *
- * @var string
- */
- var $_cache_include = null;
-
- /**
- * indicate if the current code is used in a compiled
- * include
- *
- * @var string
- */
- var $_cache_including = false;
-
- /**#@-*/
- /**
- * The class constructor.
- */
- function Smarty()
- {
- $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
- : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
- }
-
- /**
- * assigns values to template variables
- *
- * @param array|string $tpl_var the template variable name(s)
- * @param mixed $value the value to assign
- */
- function assign($tpl_var, $value = null)
- {
- if (is_array($tpl_var)){
- foreach ($tpl_var as $key => $val) {
- if ($key != '') {
- $this->_tpl_vars[$key] = $val;
- }
- }
- } else {
- if ($tpl_var != '')
- $this->_tpl_vars[$tpl_var] = $value;
- }
- }
-
- /**
- * assigns values to template variables by reference
- *
- * @param string $tpl_var the template variable name
- * @param mixed $value the referenced value to assign
- */
- function assign_by_ref($tpl_var, &$value)
- {
- if ($tpl_var != '')
- $this->_tpl_vars[$tpl_var] = &$value;
- }
-
- /**
- * appends values to template variables
- *
- * @param array|string $tpl_var the template variable name(s)
- * @param mixed $value the value to append
- */
- function append($tpl_var, $value=null, $merge=false)
- {
- if (is_array($tpl_var)) {
- // $tpl_var is an array, ignore $value
- foreach ($tpl_var as $_key => $_val) {
- if ($_key != '') {
- if(!@is_array($this->_tpl_vars[$_key])) {
- settype($this->_tpl_vars[$_key],'array');
- }
- if($merge && is_array($_val)) {
- foreach($_val as $_mkey => $_mval) {
- $this->_tpl_vars[$_key][$_mkey] = $_mval;
- }
- } else {
- $this->_tpl_vars[$_key][] = $_val;
- }
- }
- }
- } else {
- if ($tpl_var != '' && isset($value)) {
- if(!@is_array($this->_tpl_vars[$tpl_var])) {
- settype($this->_tpl_vars[$tpl_var],'array');
- }
- if($merge && is_array($value)) {
- foreach($value as $_mkey => $_mval) {
- $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
- }
- } else {
- $this->_tpl_vars[$tpl_var][] = $value;
- }
- }
- }
- }
-
- /**
- * appends values to template variables by reference
- *
- * @param string $tpl_var the template variable name
- * @param mixed $value the referenced value to append
- */
- function append_by_ref($tpl_var, &$value, $merge=false)
- {
- if ($tpl_var != '' && isset($value)) {
- if(!@is_array($this->_tpl_vars[$tpl_var])) {
- settype($this->_tpl_vars[$tpl_var],'array');
- }
- if ($merge && is_array($value)) {
- foreach($value as $_key => $_val) {
- $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
- }
- } else {
- $this->_tpl_vars[$tpl_var][] = &$value;
- }
- }
- }
-
-
- /**
- * clear the given assigned template variable.
- *
- * @param string $tpl_var the template variable to clear
- */
- function clear_assign($tpl_var)
- {
- if (is_array($tpl_var))
- foreach ($tpl_var as $curr_var)
- unset($this->_tpl_vars[$curr_var]);
- else
- unset($this->_tpl_vars[$tpl_var]);
- }
-
-
- /**
- * Registers custom function to be used in templates
- *
- * @param string $function the name of the template function
- * @param string $function_impl the name of the PHP function to register
- */
- function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
- {
- $this->_plugins['function'][$function] =
- array($function_impl, null, null, false, $cacheable, $cache_attrs);
-
- }
-
- /**
- * Unregisters custom function
- *
- * @param string $function name of template function
- */
- function unregister_function($function)
- {
- unset($this->_plugins['function'][$function]);
- }
-
- /**
- * Registers object to be used in templates
- *
- * @param string $object name of template object
- * @param object &$object_impl the referenced PHP object to register
- * @param null|array $allowed list of allowed methods (empty = all)
- * @param boolean $smarty_args smarty argument format, else traditional
- * @param null|array $block_functs list of methods that are block format
- */
- function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
- {
- settype($allowed, 'array');
- settype($smarty_args, 'boolean');
- $this->_reg_objects[$object] =
- array(&$object_impl, $allowed, $smarty_args, $block_methods);
- }
-
- /**
- * Unregisters object
- *
- * @param string $object name of template object
- */
- function unregister_object($object)
- {
- unset($this->_reg_objects[$object]);
- }
-
-
- /**
- * Registers block function to be used in templates
- *
- * @param string $block name of template block
- * @param string $block_impl PHP function to register
- */
- function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
- {
- $this->_plugins['block'][$block] =
- array($block_impl, null, null, false, $cacheable, $cache_attrs);
- }
-
- /**
- * Unregisters block function
- *
- * @param string $block name of template function
- */
- function unregister_block($block)
- {
- unset($this->_plugins['block'][$block]);
- }
-
- /**
- * Registers compiler function
- *
- * @param string $function name of template function
- * @param string $function_impl name of PHP function to register
- */
- function register_compiler_function($function, $function_impl, $cacheable=true)
- {
- $this->_plugins['compiler'][$function] =
- array($function_impl, null, null, false, $cacheable);
- }
-
- /**
- * Unregisters compiler function
- *
- * @param string $function name of template function
- */
- function unregister_compiler_function($function)
- {
- unset($this->_plugins['compiler'][$function]);
- }
-
- /**
- * Registers modifier to be used in templates
- *
- * @param string $modifier name of template modifier
- * @param string $modifier_impl name of PHP function to register
- */
- function register_modifier($modifier, $modifier_impl)
- {
- $this->_plugins['modifier'][$modifier] =
- array($modifier_impl, null, null, false);
- }
-
- /**
- * Unregisters modifier
- *
- * @param string $modifier name of template modifier
- */
- function unregister_modifier($modifier)
- {
- unset($this->_plugins['modifier'][$modifier]);
- }
-
- /**
- * Registers a resource to fetch a template
- *
- * @param string $type name of resource
- * @param array $functions array of functions to handle resource
- */
- function register_resource($type, $functions)
- {
- if (count($functions)==4) {
- $this->_plugins['resource'][$type] =
- array($functions, false);
-
- } elseif (count($functions)==5) {
- $this->_plugins['resource'][$type] =
- array(array(array(&$functions[0], $functions[1])
- ,array(&$functions[0], $functions[2])
- ,array(&$functions[0], $functions[3])
- ,array(&$functions[0], $functions[4]))
- ,false);
-
- } else {
- $this->trigger_error("malformed function-list for '$type' in register_resource");
-
- }
- }
-
- /**
- * Unregisters a resource
- *
- * @param string $type name of resource
- */
- function unregister_resource($type)
- {
- unset($this->_plugins['resource'][$type]);
- }
-
- /**
- * Registers a prefilter function to apply
- * to a template before compiling
- *
- * @param callback $function
- */
- function register_prefilter($function)
- {
- $this->_plugins['prefilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters a prefilter function
- *
- * @param callback $function
- */
- function unregister_prefilter($function)
- {
- unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * Registers a postfilter function to apply
- * to a compiled template after compilation
- *
- * @param callback $function
- */
- function register_postfilter($function)
- {
- $this->_plugins['postfilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters a postfilter function
- *
- * @param callback $function
- */
- function unregister_postfilter($function)
- {
- unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * Registers an output filter function to apply
- * to a template output
- *
- * @param callback $function
- */
- function register_outputfilter($function)
- {
- $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters an outputfilter function
- *
- * @param callback $function
- */
- function unregister_outputfilter($function)
- {
- unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * load a filter of specified type and name
- *
- * @param string $type filter type
- * @param string $name filter name
- */
- function load_filter($type, $name)
- {
- switch ($type) {
- case 'output':
- $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- break;
-
- case 'pre':
- case 'post':
- if (!isset($this->_plugins[$type . 'filter'][$name]))
- $this->_plugins[$type . 'filter'][$name] = false;
- break;
- }
- }
-
- /**
- * clear cached content for the given template and cache id
- *
- * @param string $tpl_file name of template file
- * @param string $cache_id name of cache_id
- * @param string $compile_id name of compile_id
- * @param string $exp_time expiration time
- * @return boolean
- */
- function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
- {
-
- if (!isset($compile_id))
- $compile_id = $this->compile_id;
-
- if (!isset($tpl_file))
- $compile_id = null;
-
- $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
-
- if (!empty($this->cache_handler_func)) {
- return call_user_func_array($this->cache_handler_func,
- array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
- } else {
- $_params = array('auto_base' => $this->cache_dir,
- 'auto_source' => $tpl_file,
- 'auto_id' => $_auto_id,
- 'exp_time' => $exp_time);
- require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
- return smarty_core_rm_auto($_params, $this);
- }
-
- }
-
-
- /**
- * clear the entire contents of cache (all templates)
- *
- * @param string $exp_time expire time
- * @return boolean results of {@link smarty_core_rm_auto()}
- */
- function clear_all_cache($exp_time = null)
- {
- return $this->clear_cache(null, null, null, $exp_time);
- }
-
-
- /**
- * test to see if valid cache exists for this template
- *
- * @param string $tpl_file name of template file
- * @param string $cache_id
- * @param string $compile_id
- * @return string|false results of {@link _read_cache_file()}
- */
- function is_cached($tpl_file, $cache_id = null, $compile_id = null)
- {
- if (!$this->caching)
- return false;
-
- if (!isset($compile_id))
- $compile_id = $this->compile_id;
-
- $_params = array(
- 'tpl_file' => $tpl_file,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id
- );
- require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
- return smarty_core_read_cache_file($_params, $this);
- }
-
-
- /**
- * clear all the assigned template variables.
- *
- */
- function clear_all_assign()
- {
- $this->_tpl_vars = array();
- }
-
- /**
- * clears compiled version of specified template resource,
- * or all compiled template files if one is not specified.
- * This function is for advanced use only, not normally needed.
- *
- * @param string $tpl_file
- * @param string $compile_id
- * @param string $exp_time
- * @return boolean results of {@link smarty_core_rm_auto()}
- */
- function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
- {
- if (!isset($compile_id)) {
- $compile_id = $this->compile_id;
- }
- $_params = array('auto_base' => $this->compile_dir,
- 'auto_source' => $tpl_file,
- 'auto_id' => $compile_id,
- 'exp_time' => $exp_time,
- 'extensions' => array('.inc', '.php'));
- require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
- return smarty_core_rm_auto($_params, $this);
- }
-
- /**
- * Checks whether requested template exists.
- *
- * @param string $tpl_file
- * @return boolean
- */
- function template_exists($tpl_file)
- {
- $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
- return $this->_fetch_resource_info($_params);
- }
-
- /**
- * Returns an array containing template variables
- *
- * @param string $name
- * @param string $type
- * @return array
- */
- function &get_template_vars($name=null)
- {
- if(!isset($name)) {
- return $this->_tpl_vars;
- } elseif(isset($this->_tpl_vars[$name])) {
- return $this->_tpl_vars[$name];
- } else {
- // var non-existant, return valid reference
- $_tmp = null;
- return $_tmp;
- }
- }
-
- /**
- * Returns an array containing config variables
- *
- * @param string $name
- * @param string $type
- * @return array
- */
- function &get_config_vars($name=null)
- {
- if(!isset($name) && is_array($this->_config[0])) {
- return $this->_config[0]['vars'];
- } else if(isset($this->_config[0]['vars'][$name])) {
- return $this->_config[0]['vars'][$name];
- } else {
- // var non-existant, return valid reference
- $_tmp = null;
- return $_tmp;
- }
- }
-
- /**
- * trigger Smarty error
- *
- * @param string $error_msg
- * @param integer $error_type
- */
- function trigger_error($error_msg, $error_type = E_USER_WARNING)
- {
- trigger_error("Smarty error: $error_msg", $error_type);
- }
-
-
- /**
- * executes & displays the template results
- *
- * @param string $resource_name
- * @param string $cache_id
- * @param string $compile_id
- */
- function display($resource_name, $cache_id = null, $compile_id = null)
- {
- $this->fetch($resource_name, $cache_id, $compile_id, true);
- }
-
- /**
- * executes & returns or displays the template results
- *
- * @param string $resource_name
- * @param string $cache_id
- * @param string $compile_id
- * @param boolean $display
- */
- function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
- {
- static $_cache_info = array();
-
-/*begin piwik
- $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
- ? $this->error_reporting : error_reporting() & ~E_NOTICE);
- end piwik*/
-
- if (!$this->debugging && $this->debugging_ctrl == 'URL') {
- $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
- if (@strstr($_query_string, $this->_smarty_debug_id)) {
- if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
- // enable debugging for this browser session
- @setcookie('SMARTY_DEBUG', true);
- $this->debugging = true;
- } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
- // disable debugging for this browser session
- @setcookie('SMARTY_DEBUG', false);
- $this->debugging = false;
- } else {
- // enable debugging for this page
- $this->debugging = true;
- }
- } else {
- $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
- }
- }
-
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $_debug_start_time = smarty_core_get_microtime($_params, $this);
- $this->_smarty_debug_info[] = array('type' => 'template',
- 'filename' => $resource_name,
- 'depth' => 0);
- $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
- }
-
- if (!isset($compile_id)) {
- $compile_id = $this->compile_id;
- }
-
- $this->_compile_id = $compile_id;
- $this->_inclusion_depth = 0;
-
- if ($this->caching) {
- // save old cache_info, initialize cache_info
- array_push($_cache_info, $this->_cache_info);
- $this->_cache_info = array();
- $_params = array(
- 'tpl_file' => $resource_name,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id,
- 'results' => null
- );
- require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
- if (smarty_core_read_cache_file($_params, $this)) {
- $_smarty_results = $_params['results'];
- if (!empty($this->_cache_info['insert_tags'])) {
- $_params = array('plugins' => $this->_cache_info['insert_tags']);
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- $_params = array('results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
- $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
- }
- if (!empty($this->_cache_info['cache_serials'])) {
- $_params = array('results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
- $_smarty_results = smarty_core_process_compiled_include($_params, $this);
- }
-
-
- if ($display) {
- if ($this->debugging)
- {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
- require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
- $_smarty_results .= smarty_core_display_debug_console($_params, $this);
- }
- if ($this->cache_modified_check) {
- $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
- $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
- $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
- if (@count($this->_cache_info['insert_tags']) == 0
- && !$this->_cache_serials
- && $_gmt_mtime == $_last_modified_date) {
- if (php_sapi_name()=='cgi')
- header('Status: 304 Not Modified');
- else
- header('HTTP/1.1 304 Not Modified');
-
- } else {
- header('Last-Modified: '.$_gmt_mtime);
- echo $_smarty_results;
- }
- } else {
- echo $_smarty_results;
- }
-// error_reporting($_smarty_old_error_level); // piwik
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- return true;
- } else {
-// error_reporting($_smarty_old_error_level); // piwik
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- return $_smarty_results;
- }
- } else {
- $this->_cache_info['template'][$resource_name] = true;
- if ($this->cache_modified_check && $display) {
- header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
- }
- }
- }
-
- // load filters that are marked as autoload
- if (count($this->autoload_filters)) {
- foreach ($this->autoload_filters as $_filter_type => $_filters) {
- foreach ($_filters as $_filter) {
- $this->load_filter($_filter_type, $_filter);
- }
- }
- }
-
- $_smarty_compile_path = $this->_get_compile_path($resource_name);
-
- // if we just need to display the results, don't perform output
- // buffering - for speed
- $_cache_including = $this->_cache_including;
- $this->_cache_including = false;
- if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
- if ($this->_is_compiled($resource_name, $_smarty_compile_path)
- || $this->_compile_resource($resource_name, $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
- } else {
- ob_start();
- if ($this->_is_compiled($resource_name, $_smarty_compile_path)
- || $this->_compile_resource($resource_name, $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
- $_smarty_results = ob_get_contents();
- ob_end_clean();
-
- foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
- $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
- }
- }
-
- if ($this->caching) {
- $_params = array('tpl_file' => $resource_name,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id,
- 'results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
- smarty_core_write_cache_file($_params, $this);
- require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
- $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
-
- if ($this->_cache_serials) {
- // strip nocache-tags from output
- $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
- ,''
- ,$_smarty_results);
- }
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- }
- $this->_cache_including = $_cache_including;
-
- if ($display) {
- if (isset($_smarty_results)) { echo $_smarty_results; }
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
- require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
- echo smarty_core_display_debug_console($_params, $this);
- }
-// error_reporting($_smarty_old_error_level); // piwik
- return;
- } else {
-// error_reporting($_smarty_old_error_level); // piwik
- if (isset($_smarty_results)) { return $_smarty_results; }
- }
- }
-
- /**
- * load configuration values
- *
- * @param string $file
- * @param string $section
- * @param string $scope
- */
- function config_load($file, $section = null, $scope = 'global')
- {
- require_once($this->_get_plugin_filepath('function', 'config_load'));
- smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
- }
-
- /**
- * return a reference to a registered object
- *
- * @param string $name
- * @return object
- */
- function &get_registered_object($name) {
- if (!isset($this->_reg_objects[$name]))
- $this->_trigger_fatal_error("'$name' is not a registered object");
-
- if (!is_object($this->_reg_objects[$name][0]))
- $this->_trigger_fatal_error("registered '$name' is not an object");
-
- return $this->_reg_objects[$name][0];
- }
-
- /**
- * clear configuration values
- *
- * @param string $var
- */
- function clear_config($var = null)
- {
- if(!isset($var)) {
- // clear all values
- $this->_config = array(array('vars' => array(),
- 'files' => array()));
- } else {
- unset($this->_config[0]['vars'][$var]);
- }
- }
-
- /**
- * get filepath of requested plugin
- *
- * @param string $type
- * @param string $name
- * @return string|false
- */
- function _get_plugin_filepath($type, $name)
- {
- $_params = array('type' => $type, 'name' => $name);
- require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
- return smarty_core_assemble_plugin_filepath($_params, $this);
- }
-
- /**
- * test if resource needs compiling
- *
- * @param string $resource_name
- * @param string $compile_path
- * @return boolean
- */
- function _is_compiled($resource_name, $compile_path)
- {
- if (!$this->force_compile && file_exists($compile_path)) {
- if (!$this->compile_check) {
- // no need to check compiled file
- return true;
- } else {
- // get file source and timestamp
- $_params = array('resource_name' => $resource_name, 'get_source'=>false);
- if (!$this->_fetch_resource_info($_params)) {
- return false;
- }
- if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
- // template not expired, no recompile
- return true;
- } else {
- // compile template
- return false;
- }
- }
- } else {
- // compiled template does not exist, or forced compile
- return false;
- }
- }
-
- /**
- * compile the template
- *
- * @param string $resource_name
- * @param string $compile_path
- * @return boolean
- */
- function _compile_resource($resource_name, $compile_path)
- {
-
- $_params = array('resource_name' => $resource_name);
- if (!$this->_fetch_resource_info($_params)) {
- return false;
- }
-
- $_source_content = $_params['source_content'];
- $_cache_include = substr($compile_path, 0, -4).'.inc';
-
- if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
- // if a _cache_serial was set, we also have to write an include-file:
- if ($this->_cache_include_info) {
- require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
- smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this);
- }
-
- $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
- require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
- smarty_core_write_compiled_resource($_params, $this);
-
- return true;
- } else {
- return false;
- }
-
- }
-
- /**
- * compile the given source
- *
- * @param string $resource_name
- * @param string $source_content
- * @param string $compiled_content
- * @return boolean
- */
- function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
- {
- if (file_exists(SMARTY_DIR . $this->compiler_file)) {
- require_once(SMARTY_DIR . $this->compiler_file);
- } else {
- // use include_path
- require_once($this->compiler_file);
- }
-
-
- $smarty_compiler = new $this->compiler_class;
-
- $smarty_compiler->template_dir = $this->template_dir;
- $smarty_compiler->compile_dir = $this->compile_dir;
- $smarty_compiler->plugins_dir = $this->plugins_dir;
- $smarty_compiler->config_dir = $this->config_dir;
- $smarty_compiler->force_compile = $this->force_compile;
- $smarty_compiler->caching = $this->caching;
- $smarty_compiler->php_handling = $this->php_handling;
- $smarty_compiler->left_delimiter = $this->left_delimiter;
- $smarty_compiler->right_delimiter = $this->right_delimiter;
- $smarty_compiler->_version = $this->_version;
- $smarty_compiler->security = $this->security;
- $smarty_compiler->secure_dir = $this->secure_dir;
- $smarty_compiler->security_settings = $this->security_settings;
- $smarty_compiler->trusted_dir = $this->trusted_dir;
- $smarty_compiler->use_sub_dirs = $this->use_sub_dirs;
- $smarty_compiler->_reg_objects = &$this->_reg_objects;
- $smarty_compiler->_plugins = &$this->_plugins;
- $smarty_compiler->_tpl_vars = &$this->_tpl_vars;
- $smarty_compiler->default_modifiers = $this->default_modifiers;
- $smarty_compiler->compile_id = $this->_compile_id;
- $smarty_compiler->_config = $this->_config;
- $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
-
- if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
- $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
- }
- $smarty_compiler->_cache_include = $cache_include_path;
-
-
- $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
-
- if ($smarty_compiler->_cache_serial) {
- $this->_cache_include_info = array(
- 'cache_serial'=>$smarty_compiler->_cache_serial
- ,'plugins_code'=>$smarty_compiler->_plugins_code
- ,'include_file_path' => $cache_include_path);
-
- } else {
- $this->_cache_include_info = null;
-
- }
-
- return $_results;
- }
-
- /**
- * Get the compile path for this resource
- *
- * @param string $resource_name
- * @return string results of {@link _get_auto_filename()}
- */
- function _get_compile_path($resource_name)
- {
- return $this->_get_auto_filename($this->compile_dir, $resource_name,
- $this->_compile_id) . '.php';
- }
-
- /**
- * fetch the template info. Gets timestamp, and source
- * if get_source is true
- *
- * sets $source_content to the source of the template, and
- * $resource_timestamp to its time stamp
- * @param string $resource_name
- * @param string $source_content
- * @param integer $resource_timestamp
- * @param boolean $get_source
- * @param boolean $quiet
- * @return boolean
- */
-
- function _fetch_resource_info(&$params)
- {
- if(!isset($params['get_source'])) { $params['get_source'] = true; }
- if(!isset($params['quiet'])) { $params['quiet'] = false; }
-
- $_return = false;
- $_params = array('resource_name' => $params['resource_name']) ;
- if (isset($params['resource_base_path']))
- $_params['resource_base_path'] = $params['resource_base_path'];
- else
- $_params['resource_base_path'] = $this->template_dir;
-
- if ($this->_parse_resource_name($_params)) {
- $_resource_type = $_params['resource_type'];
- $_resource_name = $_params['resource_name'];
- switch ($_resource_type) {
- case 'file':
- if ($params['get_source']) {
- $params['source_content'] = $this->_read_file($_resource_name);
- }
- $params['resource_timestamp'] = filemtime($_resource_name);
- $_return = is_file($_resource_name);
- break;
-
- default:
- // call resource functions to fetch the template source and timestamp
- if ($params['get_source']) {
- $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
- call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
- array($_resource_name, &$params['source_content'], &$this));
- } else {
- $_source_return = true;
- }
-
- $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
- call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
- array($_resource_name, &$params['resource_timestamp'], &$this));
-
- $_return = $_source_return && $_timestamp_return;
- break;
- }
- }
-
- if (!$_return) {
- // see if we can get a template with the default template handler
- if (!empty($this->default_template_handler_func)) {
- if (!is_callable($this->default_template_handler_func)) {
- $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
- } else {
- $_return = call_user_func_array(
- $this->default_template_handler_func,
- array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
- }
- }
- }
-
- if (!$_return) {
- if (!$params['quiet']) {
- $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
- }
- } else if ($_return && $this->security) {
- require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
- if (!smarty_core_is_secure($_params, $this)) {
- if (!$params['quiet'])
- $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
- $params['source_content'] = null;
- $params['resource_timestamp'] = null;
- return false;
- }
- }
- return $_return;
- }
-
-
- /**
- * parse out the type and name from the resource
- *
- * @param string $resource_base_path
- * @param string $resource_name
- * @param string $resource_type
- * @param string $resource_name
- * @return boolean
- */
-
- function _parse_resource_name(&$params)
- {
-
- // split tpl_path by the first colon
- $_resource_name_parts = explode(':', $params['resource_name'], 2);
-
- if (count($_resource_name_parts) == 1) {
- // no resource type given
- $params['resource_type'] = $this->default_resource_type;
- $params['resource_name'] = $_resource_name_parts[0];
- } else {
- if(strlen($_resource_name_parts[0]) == 1) {
- // 1 char is not resource type, but part of filepath
- $params['resource_type'] = $this->default_resource_type;
- $params['resource_name'] = $params['resource_name'];
- } else {
- $params['resource_type'] = $_resource_name_parts[0];
- $params['resource_name'] = $_resource_name_parts[1];
- }
- }
-
- if ($params['resource_type'] == 'file') {
- if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
- // relative pathname to $params['resource_base_path']
- // use the first directory where the file is found
- foreach ((array)$params['resource_base_path'] as $_curr_path) {
- $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
- if (file_exists($_fullpath) && is_file($_fullpath)) {
- $params['resource_name'] = $_fullpath;
- return true;
- }
- // didn't find the file, try include_path
- $_params = array('file_path' => $_fullpath);
- require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
- if(smarty_core_get_include_path($_params, $this)) {
- $params['resource_name'] = $_params['new_file_path'];
- return true;
- }
- }
- return false;
- } else {
- /* absolute path */
- return file_exists($params['resource_name']);
- }
- } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
- $_params = array('type' => $params['resource_type']);
- require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
- smarty_core_load_resource_plugin($_params, $this);
- }
-
- return true;
- }
-
-
- /**
- * Handle modifiers
- *
- * @param string|null $modifier_name
- * @param array|null $map_array
- * @return string result of modifiers
- */
- function _run_mod_handler()
- {
- $_args = func_get_args();
- list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
- list($_func_name, $_tpl_file, $_tpl_line) =
- $this->_plugins['modifier'][$_modifier_name];
-
- $_var = $_args[0];
- foreach ($_var as $_key => $_val) {
- $_args[0] = $_val;
- $_var[$_key] = call_user_func_array($_func_name, $_args);
- }
- return $_var;
- }
-
- /**
- * Remove starting and ending quotes from the string
- *
- * @param string $string
- * @return string
- */
- function _dequote($string)
- {
- if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
- substr($string, -1) == substr($string, 0, 1))
- return substr($string, 1, -1);
- else
- return $string;
- }
-
-
- /**
- * read in a file
- *
- * @param string $filename
- * @return string
- */
- function _read_file($filename)
- {
- if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) {
- $contents = '';
- while (!feof($fd)) {
- $contents .= fread($fd, 8192);
- }
- fclose($fd);
- return $contents;
- } else {
- return false;
- }
- }
-
- /**
- * get a concrete filename for automagically created content
- *
- * @param string $auto_base
- * @param string $auto_source
- * @param string $auto_id
- * @return string
- * @staticvar string|null
- * @staticvar string|null
- */
- function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
- {
- $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
- $_return = $auto_base . DIRECTORY_SEPARATOR;
-
- if(isset($auto_id)) {
- // make auto_id safe for directory names
- $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
- // split into separate directories
- $_return .= $auto_id . $_compile_dir_sep;
- }
-
- if(isset($auto_source)) {
- // make source name safe for filename
- $_filename = urlencode(basename($auto_source));
- $_crc32 = sprintf('%08X', crc32($auto_source));
- // prepend %% to avoid name conflicts with
- // with $params['auto_id'] names
- $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
- substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
- $_return .= '%%' . $_crc32 . '%%' . $_filename;
- }
-
- return $_return;
- }
-
- /**
- * unlink a file, possibly using expiration time
- *
- * @param string $resource
- * @param integer $exp_time
- */
- function _unlink($resource, $exp_time = null)
- {
- if(isset($exp_time)) {
- if(time() - @filemtime($resource) >= $exp_time) {
- return @unlink($resource);
- }
- } else {
- return @unlink($resource);
- }
- }
-
- /**
- * returns an auto_id for auto-file-functions
- *
- * @param string $cache_id
- * @param string $compile_id
- * @return string|null
- */
- function _get_auto_id($cache_id=null, $compile_id=null) {
- if (isset($cache_id))
- return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id;
- elseif(isset($compile_id))
- return $compile_id;
- else
- return null;
- }
-
- /**
- * trigger Smarty plugin error
- *
- * @param string $error_msg
- * @param string $tpl_file
- * @param integer $tpl_line
- * @param string $file
- * @param integer $line
- * @param integer $error_type
- */
- function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
- $file = null, $line = null, $error_type = E_USER_ERROR)
- {
- if(isset($file) && isset($line)) {
- $info = ' ('.basename($file).", line $line)";
- } else {
- $info = '';
- }
- if (isset($tpl_line) && isset($tpl_file)) {
- $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
- } else {
- $this->trigger_error($error_msg . $info, $error_type);
- }
- }
-
-
- /**
- * callback function for preg_replace, to call a non-cacheable block
- * @return string
- */
- function _process_compiled_include_callback($match) {
- $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
- ob_start();
- $_func($this);
- $_ret = ob_get_contents();
- ob_end_clean();
- return $_ret;
- }
-
-
- /**
- * called for included templates
- *
- * @param string $_smarty_include_tpl_file
- * @param string $_smarty_include_vars
- */
-
- // $_smarty_include_tpl_file, $_smarty_include_vars
-
- function _smarty_include($params)
- {
- if ($this->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $debug_start_time = smarty_core_get_microtime($_params, $this);
- $this->_smarty_debug_info[] = array('type' => 'template',
- 'filename' => $params['smarty_include_tpl_file'],
- 'depth' => ++$this->_inclusion_depth);
- $included_tpls_idx = count($this->_smarty_debug_info) - 1;
- }
-
- $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
-
- // config vars are treated as local, so push a copy of the
- // current ones onto the front of the stack
- array_unshift($this->_config, $this->_config[0]);
-
- $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
-
-
- if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
- || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
-
- // pop the local vars off the front of the stack
- array_shift($this->_config);
-
- $this->_inclusion_depth--;
-
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
- }
-
- if ($this->caching) {
- $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
- }
- }
-
-
- /**
- * get or set an array of cached attributes for function that is
- * not cacheable
- * @return array
- */
- function &_smarty_cache_attrs($cache_serial, $count) {
- $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
-
- if ($this->_cache_including) {
- /* return next set of cache_attrs */
- $_return = current($_cache_attrs);
- next($_cache_attrs);
- return $_return;
-
- } else {
- /* add a reference to a new set of cache_attrs */
- $_cache_attrs[] = array();
- return $_cache_attrs[count($_cache_attrs)-1];
-
- }
-
- }
-
-
- /**
- * wrapper for include() retaining $this
- * @return mixed
- */
- function _include($filename, $once=false, $params=null)
- {
- if ($once) {
- return include_once($filename);
- } else {
- return include($filename);
- }
- }
-
-
- /**
- * wrapper for eval() retaining $this
- * @return mixed
- */
- function _eval($code, $params=null)
- {
- return eval($code);
- }
-
- /**
- * Extracts the filter name from the given callback
- *
- * @param callback $function
- * @return string
- */
- function _get_filter_name($function)
- {
- if (is_array($function)) {
- $_class_name = (is_object($function[0]) ?
- get_class($function[0]) : $function[0]);
- return $_class_name . '_' . $function[1];
- }
- else {
- return $function;
- }
- }
-
- /**#@-*/
-
-}
-
-/* vim: set expandtab: */
-
-?>
+<?php + +/** + * Project: Smarty: the PHP compiling template engine + * File: Smarty.class.php + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For questions, help, comments, discussion, etc., please join the + * Smarty mailing list. Send a blank e-mail to + * smarty-discussion-subscribe@googlegroups.com + * + * @link http://www.smarty.net/ + * @copyright 2001-2005 New Digital Group, Inc. + * @author Monte Ohrt <monte at ohrt dot com> + * @author Andrei Zmievski <andrei@php.net> + * @package Smarty + * @version 2.6.22 + */ + +/* $Id$ */ + +/** + * DIR_SEP isn't used anymore, but third party apps might + */ +if(!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user + * application has not already defined it. + */ + +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); +} + +if (!defined('SMARTY_CORE_DIR')) { + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +} + +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +/** + * @package Smarty + */ +class Smarty +{ + /**#@+ + * Smarty Configuration Section + */ + + /** + * The name of the directory where templates are located. + * + * @var string + */ + var $template_dir = 'templates'; + + /** + * The directory where compiled templates are located. + * + * @var string + */ + var $compile_dir = 'templates_c'; + + /** + * The directory where config files are located. + * + * @var string + */ + var $config_dir = 'configs'; + + /** + * An array of directories searched for plugins. + * + * @var array + */ + var $plugins_dir = array('plugins'); + + /** + * If debugging is enabled, a debug console window will display + * when the page loads (make sure your browser allows unrequested + * popup windows) + * + * @var boolean + */ + var $debugging = false; + + /** + * When set, smarty does uses this value as error_reporting-level. + * + * @var boolean + */ + var $error_reporting = null; + + /** + * This is the path to the debug console template. If not set, + * the default one will be used. + * + * @var string + */ + var $debug_tpl = ''; + + /** + * This determines if debugging is enable-able from the browser. + * <ul> + * <li>NONE => no debugging control allowed</li> + * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> + * </ul> + * @link http://www.foo.dom/index.php?SMARTY_DEBUG + * @var string + */ + var $debugging_ctrl = 'NONE'; + + /** + * This tells Smarty whether to check for recompiling or not. Recompiling + * does not need to happen unless a template or config file is changed. + * Typically you enable this during development, and disable for + * production. + * + * @var boolean + */ + var $compile_check = true; + + /** + * This forces templates to compile every time. Useful for development + * or debugging. + * + * @var boolean + */ + var $force_compile = false; + + /** + * This enables template caching. + * <ul> + * <li>0 = no caching</li> + * <li>1 = use class cache_lifetime value</li> + * <li>2 = use cache_lifetime in cache file</li> + * </ul> + * @var integer + */ + var $caching = 0; + + /** + * The name of the directory for cache files. + * + * @var string + */ + var $cache_dir = 'cache'; + + /** + * This is the number of seconds cached content will persist. + * <ul> + * <li>0 = always regenerate cache</li> + * <li>-1 = never expires</li> + * </ul> + * + * @var integer + */ + var $cache_lifetime = 3600; + + /** + * Only used when $caching is enabled. If true, then If-Modified-Since headers + * are respected with cached content, and appropriate HTTP headers are sent. + * This way repeated hits to a cached page do not send the entire page to the + * client every time. + * + * @var boolean + */ + var $cache_modified_check = false; + + /** + * This determines how Smarty handles "<?php ... ?>" tags in templates. + * possible values: + * <ul> + * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li> + * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li> + * <li>SMARTY_PHP_REMOVE -> remove php tags</li> + * <li>SMARTY_PHP_ALLOW -> execute php tags</li> + * </ul> + * + * @var integer + */ + var $php_handling = SMARTY_PHP_PASSTHRU; + + /** + * This enables template security. When enabled, many things are restricted + * in the templates that normally would go unchecked. This is useful when + * untrusted parties are editing templates and you want a reasonable level + * of security. (no direct execution of PHP in templates for example) + * + * @var boolean + */ + var $security = false; + + /** + * This is the list of template directories that are considered secure. This + * is used only if {@link $security} is enabled. One directory per array + * element. {@link $template_dir} is in this list implicitly. + * + * @var array + */ + var $secure_dir = array(); + + /** + * These are the security settings for Smarty. They are used only when + * {@link $security} is enabled. + * + * @var array + */ + var $security_settings = array( + 'PHP_HANDLING' => false, + 'IF_FUNCS' => array('array', 'list', + 'isset', 'empty', + 'count', 'sizeof', + 'in_array', 'is_array', + 'true', 'false', 'null'), + 'INCLUDE_ANY' => false, + 'PHP_TAGS' => false, + 'MODIFIER_FUNCS' => array('count'), + 'ALLOW_CONSTANTS' => false + ); + + /** + * This is an array of directories where trusted php scripts reside. + * {@link $security} is disabled during their inclusion/execution. + * + * @var array + */ + var $trusted_dir = array(); + + /** + * The left delimiter used for the template tags. + * + * @var string + */ + var $left_delimiter = '{'; + + /** + * The right delimiter used for the template tags. + * + * @var string + */ + var $right_delimiter = '}'; + + /** + * The order in which request variables are registered, similar to + * variables_order in php.ini E = Environment, G = GET, P = POST, + * C = Cookies, S = Server + * + * @var string + */ + var $request_vars_order = 'EGPCS'; + + /** + * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) + * are uses as request-vars or $_*[]-vars. note: if + * request_use_auto_globals is true, then $request_vars_order has + * no effect, but the php-ini-value "gpc_order" + * + * @var boolean + */ + var $request_use_auto_globals = true; + + /** + * Set this if you want different sets of compiled files for the same + * templates. This is useful for things like different languages. + * Instead of creating separate sets of templates per language, you + * set different compile_ids like 'en' and 'de'. + * + * @var string + */ + var $compile_id = null; + + /** + * This tells Smarty whether or not to use sub dirs in the cache/ and + * templates_c/ directories. sub directories better organized, but + * may not work well with PHP safe mode enabled. + * + * @var boolean + * + */ + var $use_sub_dirs = false; + + /** + * This is a list of the modifiers to apply to all template variables. + * Put each modifier in a separate array element in the order you want + * them applied. example: <code>array('escape:"htmlall"');</code> + * + * @var array + */ + var $default_modifiers = array(); + + /** + * This is the resource type to be used when not specified + * at the beginning of the resource path. examples: + * $smarty->display('file:index.tpl'); + * $smarty->display('db:index.tpl'); + * $smarty->display('index.tpl'); // will use default resource type + * {include file="file:index.tpl"} + * {include file="db:index.tpl"} + * {include file="index.tpl"} {* will use default resource type *} + * + * @var array + */ + var $default_resource_type = 'file'; + + /** + * The function used for cache file handling. If not set, built-in caching is used. + * + * @var null|string function name + */ + var $cache_handler_func = null; + + /** + * This indicates which filters are automatically loaded into Smarty. + * + * @var array array of filter names + */ + var $autoload_filters = array(); + + /**#@+ + * @var boolean + */ + /** + * This tells if config file vars of the same name overwrite each other or not. + * if disabled, same name variables are accumulated in an array. + */ + var $config_overwrite = true; + + /** + * This tells whether or not to automatically booleanize config file variables. + * If enabled, then the strings "on", "true", and "yes" are treated as boolean + * true, and "off", "false" and "no" are treated as boolean false. + */ + var $config_booleanize = true; + + /** + * This tells whether hidden sections [.foobar] are readable from the + * tempalates or not. Normally you would never allow this since that is + * the point behind hidden sections: the application can access them, but + * the templates cannot. + */ + var $config_read_hidden = false; + + /** + * This tells whether or not automatically fix newlines in config files. + * It basically converts \r (mac) or \r\n (dos) to \n + */ + var $config_fix_newlines = true; + /**#@-*/ + + /** + * If a template cannot be found, this PHP function will be executed. + * Useful for creating templates on-the-fly or other special action. + * + * @var string function name + */ + var $default_template_handler_func = ''; + + /** + * The file that contains the compiler class. This can a full + * pathname, or relative to the php_include path. + * + * @var string + */ + var $compiler_file = 'Smarty_Compiler.class.php'; + + /** + * The class used for compiling templates. + * + * @var string + */ + var $compiler_class = 'Smarty_Compiler'; + + /** + * The class used to load config vars. + * + * @var string + */ + var $config_class = 'Config_File'; + +/**#@+ + * END Smarty Configuration Section + * There should be no need to touch anything below this line. + * @access private + */ + /** + * where assigned template vars are kept + * + * @var array + */ + var $_tpl_vars = array(); + + /** + * stores run-time $smarty.* vars + * + * @var null|array + */ + var $_smarty_vars = null; + + /** + * keeps track of sections + * + * @var array + */ + var $_sections = array(); + + /** + * keeps track of foreach blocks + * + * @var array + */ + var $_foreach = array(); + + /** + * keeps track of tag hierarchy + * + * @var array + */ + var $_tag_stack = array(); + + /** + * configuration object + * + * @var Config_file + */ + var $_conf_obj = null; + + /** + * loaded configuration settings + * + * @var array + */ + var $_config = array(array('vars' => array(), 'files' => array())); + + /** + * md5 checksum of the string 'Smarty' + * + * @var string + */ + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; + + /** + * Smarty version number + * + * @var string + */ + var $_version = '2.6.22'; + + /** + * current template inclusion depth + * + * @var integer + */ + var $_inclusion_depth = 0; + + /** + * for different compiled templates + * + * @var string + */ + var $_compile_id = null; + + /** + * text in URL to enable debug mode + * + * @var string + */ + var $_smarty_debug_id = 'SMARTY_DEBUG'; + + /** + * debugging information for debug console + * + * @var array + */ + var $_smarty_debug_info = array(); + + /** + * info that makes up a cache file + * + * @var array + */ + var $_cache_info = array(); + + /** + * default file permissions + * + * @var integer + */ + var $_file_perms = 0644; + + /** + * default dir permissions + * + * @var integer + */ + var $_dir_perms = 0771; + + /** + * registered objects + * + * @var array + */ + var $_reg_objects = array(); + + /** + * table keeping track of plugins + * + * @var array + */ + var $_plugins = array( + 'modifier' => array(), + 'function' => array(), + 'block' => array(), + 'compiler' => array(), + 'prefilter' => array(), + 'postfilter' => array(), + 'outputfilter' => array(), + 'resource' => array(), + 'insert' => array()); + + + /** + * cache serials + * + * @var array + */ + var $_cache_serials = array(); + + /** + * name of optional cache include file + * + * @var string + */ + var $_cache_include = null; + + /** + * indicate if the current code is used in a compiled + * include + * + * @var string + */ + var $_cache_including = false; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty() + { + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); + } + + /** + * assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign + */ + function assign($tpl_var, $value = null) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if ($key != '') { + $this->_tpl_vars[$key] = $val; + } + } + } else { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = $value; + } + } + + /** + * assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign + */ + function assign_by_ref($tpl_var, &$value) + { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = &$value; + } + + /** + * appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + */ + function append($tpl_var, $value=null, $merge=false) + { + if (is_array($tpl_var)) { + // $tpl_var is an array, ignore $value + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + if(!@is_array($this->_tpl_vars[$_key])) { + settype($this->_tpl_vars[$_key],'array'); + } + if($merge && is_array($_val)) { + foreach($_val as $_mkey => $_mval) { + $this->_tpl_vars[$_key][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$_key][] = $_val; + } + } + } + } else { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if($merge && is_array($value)) { + foreach($value as $_mkey => $_mval) { + $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } + } + + /** + * appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + */ + function append_by_ref($tpl_var, &$value, $merge=false) + { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_key => $_val) { + $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; + } + } else { + $this->_tpl_vars[$tpl_var][] = &$value; + } + } + } + + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + function clear_assign($tpl_var) + { + if (is_array($tpl_var)) + foreach ($tpl_var as $curr_var) + unset($this->_tpl_vars[$curr_var]); + else + unset($this->_tpl_vars[$tpl_var]); + } + + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + */ + function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['function'][$function] = + array($function_impl, null, null, false, $cacheable, $cache_attrs); + + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + function unregister_function($function) + { + unset($this->_plugins['function'][$function]); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object &$object_impl the referenced PHP object to register + * @param null|array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param null|array $block_functs list of methods that are block format + */ + function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->_reg_objects[$object] = + array(&$object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + function unregister_object($object) + { + unset($this->_reg_objects[$object]); + } + + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + */ + function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['block'][$block] = + array($block_impl, null, null, false, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + function unregister_block($block) + { + unset($this->_plugins['block'][$block]); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + */ + function register_compiler_function($function, $function_impl, $cacheable=true) + { + $this->_plugins['compiler'][$function] = + array($function_impl, null, null, false, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + function unregister_compiler_function($function) + { + unset($this->_plugins['compiler'][$function]); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + function register_modifier($modifier, $modifier_impl) + { + $this->_plugins['modifier'][$modifier] = + array($modifier_impl, null, null, false); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + function unregister_modifier($modifier) + { + unset($this->_plugins['modifier'][$modifier]); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + function register_resource($type, $functions) + { + if (count($functions)==4) { + $this->_plugins['resource'][$type] = + array($functions, false); + + } elseif (count($functions)==5) { + $this->_plugins['resource'][$type] = + array(array(array(&$functions[0], $functions[1]) + ,array(&$functions[0], $functions[2]) + ,array(&$functions[0], $functions[3]) + ,array(&$functions[0], $functions[4])) + ,false); + + } else { + $this->trigger_error("malformed function-list for '$type' in register_resource"); + + } + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + function unregister_resource($type) + { + unset($this->_plugins['resource'][$type]); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param callback $function + */ + function register_prefilter($function) + { + $this->_plugins['prefilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters a prefilter function + * + * @param callback $function + */ + function unregister_prefilter($function) + { + unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param callback $function + */ + function register_postfilter($function) + { + $this->_plugins['postfilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters a postfilter function + * + * @param callback $function + */ + function unregister_postfilter($function) + { + unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param callback $function + */ + function register_outputfilter($function) + { + $this->_plugins['outputfilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters an outputfilter function + * + * @param callback $function + */ + function unregister_outputfilter($function) + { + unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + function load_filter($type, $name) + { + switch ($type) { + case 'output': + $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + break; + + case 'pre': + case 'post': + if (!isset($this->_plugins[$type . 'filter'][$name])) + $this->_plugins[$type . 'filter'][$name] = false; + break; + } + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * @return boolean + */ + function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + if (!isset($tpl_file)) + $compile_id = null; + + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); + + if (!empty($this->cache_handler_func)) { + return call_user_func_array($this->cache_handler_func, + array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); + } else { + $_params = array('auto_base' => $this->cache_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $_auto_id, + 'exp_time' => $exp_time); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + } + + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_all_cache($exp_time = null) + { + return $this->clear_cache(null, null, null, $exp_time); + } + + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * @return string|false results of {@link _read_cache_file()} + */ + function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + if (!$this->caching) + return false; + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + $_params = array( + 'tpl_file' => $tpl_file, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + return smarty_core_read_cache_file($_params, $this); + } + + + /** + * clear all the assigned template variables. + * + */ + function clear_all_assign() + { + $this->_tpl_vars = array(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + $_params = array('auto_base' => $this->compile_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $compile_id, + 'exp_time' => $exp_time, + 'extensions' => array('.inc', '.php')); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * @return boolean + */ + function template_exists($tpl_file) + { + $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); + return $this->_fetch_resource_info($_params); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_template_vars($name=null) + { + if(!isset($name)) { + return $this->_tpl_vars; + } elseif(isset($this->_tpl_vars[$name])) { + return $this->_tpl_vars[$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * Returns an array containing config variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_config_vars($name=null) + { + if(!isset($name) && is_array($this->_config[0])) { + return $this->_config[0]['vars']; + } else if(isset($this->_config[0]['vars'][$name])) { + return $this->_config[0]['vars'][$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Smarty error: $error_msg", $error_type); + } + + + /** + * executes & displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + */ + function display($resource_name, $cache_id = null, $compile_id = null) + { + $this->fetch($resource_name, $cache_id, $compile_id, true); + } + + /** + * executes & returns or displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + * @param boolean $display + */ + function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) + { + static $_cache_info = array(); + +/*begin piwik + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) + ? $this->error_reporting : error_reporting() & ~E_NOTICE); + end piwik*/ + + if (!$this->debugging && $this->debugging_ctrl == 'URL') { + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; + if (@strstr($_query_string, $this->_smarty_debug_id)) { + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { + // enable debugging for this browser session + @setcookie('SMARTY_DEBUG', true); + $this->debugging = true; + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { + // disable debugging for this browser session + @setcookie('SMARTY_DEBUG', false); + $this->debugging = false; + } else { + // enable debugging for this page + $this->debugging = true; + } + } else { + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + } + } + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $resource_name, + 'depth' => 0); + $_included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + + $this->_compile_id = $compile_id; + $this->_inclusion_depth = 0; + + if ($this->caching) { + // save old cache_info, initialize cache_info + array_push($_cache_info, $this->_cache_info); + $this->_cache_info = array(); + $_params = array( + 'tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => null + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + if (smarty_core_read_cache_file($_params, $this)) { + $_smarty_results = $_params['results']; + if (!empty($this->_cache_info['insert_tags'])) { + $_params = array('plugins' => $this->_cache_info['insert_tags']); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + } + if (!empty($this->_cache_info['cache_serials'])) { + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); + $_smarty_results = smarty_core_process_compiled_include($_params, $this); + } + + + if ($display) { + if ($this->debugging) + { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + $_smarty_results .= smarty_core_display_debug_console($_params, $this); + } + if ($this->cache_modified_check) { + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; + if (@count($this->_cache_info['insert_tags']) == 0 + && !$this->_cache_serials + && $_gmt_mtime == $_last_modified_date) { + if (php_sapi_name()=='cgi') + header('Status: 304 Not Modified'); + else + header('HTTP/1.1 304 Not Modified'); + + } else { + header('Last-Modified: '.$_gmt_mtime); + echo $_smarty_results; + } + } else { + echo $_smarty_results; + } +// error_reporting($_smarty_old_error_level); // piwik + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return true; + } else { +// error_reporting($_smarty_old_error_level); // piwik + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return $_smarty_results; + } + } else { + $this->_cache_info['template'][$resource_name] = true; + if ($this->cache_modified_check && $display) { + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + } + } + } + + // load filters that are marked as autoload + if (count($this->autoload_filters)) { + foreach ($this->autoload_filters as $_filter_type => $_filters) { + foreach ($_filters as $_filter) { + $this->load_filter($_filter_type, $_filter); + } + } + } + + $_smarty_compile_path = $this->_get_compile_path($resource_name); + + // if we just need to display the results, don't perform output + // buffering - for speed + $_cache_including = $this->_cache_including; + $this->_cache_including = false; + if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + } else { + ob_start(); + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + $_smarty_results = ob_get_contents(); + ob_end_clean(); + + foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { + $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); + } + } + + if ($this->caching) { + $_params = array('tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); + smarty_core_write_cache_file($_params, $this); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + + if ($this->_cache_serials) { + // strip nocache-tags from output + $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' + ,'' + ,$_smarty_results); + } + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + } + $this->_cache_including = $_cache_including; + + if ($display) { + if (isset($_smarty_results)) { echo $_smarty_results; } + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + echo smarty_core_display_debug_console($_params, $this); + } +// error_reporting($_smarty_old_error_level); // piwik + return; + } else { +// error_reporting($_smarty_old_error_level); // piwik + if (isset($_smarty_results)) { return $_smarty_results; } + } + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + function config_load($file, $section = null, $scope = 'global') + { + require_once($this->_get_plugin_filepath('function', 'config_load')); + smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); + } + + /** + * return a reference to a registered object + * + * @param string $name + * @return object + */ + function &get_registered_object($name) { + if (!isset($this->_reg_objects[$name])) + $this->_trigger_fatal_error("'$name' is not a registered object"); + + if (!is_object($this->_reg_objects[$name][0])) + $this->_trigger_fatal_error("registered '$name' is not an object"); + + return $this->_reg_objects[$name][0]; + } + + /** + * clear configuration values + * + * @param string $var + */ + function clear_config($var = null) + { + if(!isset($var)) { + // clear all values + $this->_config = array(array('vars' => array(), + 'files' => array())); + } else { + unset($this->_config[0]['vars'][$var]); + } + } + + /** + * get filepath of requested plugin + * + * @param string $type + * @param string $name + * @return string|false + */ + function _get_plugin_filepath($type, $name) + { + $_params = array('type' => $type, 'name' => $name); + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); + return smarty_core_assemble_plugin_filepath($_params, $this); + } + + /** + * test if resource needs compiling + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _is_compiled($resource_name, $compile_path) + { + if (!$this->force_compile && file_exists($compile_path)) { + if (!$this->compile_check) { + // no need to check compiled file + return true; + } else { + // get file source and timestamp + $_params = array('resource_name' => $resource_name, 'get_source'=>false); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + if ($_params['resource_timestamp'] <= filemtime($compile_path)) { + // template not expired, no recompile + return true; + } else { + // compile template + return false; + } + } + } else { + // compiled template does not exist, or forced compile + return false; + } + } + + /** + * compile the template + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _compile_resource($resource_name, $compile_path) + { + + $_params = array('resource_name' => $resource_name); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + + $_source_content = $_params['source_content']; + $_cache_include = substr($compile_path, 0, -4).'.inc'; + + if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { + // if a _cache_serial was set, we also have to write an include-file: + if ($this->_cache_include_info) { + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); + } + + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $this); + + return true; + } else { + return false; + } + + } + + /** + * compile the given source + * + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return boolean + */ + function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) + { + if (file_exists(SMARTY_DIR . $this->compiler_file)) { + require_once(SMARTY_DIR . $this->compiler_file); + } else { + // use include_path + require_once($this->compiler_file); + } + + + $smarty_compiler = new $this->compiler_class; + + $smarty_compiler->template_dir = $this->template_dir; + $smarty_compiler->compile_dir = $this->compile_dir; + $smarty_compiler->plugins_dir = $this->plugins_dir; + $smarty_compiler->config_dir = $this->config_dir; + $smarty_compiler->force_compile = $this->force_compile; + $smarty_compiler->caching = $this->caching; + $smarty_compiler->php_handling = $this->php_handling; + $smarty_compiler->left_delimiter = $this->left_delimiter; + $smarty_compiler->right_delimiter = $this->right_delimiter; + $smarty_compiler->_version = $this->_version; + $smarty_compiler->security = $this->security; + $smarty_compiler->secure_dir = $this->secure_dir; + $smarty_compiler->security_settings = $this->security_settings; + $smarty_compiler->trusted_dir = $this->trusted_dir; + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; + $smarty_compiler->_reg_objects = &$this->_reg_objects; + $smarty_compiler->_plugins = &$this->_plugins; + $smarty_compiler->_tpl_vars = &$this->_tpl_vars; + $smarty_compiler->default_modifiers = $this->default_modifiers; + $smarty_compiler->compile_id = $this->_compile_id; + $smarty_compiler->_config = $this->_config; + $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; + + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + } + $smarty_compiler->_cache_include = $cache_include_path; + + + $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); + + if ($smarty_compiler->_cache_serial) { + $this->_cache_include_info = array( + 'cache_serial'=>$smarty_compiler->_cache_serial + ,'plugins_code'=>$smarty_compiler->_plugins_code + ,'include_file_path' => $cache_include_path); + + } else { + $this->_cache_include_info = null; + + } + + return $_results; + } + + /** + * Get the compile path for this resource + * + * @param string $resource_name + * @return string results of {@link _get_auto_filename()} + */ + function _get_compile_path($resource_name) + { + return $this->_get_auto_filename($this->compile_dir, $resource_name, + $this->_compile_id) . '.php'; + } + + /** + * fetch the template info. Gets timestamp, and source + * if get_source is true + * + * sets $source_content to the source of the template, and + * $resource_timestamp to its time stamp + * @param string $resource_name + * @param string $source_content + * @param integer $resource_timestamp + * @param boolean $get_source + * @param boolean $quiet + * @return boolean + */ + + function _fetch_resource_info(&$params) + { + if(!isset($params['get_source'])) { $params['get_source'] = true; } + if(!isset($params['quiet'])) { $params['quiet'] = false; } + + $_return = false; + $_params = array('resource_name' => $params['resource_name']) ; + if (isset($params['resource_base_path'])) + $_params['resource_base_path'] = $params['resource_base_path']; + else + $_params['resource_base_path'] = $this->template_dir; + + if ($this->_parse_resource_name($_params)) { + $_resource_type = $_params['resource_type']; + $_resource_name = $_params['resource_name']; + switch ($_resource_type) { + case 'file': + if ($params['get_source']) { + $params['source_content'] = $this->_read_file($_resource_name); + } + $params['resource_timestamp'] = filemtime($_resource_name); + $_return = is_file($_resource_name); + break; + + default: + // call resource functions to fetch the template source and timestamp + if ($params['get_source']) { + $_source_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], + array($_resource_name, &$params['source_content'], &$this)); + } else { + $_source_return = true; + } + + $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], + array($_resource_name, &$params['resource_timestamp'], &$this)); + + $_return = $_source_return && $_timestamp_return; + break; + } + } + + if (!$_return) { + // see if we can get a template with the default template handler + if (!empty($this->default_template_handler_func)) { + if (!is_callable($this->default_template_handler_func)) { + $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); + } else { + $_return = call_user_func_array( + $this->default_template_handler_func, + array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); + } + } + } + + if (!$_return) { + if (!$params['quiet']) { + $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); + } + } else if ($_return && $this->security) { + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if (!smarty_core_is_secure($_params, $this)) { + if (!$params['quiet']) + $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); + $params['source_content'] = null; + $params['resource_timestamp'] = null; + return false; + } + } + return $_return; + } + + + /** + * parse out the type and name from the resource + * + * @param string $resource_base_path + * @param string $resource_name + * @param string $resource_type + * @param string $resource_name + * @return boolean + */ + + function _parse_resource_name(&$params) + { + + // split tpl_path by the first colon + $_resource_name_parts = explode(':', $params['resource_name'], 2); + + if (count($_resource_name_parts) == 1) { + // no resource type given + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $_resource_name_parts[0]; + } else { + if(strlen($_resource_name_parts[0]) == 1) { + // 1 char is not resource type, but part of filepath + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $params['resource_name']; + } else { + $params['resource_type'] = $_resource_name_parts[0]; + $params['resource_name'] = $_resource_name_parts[1]; + } + } + + if ($params['resource_type'] == 'file') { + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { + // relative pathname to $params['resource_base_path'] + // use the first directory where the file is found + foreach ((array)$params['resource_base_path'] as $_curr_path) { + $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; + if (file_exists($_fullpath) && is_file($_fullpath)) { + $params['resource_name'] = $_fullpath; + return true; + } + // didn't find the file, try include_path + $_params = array('file_path' => $_fullpath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $this)) { + $params['resource_name'] = $_params['new_file_path']; + return true; + } + } + return false; + } else { + /* absolute path */ + return file_exists($params['resource_name']); + } + } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { + $_params = array('type' => $params['resource_type']); + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); + smarty_core_load_resource_plugin($_params, $this); + } + + return true; + } + + + /** + * Handle modifiers + * + * @param string|null $modifier_name + * @param array|null $map_array + * @return string result of modifiers + */ + function _run_mod_handler() + { + $_args = func_get_args(); + list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); + list($_func_name, $_tpl_file, $_tpl_line) = + $this->_plugins['modifier'][$_modifier_name]; + + $_var = $_args[0]; + foreach ($_var as $_key => $_val) { + $_args[0] = $_val; + $_var[$_key] = call_user_func_array($_func_name, $_args); + } + return $_var; + } + + /** + * Remove starting and ending quotes from the string + * + * @param string $string + * @return string + */ + function _dequote($string) + { + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && + substr($string, -1) == substr($string, 0, 1)) + return substr($string, 1, -1); + else + return $string; + } + + + /** + * read in a file + * + * @param string $filename + * @return string + */ + function _read_file($filename) + { + if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { + $contents = ''; + while (!feof($fd)) { + $contents .= fread($fd, 8192); + } + fclose($fd); + return $contents; + } else { + return false; + } + } + + /** + * get a concrete filename for automagically created content + * + * @param string $auto_base + * @param string $auto_source + * @param string $auto_id + * @return string + * @staticvar string|null + * @staticvar string|null + */ + function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) + { + $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; + $_return = $auto_base . DIRECTORY_SEPARATOR; + + if(isset($auto_id)) { + // make auto_id safe for directory names + $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); + // split into separate directories + $_return .= $auto_id . $_compile_dir_sep; + } + + if(isset($auto_source)) { + // make source name safe for filename + $_filename = urlencode(basename($auto_source)); + $_crc32 = sprintf('%08X', crc32($auto_source)); + // prepend %% to avoid name conflicts with + // with $params['auto_id'] names + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; + $_return .= '%%' . $_crc32 . '%%' . $_filename; + } + + return $_return; + } + + /** + * unlink a file, possibly using expiration time + * + * @param string $resource + * @param integer $exp_time + */ + function _unlink($resource, $exp_time = null) + { + if(isset($exp_time)) { + if(time() - @filemtime($resource) >= $exp_time) { + return @unlink($resource); + } + } else { + return @unlink($resource); + } + } + + /** + * returns an auto_id for auto-file-functions + * + * @param string $cache_id + * @param string $compile_id + * @return string|null + */ + function _get_auto_id($cache_id=null, $compile_id=null) { + if (isset($cache_id)) + return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; + elseif(isset($compile_id)) + return $compile_id; + else + return null; + } + + /** + * trigger Smarty plugin error + * + * @param string $error_msg + * @param string $tpl_file + * @param integer $tpl_line + * @param string $file + * @param integer $line + * @param integer $error_type + */ + function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, + $file = null, $line = null, $error_type = E_USER_ERROR) + { + if(isset($file) && isset($line)) { + $info = ' ('.basename($file).", line $line)"; + } else { + $info = ''; + } + if (isset($tpl_line) && isset($tpl_file)) { + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); + } else { + $this->trigger_error($error_msg . $info, $error_type); + } + } + + + /** + * callback function for preg_replace, to call a non-cacheable block + * @return string + */ + function _process_compiled_include_callback($match) { + $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; + ob_start(); + $_func($this); + $_ret = ob_get_contents(); + ob_end_clean(); + return $_ret; + } + + + /** + * called for included templates + * + * @param string $_smarty_include_tpl_file + * @param string $_smarty_include_vars + */ + + // $_smarty_include_tpl_file, $_smarty_include_vars + + function _smarty_include($params) + { + if ($this->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $params['smarty_include_tpl_file'], + 'depth' => ++$this->_inclusion_depth); + $included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); + + // config vars are treated as local, so push a copy of the + // current ones onto the front of the stack + array_unshift($this->_config, $this->_config[0]); + + $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); + + + if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) + || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + + // pop the local vars off the front of the stack + array_shift($this->_config); + + $this->_inclusion_depth--; + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; + } + + if ($this->caching) { + $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; + } + } + + + /** + * get or set an array of cached attributes for function that is + * not cacheable + * @return array + */ + function &_smarty_cache_attrs($cache_serial, $count) { + $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; + + if ($this->_cache_including) { + /* return next set of cache_attrs */ + $_return = current($_cache_attrs); + next($_cache_attrs); + return $_return; + + } else { + /* add a reference to a new set of cache_attrs */ + $_cache_attrs[] = array(); + return $_cache_attrs[count($_cache_attrs)-1]; + + } + + } + + + /** + * wrapper for include() retaining $this + * @return mixed + */ + function _include($filename, $once=false, $params=null) + { + if ($once) { + return include_once($filename); + } else { + return include($filename); + } + } + + + /** + * wrapper for eval() retaining $this + * @return mixed + */ + function _eval($code, $params=null) + { + return eval($code); + } + + /** + * Extracts the filter name from the given callback + * + * @param callback $function + * @return string + */ + function _get_filter_name($function) + { + if (is_array($function)) { + $_class_name = (is_object($function[0]) ? + get_class($function[0]) : $function[0]); + return $_class_name . '_' . $function[1]; + } + else { + return $function; + } + } + + /**#@-*/ + +} + +/* vim: set expandtab: */ + +?> diff --git a/libs/Smarty/Smarty_Compiler.class.php b/libs/Smarty/Smarty_Compiler.class.php index d3e41ee040..408f294ade 100755 --- a/libs/Smarty/Smarty_Compiler.class.php +++ b/libs/Smarty/Smarty_Compiler.class.php @@ -1,2351 +1,2351 @@ -<?php
-
-/**
- * Project: Smarty: the PHP compiling template engine
- * File: Smarty_Compiler.class.php
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @link http://www.smarty.net/
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Andrei Zmievski <andrei@php.net>
- * @version 2.6.22
- * @copyright 2001-2005 New Digital Group, Inc.
- * @package Smarty
- */
-
-/* $Id$ */
-
-/**
- * Template compiling class
- * @package Smarty
- */
-class Smarty_Compiler extends Smarty {
-
- // internal vars
- /**#@+
- * @access private
- */
- var $_folded_blocks = array(); // keeps folded template blocks
- var $_current_file = null; // the current template being compiled
- var $_current_line_no = 1; // line number for error messages
- var $_capture_stack = array(); // keeps track of nested capture buffers
- var $_plugin_info = array(); // keeps track of plugins to load
- var $_init_smarty_vars = false;
- var $_permitted_tokens = array('true','false','yes','no','on','off','null');
- var $_db_qstr_regexp = null; // regexps are setup in the constructor
- var $_si_qstr_regexp = null;
- var $_qstr_regexp = null;
- var $_func_regexp = null;
- var $_reg_obj_regexp = null;
- var $_var_bracket_regexp = null;
- var $_num_const_regexp = null;
- var $_dvar_guts_regexp = null;
- var $_dvar_regexp = null;
- var $_cvar_regexp = null;
- var $_svar_regexp = null;
- var $_avar_regexp = null;
- var $_mod_regexp = null;
- var $_var_regexp = null;
- var $_parenth_param_regexp = null;
- var $_func_call_regexp = null;
- var $_obj_ext_regexp = null;
- var $_obj_start_regexp = null;
- var $_obj_params_regexp = null;
- var $_obj_call_regexp = null;
- var $_cacheable_state = 0;
- var $_cache_attrs_count = 0;
- var $_nocache_count = 0;
- var $_cache_serial = null;
- var $_cache_include = null;
-
- var $_strip_depth = 0;
- var $_additional_newline = "\n";
-
- var $_phpversion = 0;
-
-
- /**#@-*/
- /**
- * The class constructor.
- */
- function Smarty_Compiler()
- {
- $this->_phpversion = substr(phpversion(),0,1);
-
- // matches double quoted strings:
- // "foobar"
- // "foo\"bar"
- $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
-
- // matches single quoted strings:
- // 'foobar'
- // 'foo\'bar'
- $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
-
- // matches single or double quoted strings
- $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
-
- // matches bracket portion of vars
- // [0]
- // [foo]
- // [$bar]
- $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
-
- // matches numerical constants
- // 30
- // -12
- // 13.22
- $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
-
- // matches $ vars (not objects):
- // $foo
- // $foo.bar
- // $foo.bar.foobar
- // $foo[0]
- // $foo[$bar]
- // $foo[5][blah]
- // $foo[5].bar[$foobar][4]
- $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
- $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
- $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
- . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
- $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
-
- // matches config vars:
- // #foo#
- // #foobar123_foo#
- $this->_cvar_regexp = '\#\w+\#';
-
- // matches section vars:
- // %foo.bar%
- $this->_svar_regexp = '\%\w+\.\w+\%';
-
- // matches all valid variables (no quotes, no modifiers)
- $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
- . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
-
- // matches valid variable syntax:
- // $foo
- // $foo
- // #foo#
- // #foo#
- // "text"
- // "text"
- $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
-
- // matches valid object call (one level of object nesting allowed in parameters):
- // $foo->bar
- // $foo->bar()
- // $foo->bar("text")
- // $foo->bar($foo, $bar, "text")
- // $foo->bar($foo, "foo")
- // $foo->bar->foo()
- // $foo->bar->foo->bar()
- // $foo->bar($foo->bar)
- // $foo->bar($foo->bar())
- // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
- // $foo->getBar()->getFoo()
- // $foo->getBar()->foo
- $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
- $this->_obj_restricted_param_regexp = '(?:'
- . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
- . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
-
- $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
- . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
-
- $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
- . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
- $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
- $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
-
- // matches valid modifier syntax:
- // |foo
- // |@foo
- // |foo:"bar"
- // |foo:$bar
- // |foo:"bar":$foobar
- // |foo|bar
- // |foo:$foo->bar
- $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
- . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
-
- // matches valid function name:
- // foo123
- // _foo_bar
- $this->_func_regexp = '[a-zA-Z_]\w*';
-
- // matches valid registered object:
- // foo->bar
- $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
-
- // matches valid parameter values:
- // true
- // $foo
- // $foo|bar
- // #foo#
- // #foo#|bar
- // "text"
- // "text"|bar
- // $foo->bar
- $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
- . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
-
- // matches valid parenthesised function parameters:
- //
- // "text"
- // $foo, $bar, "text"
- // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
- $this->_parenth_param_regexp = '(?:\((?:\w+|'
- . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
- . $this->_param_regexp . ')))*)?\))';
-
- // matches valid function call:
- // foo()
- // foo_bar($foo)
- // _foo_bar($foo,"bar")
- // foo123($foo,$foo->bar(),"foo")
- $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
- . $this->_parenth_param_regexp . '))';
- }
-
- /**
- * compile a resource
- *
- * sets $compiled_content to the compiled source
- * @param string $resource_name
- * @param string $source_content
- * @param string $compiled_content
- * @return true
- */
- function _compile_file($resource_name, $source_content, &$compiled_content)
- {
-
- if ($this->security) {
- // do not allow php syntax to be executed unless specified
- if ($this->php_handling == SMARTY_PHP_ALLOW &&
- !$this->security_settings['PHP_HANDLING']) {
- $this->php_handling = SMARTY_PHP_PASSTHRU;
- }
- }
-
- $this->_load_filters();
-
- $this->_current_file = $resource_name;
- $this->_current_line_no = 1;
- $ldq = preg_quote($this->left_delimiter, '~');
- $rdq = preg_quote($this->right_delimiter, '~');
-
- // run template source through prefilter functions
- if (count($this->_plugins['prefilter']) > 0) {
- foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
- if ($prefilter === false) continue;
- if ($prefilter[3] || is_callable($prefilter[0])) {
- $source_content = call_user_func_array($prefilter[0],
- array($source_content, &$this));
- $this->_plugins['prefilter'][$filter_name][3] = true;
- } else {
- $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
- }
- }
- }
-
- /* fetch all special blocks */
- $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
-
- preg_match_all($search, $source_content, $match, PREG_SET_ORDER);
- $this->_folded_blocks = $match;
- reset($this->_folded_blocks);
-
- /* replace special blocks by "{php}" */
- $source_content = preg_replace($search.'e', "'"
- . $this->_quote_replace($this->left_delimiter) . 'php'
- . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
- . $this->_quote_replace($this->right_delimiter)
- . "'"
- , $source_content);
-
- /* Gather all template tags. */
- preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
- $template_tags = $_match[1];
- /* Split content by template tags to obtain non-template content. */
- $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
-
- /* loop through text blocks */
- for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
- /* match anything resembling php tags */
- if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
- /* replace tags with placeholders to prevent recursive replacements */
- $sp_match[1] = array_unique($sp_match[1]);
- usort($sp_match[1], '_smarty_sort_length');
- for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
- $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
- }
- /* process each one */
- for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
- if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
- /* echo php contents */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
- } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
- /* quote php tags */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
- } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
- /* remove php tags */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
- } else {
- /* SMARTY_PHP_ALLOW, but echo non php starting tags */
- $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
- }
- }
- }
- }
-
- /* Compile the template tags into PHP code. */
- $compiled_tags = array();
- for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
- $this->_current_line_no += substr_count($text_blocks[$i], "\n");
- $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
- $this->_current_line_no += substr_count($template_tags[$i], "\n");
- }
- if (count($this->_tag_stack)>0) {
- list($_open_tag, $_line_no) = end($this->_tag_stack);
- $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
- return;
- }
-
- /* Reformat $text_blocks between 'strip' and '/strip' tags,
- removing spaces, tabs and newlines. */
- $strip = false;
- for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
- if ($compiled_tags[$i] == '{strip}') {
- $compiled_tags[$i] = '';
- $strip = true;
- /* remove leading whitespaces */
- $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
- }
- if ($strip) {
- /* strip all $text_blocks before the next '/strip' */
- for ($j = $i + 1; $j < $for_max; $j++) {
- /* remove leading and trailing whitespaces of each line */
- $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
- if ($compiled_tags[$j] == '{/strip}') {
- /* remove trailing whitespaces from the last text_block */
- $text_blocks[$j] = rtrim($text_blocks[$j]);
- }
- $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
- if ($compiled_tags[$j] == '{/strip}') {
- $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
- if a newline is following the closing strip-tag */
- $strip = false;
- $i = $j;
- break;
- }
- }
- }
- }
- $compiled_content = '';
-
- $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
-
- /* Interleave the compiled contents and text blocks to get the final result. */
- for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
- if ($compiled_tags[$i] == '') {
- // tag result empty, remove first newline from following text block
- $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
- }
- // replace legit PHP tags with placeholder
- $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
- $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
-
- $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
- }
- $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
-
- // escape php tags created by interleaving
- $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
- $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
-
- // recover legit tags
- $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
-
- // remove \n from the end of the file, if any
- if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
- $compiled_content = substr($compiled_content, 0, -1);
- }
-
- if (!empty($this->_cache_serial)) {
- $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
- }
-
- // run compiled template through postfilter functions
- if (count($this->_plugins['postfilter']) > 0) {
- foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
- if ($postfilter === false) continue;
- if ($postfilter[3] || is_callable($postfilter[0])) {
- $compiled_content = call_user_func_array($postfilter[0],
- array($compiled_content, &$this));
- $this->_plugins['postfilter'][$filter_name][3] = true;
- } else {
- $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
- }
- }
- }
-
- // put header at the top of the compiled template
- $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
- $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
-
- /* Emit code to load needed plugins. */
- $this->_plugins_code = '';
- if (count($this->_plugin_info)) {
- $_plugins_params = "array('plugins' => array(";
- foreach ($this->_plugin_info as $plugin_type => $plugins) {
- foreach ($plugins as $plugin_name => $plugin_info) {
- $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
- $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
- }
- }
- $_plugins_params .= '))';
- $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
- $template_header .= $plugins_code;
- $this->_plugin_info = array();
- $this->_plugins_code = $plugins_code;
- }
-
- if ($this->_init_smarty_vars) {
- $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
- $this->_init_smarty_vars = false;
- }
-
- $compiled_content = $template_header . $compiled_content;
- return true;
- }
-
- /**
- * Compile a template tag
- *
- * @param string $template_tag
- * @return string
- */
- function _compile_tag($template_tag)
- {
- /* Matched comment. */
- if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
- return '';
-
- /* Split tag into two three parts: command, command modifiers and the arguments. */
- if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
- . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
- (?:\s+(.*))?$
- ~xs', $template_tag, $match)) {
- $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $tag_command = $match[1];
- $tag_modifier = isset($match[2]) ? $match[2] : null;
- $tag_args = isset($match[3]) ? $match[3] : null;
-
- if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
- /* tag name is a variable or object */
- $_return = $this->_parse_var_props($tag_command . $tag_modifier);
- return "<?php echo $_return; ?>" . $this->_additional_newline;
- }
-
- /* If the tag name is a registered object, we process it. */
- if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
- return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
- }
-
- switch ($tag_command) {
- case 'include':
- return $this->_compile_include_tag($tag_args);
-
- case 'include_php':
- return $this->_compile_include_php_tag($tag_args);
-
- case 'if':
- $this->_push_tag('if');
- return $this->_compile_if_tag($tag_args);
-
- case 'else':
- list($_open_tag) = end($this->_tag_stack);
- if ($_open_tag != 'if' && $_open_tag != 'elseif')
- $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
- else
- $this->_push_tag('else');
- return '<?php else: ?>';
-
- case 'elseif':
- list($_open_tag) = end($this->_tag_stack);
- if ($_open_tag != 'if' && $_open_tag != 'elseif')
- $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
- if ($_open_tag == 'if')
- $this->_push_tag('elseif');
- return $this->_compile_if_tag($tag_args, true);
-
- case '/if':
- $this->_pop_tag('if');
- return '<?php endif; ?>';
-
- case 'capture':
- return $this->_compile_capture_tag(true, $tag_args);
-
- case '/capture':
- return $this->_compile_capture_tag(false);
-
- case 'ldelim':
- return $this->left_delimiter;
-
- case 'rdelim':
- return $this->right_delimiter;
-
- case 'section':
- $this->_push_tag('section');
- return $this->_compile_section_start($tag_args);
-
- case 'sectionelse':
- $this->_push_tag('sectionelse');
- return "<?php endfor; else: ?>";
- break;
-
- case '/section':
- $_open_tag = $this->_pop_tag('section');
- if ($_open_tag == 'sectionelse')
- return "<?php endif; ?>";
- else
- return "<?php endfor; endif; ?>";
-
- case 'foreach':
- $this->_push_tag('foreach');
- return $this->_compile_foreach_start($tag_args);
- break;
-
- case 'foreachelse':
- $this->_push_tag('foreachelse');
- return "<?php endforeach; else: ?>";
-
- case '/foreach':
- $_open_tag = $this->_pop_tag('foreach');
- if ($_open_tag == 'foreachelse')
- return "<?php endif; unset(\$_from); ?>";
- else
- return "<?php endforeach; endif; unset(\$_from); ?>";
- break;
-
- case 'strip':
- case '/strip':
- if (substr($tag_command, 0, 1)=='/') {
- $this->_pop_tag('strip');
- if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
- $this->_additional_newline = "\n";
- return '{' . $tag_command . '}';
- }
- } else {
- $this->_push_tag('strip');
- if ($this->_strip_depth++==0) { /* outermost opening {strip} */
- $this->_additional_newline = "";
- return '{' . $tag_command . '}';
- }
- }
- return '';
-
- case 'php':
- /* handle folded tags replaced by {php} */
- list(, $block) = each($this->_folded_blocks);
- $this->_current_line_no += substr_count($block[0], "\n");
- /* the number of matched elements in the regexp in _compile_file()
- determins the type of folded tag that was found */
- switch (count($block)) {
- case 2: /* comment */
- return '';
-
- case 3: /* literal */
- return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
-
- case 4: /* php */
- if ($this->security && !$this->security_settings['PHP_TAGS']) {
- $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- return '<?php ' . $block[3] .' ?>';
- }
- break;
-
- case 'insert':
- return $this->_compile_insert_tag($tag_args);
-
- default:
- if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
- return $output;
- } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
- return $output;
- } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
- return $output;
- } else {
- $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- }
- }
-
-
- /**
- * compile the custom compiler tag
- *
- * sets $output to the compiled custom compiler tag
- * @param string $tag_command
- * @param string $tag_args
- * @param string $output
- * @return boolean
- */
- function _compile_compiler_tag($tag_command, $tag_args, &$output)
- {
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the compiler function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['compiler'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['compiler'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "compiler function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_compiler_' . $tag_command;
- if (!is_callable($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
- }
- }
-
- /*
- * True return value means that we either found a plugin or a
- * dynamically registered function. False means that we didn't and the
- * compiler should now emit code to load custom function plugin for this
- * tag.
- */
- if ($found) {
- if ($have_function) {
- $output = call_user_func_array($plugin_func, array($tag_args, &$this));
- if($output != '') {
- $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
- . $output
- . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
- }
- } else {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- }
- return true;
- } else {
- return false;
- }
- }
-
-
- /**
- * compile block function tag
- *
- * sets $output to compiled block function tag
- * @param string $tag_command
- * @param string $tag_args
- * @param string $tag_modifier
- * @param string $output
- * @return boolean
- */
- function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
- {
- if (substr($tag_command, 0, 1) == '/') {
- $start_tag = false;
- $tag_command = substr($tag_command, 1);
- } else
- $start_tag = true;
-
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the block function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['block'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['block'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "block function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_block_' . $tag_command;
- if (!function_exists($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
-
- }
- }
-
- if (!$found) {
- return false;
- } else if (!$have_function) {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- return true;
- }
-
- /*
- * Even though we've located the plugin function, compilation
- * happens only once, so the plugin will still need to be loaded
- * at runtime for future requests.
- */
- $this->_add_plugin('block', $tag_command);
-
- if ($start_tag)
- $this->_push_tag($tag_command);
- else
- $this->_pop_tag($tag_command);
-
- if ($start_tag) {
- $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
- $attrs = $this->_parse_attrs($tag_args);
- $_cache_attrs='';
- $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
- $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
- $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
- $output .= 'while ($_block_repeat) { ob_start(); ?>';
- } else {
- $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
- $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
- if ($tag_modifier != '') {
- $this->_parse_modifiers($_out_tag_text, $tag_modifier);
- }
- $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
- $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
- }
-
- return true;
- }
-
-
- /**
- * compile custom function tag
- *
- * @param string $tag_command
- * @param string $tag_args
- * @param string $tag_modifier
- * @return string
- */
- function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
- {
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the custom function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['function'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['function'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "custom function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_function_' . $tag_command;
- if (!function_exists($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
-
- }
- }
-
- if (!$found) {
- return false;
- } else if (!$have_function) {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- return true;
- }
-
- /* declare plugin to be loaded on display of the template that
- we compile right now */
- $this->_add_plugin('function', $tag_command);
-
- $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
- $attrs = $this->_parse_attrs($tag_args);
- $_cache_attrs = '';
- $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
-
- $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
- if($tag_modifier != '') {
- $this->_parse_modifiers($output, $tag_modifier);
- }
-
- if($output != '') {
- $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
- . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
- }
-
- return true;
- }
-
- /**
- * compile a registered object tag
- *
- * @param string $tag_command
- * @param array $attrs
- * @param string $tag_modifier
- * @return string
- */
- function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
- {
- if (substr($tag_command, 0, 1) == '/') {
- $start_tag = false;
- $tag_command = substr($tag_command, 1);
- } else {
- $start_tag = true;
- }
-
- list($object, $obj_comp) = explode('->', $tag_command);
-
- $arg_list = array();
- if(count($attrs)) {
- $_assign_var = false;
- foreach ($attrs as $arg_name => $arg_value) {
- if($arg_name == 'assign') {
- $_assign_var = $arg_value;
- unset($attrs['assign']);
- continue;
- }
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
-
- if($this->_reg_objects[$object][2]) {
- // smarty object argument format
- $args = "array(".implode(',', (array)$arg_list)."), \$this";
- } else {
- // traditional argument format
- $args = implode(',', array_values($attrs));
- if (empty($args)) {
- $args = '';
- }
- }
-
- $prefix = '';
- $postfix = '';
- $newline = '';
- if(!is_object($this->_reg_objects[$object][0])) {
- $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
- $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
- // method
- if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
- // block method
- if ($start_tag) {
- $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
- $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
- $prefix .= "while (\$_block_repeat) { ob_start();";
- $return = null;
- $postfix = '';
- } else {
- $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
- $postfix = "} array_pop(\$this->_tag_stack);";
- }
- } else {
- // non-block method
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
- }
- } else {
- // property
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
- }
-
- if($return != null) {
- if($tag_modifier != '') {
- $this->_parse_modifiers($return, $tag_modifier);
- }
-
- if(!empty($_assign_var)) {
- $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);";
- } else {
- $output = 'echo ' . $return . ';';
- $newline = $this->_additional_newline;
- }
- } else {
- $output = '';
- }
-
- return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
- }
-
- /**
- * Compile {insert ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_insert_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $name = $this->_dequote($attrs['name']);
-
- if (empty($name)) {
- return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (!preg_match('~^\w+$~', $name)) {
- return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (!empty($attrs['script'])) {
- $delayed_loading = true;
- } else {
- $delayed_loading = false;
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
-
- $this->_add_plugin('insert', $name, $delayed_loading);
-
- $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
-
- return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
- }
-
- /**
- * Compile {include ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_include_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- if (empty($attrs['file'])) {
- $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if ($arg_name == 'file') {
- $include_file = $arg_value;
- continue;
- } else if ($arg_name == 'assign') {
- $assign_var = $arg_value;
- continue;
- }
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
-
- $output = '<?php ';
-
- if (isset($assign_var)) {
- $output .= "ob_start();\n";
- }
-
- $output .=
- "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
-
-
- $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
- $output .= "\$this->_smarty_include($_params);\n" .
- "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
- "unset(\$_smarty_tpl_vars);\n";
-
- if (isset($assign_var)) {
- $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
- }
-
- $output .= ' ?>';
-
- return $output;
-
- }
-
- /**
- * Compile {include ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_include_php_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
-
- if (empty($attrs['file'])) {
- $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
- $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
-
- $arg_list = array();
- foreach($attrs as $arg_name => $arg_value) {
- if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
- if(is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
-
- $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
-
- return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
- }
-
-
- /**
- * Compile {section ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_section_start($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- $output = '<?php ';
- $section_name = $attrs['name'];
- if (empty($section_name)) {
- $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $output .= "unset(\$this->_sections[$section_name]);\n";
- $section_props = "\$this->_sections[$section_name]";
-
- foreach ($attrs as $attr_name => $attr_value) {
- switch ($attr_name) {
- case 'loop':
- $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
- break;
-
- case 'show':
- if (is_bool($attr_value))
- $show_attr_value = $attr_value ? 'true' : 'false';
- else
- $show_attr_value = "(bool)$attr_value";
- $output .= "{$section_props}['show'] = $show_attr_value;\n";
- break;
-
- case 'name':
- $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
- break;
-
- case 'max':
- case 'start':
- $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
- break;
-
- case 'step':
- $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
- break;
-
- default:
- $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
- }
-
- if (!isset($attrs['show']))
- $output .= "{$section_props}['show'] = true;\n";
-
- if (!isset($attrs['loop']))
- $output .= "{$section_props}['loop'] = 1;\n";
-
- if (!isset($attrs['max']))
- $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
- else
- $output .= "if ({$section_props}['max'] < 0)\n" .
- " {$section_props}['max'] = {$section_props}['loop'];\n";
-
- if (!isset($attrs['step']))
- $output .= "{$section_props}['step'] = 1;\n";
-
- if (!isset($attrs['start']))
- $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
- else {
- $output .= "if ({$section_props}['start'] < 0)\n" .
- " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
- "else\n" .
- " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
- }
-
- $output .= "if ({$section_props}['show']) {\n";
- if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
- $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
- } else {
- $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
- }
- $output .= " if ({$section_props}['total'] == 0)\n" .
- " {$section_props}['show'] = false;\n" .
- "} else\n" .
- " {$section_props}['total'] = 0;\n";
-
- $output .= "if ({$section_props}['show']):\n";
- $output .= "
- for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
- {$section_props}['iteration'] <= {$section_props}['total'];
- {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
- $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
- $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
- $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
- $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
- $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
-
- $output .= "?>";
-
- return $output;
- }
-
-
- /**
- * Compile {foreach ...} tag.
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_foreach_start($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- if (empty($attrs['from'])) {
- return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
- }
- $from = $attrs['from'];
-
- if (empty($attrs['item'])) {
- return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
- }
- $item = $this->_dequote($attrs['item']);
- if (!preg_match('~^\w+$~', $item)) {
- return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (isset($attrs['key'])) {
- $key = $this->_dequote($attrs['key']);
- if (!preg_match('~^\w+$~', $key)) {
- return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
- }
- $key_part = "\$this->_tpl_vars['$key'] => ";
- } else {
- $key = null;
- $key_part = '';
- }
-
- if (isset($attrs['name'])) {
- $name = $attrs['name'];
- } else {
- $name = null;
- }
-
- $output = '<?php ';
- $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
- if (isset($name)) {
- $foreach_props = "\$this->_foreach[$name]";
- $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
- $output .= "if ({$foreach_props}['total'] > 0):\n";
- $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
- $output .= " {$foreach_props}['iteration']++;\n";
- } else {
- $output .= "if (count(\$_from)):\n";
- $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
- }
- $output .= '?>';
-
- return $output;
- }
-
-
- /**
- * Compile {capture} .. {/capture} tags
- *
- * @param boolean $start true if this is the {capture} tag
- * @param string $tag_args
- * @return string
- */
-
- function _compile_capture_tag($start, $tag_args = '')
- {
- $attrs = $this->_parse_attrs($tag_args);
-
- if ($start) {
- $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
- $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
- $append = isset($attrs['append']) ? $attrs['append'] : null;
-
- $output = "<?php ob_start(); ?>";
- $this->_capture_stack[] = array($buffer, $assign, $append);
- } else {
- list($buffer, $assign, $append) = array_pop($this->_capture_stack);
- $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
- if (isset($assign)) {
- $output .= " \$this->assign($assign, ob_get_contents());";
- }
- if (isset($append)) {
- $output .= " \$this->append($append, ob_get_contents());";
- }
- $output .= "ob_end_clean(); ?>";
- }
-
- return $output;
- }
-
- /**
- * Compile {if ...} tag
- *
- * @param string $tag_args
- * @param boolean $elseif if true, uses elseif instead of if
- * @return string
- */
- function _compile_if_tag($tag_args, $elseif = false)
- {
-
- /* Tokenize args for 'if' tag. */
- preg_match_all('~(?>
- ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
- ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string
- \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token
- \b\w+\b | # valid word token
- \S+ # anything else
- )~x', $tag_args, $match);
-
- $tokens = $match[0];
-
- if(empty($tokens)) {
- $_error_msg = $elseif ? "'elseif'" : "'if'";
- $_error_msg .= ' statement requires arguments';
- $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
- }
-
-
- // make sure we have balanced parenthesis
- $token_count = array_count_values($tokens);
- if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
- $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $is_arg_stack = array();
-
- for ($i = 0; $i < count($tokens); $i++) {
-
- $token = &$tokens[$i];
-
- switch (strtolower($token)) {
- case '!':
- case '%':
- case '!==':
- case '==':
- case '===':
- case '>':
- case '<':
- case '!=':
- case '<>':
- case '<<':
- case '>>':
- case '<=':
- case '>=':
- case '&&':
- case '||':
- case '|':
- case '^':
- case '&':
- case '~':
- case ')':
- case ',':
- case '+':
- case '-':
- case '*':
- case '/':
- case '@':
- break;
-
- case 'eq':
- $token = '==';
- break;
-
- case 'ne':
- case 'neq':
- $token = '!=';
- break;
-
- case 'lt':
- $token = '<';
- break;
-
- case 'le':
- case 'lte':
- $token = '<=';
- break;
-
- case 'gt':
- $token = '>';
- break;
-
- case 'ge':
- case 'gte':
- $token = '>=';
- break;
-
- case 'and':
- $token = '&&';
- break;
-
- case 'or':
- $token = '||';
- break;
-
- case 'not':
- $token = '!';
- break;
-
- case 'mod':
- $token = '%';
- break;
-
- case '(':
- array_push($is_arg_stack, $i);
- break;
-
- case 'is':
- /* If last token was a ')', we operate on the parenthesized
- expression. The start of the expression is on the stack.
- Otherwise, we operate on the last encountered token. */
- if ($tokens[$i-1] == ')') {
- $is_arg_start = array_pop($is_arg_stack);
- if ($is_arg_start != 0) {
- if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
- $is_arg_start--;
- }
- }
- } else
- $is_arg_start = $i-1;
- /* Construct the argument for 'is' expression, so it knows
- what to operate on. */
- $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
-
- /* Pass all tokens from next one until the end to the
- 'is' expression parsing function. The function will
- return modified tokens, where the first one is the result
- of the 'is' expression and the rest are the tokens it
- didn't touch. */
- $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
-
- /* Replace the old tokens with the new ones. */
- array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
-
- /* Adjust argument start so that it won't change from the
- current position for the next iteration. */
- $i = $is_arg_start;
- break;
-
- default:
- if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
- // function call
- if($this->security &&
- !in_array($token, $this->security_settings['IF_FUNCS'])) {
- $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
- }
- } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
- // variable function call
- $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
- } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
- // object or variable
- $token = $this->_parse_var_props($token);
- } elseif(is_numeric($token)) {
- // number, skip it
- } else {
- $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
- }
- break;
- }
- }
-
- if ($elseif)
- return '<?php elseif ('.implode(' ', $tokens).'): ?>';
- else
- return '<?php if ('.implode(' ', $tokens).'): ?>';
- }
-
-
- function _compile_arg_list($type, $name, $attrs, &$cache_code) {
- $arg_list = array();
-
- if (isset($type) && isset($name)
- && isset($this->_plugins[$type])
- && isset($this->_plugins[$type][$name])
- && empty($this->_plugins[$type][$name][4])
- && is_array($this->_plugins[$type][$name][5])
- ) {
- /* we have a list of parameters that should be cached */
- $_cache_attrs = $this->_plugins[$type][$name][5];
- $_count = $this->_cache_attrs_count++;
- $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
-
- } else {
- /* no parameters are cached */
- $_cache_attrs = null;
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- if (is_null($arg_value))
- $arg_value = 'null';
- if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
- $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
- } else {
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
- return $arg_list;
- }
-
- /**
- * Parse is expression
- *
- * @param string $is_arg
- * @param array $tokens
- * @return array
- */
- function _parse_is_expr($is_arg, $tokens)
- {
- $expr_end = 0;
- $negate_expr = false;
-
- if (($first_token = array_shift($tokens)) == 'not') {
- $negate_expr = true;
- $expr_type = array_shift($tokens);
- } else
- $expr_type = $first_token;
-
- switch ($expr_type) {
- case 'even':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
- } else
- $expr = "!(1 & $is_arg)";
- break;
-
- case 'odd':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
- } else
- $expr = "(1 & $is_arg)";
- break;
-
- case 'div':
- if (@$tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
- } else {
- $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
- }
- break;
-
- default:
- $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
-
- if ($negate_expr) {
- $expr = "!($expr)";
- }
-
- array_splice($tokens, 0, $expr_end, $expr);
-
- return $tokens;
- }
-
-
- /**
- * Parse attribute string
- *
- * @param string $tag_args
- * @return array
- */
- function _parse_attrs($tag_args)
- {
-
- /* Tokenize tag attributes. */
- preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
- )+ |
- [=]
- ~x', $tag_args, $match);
- $tokens = $match[0];
-
- $attrs = array();
- /* Parse state:
- 0 - expecting attribute name
- 1 - expecting '='
- 2 - expecting attribute value (not '=') */
- $state = 0;
-
- foreach ($tokens as $token) {
- switch ($state) {
- case 0:
- /* If the token is a valid identifier, we set attribute name
- and go to state 1. */
- if (preg_match('~^\w+$~', $token)) {
- $attr_name = $token;
- $state = 1;
- } else
- $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
-
- case 1:
- /* If the token is '=', then we go to state 2. */
- if ($token == '=') {
- $state = 2;
- } else
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
-
- case 2:
- /* If token is not '=', we set the attribute value and go to
- state 0. */
- if ($token != '=') {
- /* We booleanize the token if it's a non-quoted possible
- boolean value. */
- if (preg_match('~^(on|yes|true)$~', $token)) {
- $token = 'true';
- } else if (preg_match('~^(off|no|false)$~', $token)) {
- $token = 'false';
- } else if ($token == 'null') {
- $token = 'null';
- } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
- /* treat integer literally */
- } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
- /* treat as a string, double-quote it escaping quotes */
- $token = '"'.addslashes($token).'"';
- }
-
- $attrs[$attr_name] = $token;
- $state = 0;
- } else
- $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
- $last_token = $token;
- }
-
- if($state != 0) {
- if($state == 1) {
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- } else {
- $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
- }
- }
-
- $this->_parse_vars_props($attrs);
-
- return $attrs;
- }
-
- /**
- * compile multiple variables and section properties tokens into
- * PHP code
- *
- * @param array $tokens
- */
- function _parse_vars_props(&$tokens)
- {
- foreach($tokens as $key => $val) {
- $tokens[$key] = $this->_parse_var_props($val);
- }
- }
-
- /**
- * compile single variable and section properties token into
- * PHP code
- *
- * @param string $val
- * @param string $tag_attrs
- * @return string
- */
- function _parse_var_props($val)
- {
- $val = trim($val);
-
- if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
- // $ variable or object
- $return = $this->_parse_var($match[1]);
- $modifiers = $match[2];
- if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
- $_default_mod_string = implode('|',(array)$this->default_modifiers);
- $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
- }
- $this->_parse_modifiers($return, $modifiers);
- return $return;
- } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // double quoted text
- preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- $return = $this->_expand_quoted_text($match[1]);
- if($match[2] != '') {
- $this->_parse_modifiers($return, $match[2]);
- }
- return $return;
- }
- elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // numerical constant
- preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- if($match[2] != '') {
- $this->_parse_modifiers($match[1], $match[2]);
- return $match[1];
- }
- }
- elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // single quoted text
- preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- if($match[2] != '') {
- $this->_parse_modifiers($match[1], $match[2]);
- return $match[1];
- }
- }
- elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // config var
- return $this->_parse_conf_var($val);
- }
- elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // section var
- return $this->_parse_section_prop($val);
- }
- elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
- // literal string
- return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
- }
- return $val;
- }
-
- /**
- * expand quoted text with embedded variables
- *
- * @param string $var_expr
- * @return string
- */
- function _expand_quoted_text($var_expr)
- {
- // if contains unescaped $, expand it
- if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
- $_match = $_match[0];
- $_replace = array();
- foreach($_match as $_var) {
- $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
- }
- $var_expr = strtr($var_expr, $_replace);
- $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
- } else {
- $_return = $var_expr;
- }
- // replace double quoted literal string with single quotes
- $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
- // escape dollar sign if not printing a var
- $_return = preg_replace('~\$(\W)~',"\\\\\$\\1",$_return);
- return $_return;
- }
-
- /**
- * parse variable expression into PHP code
- *
- * @param string $var_expr
- * @param string $output
- * @return string
- */
- function _parse_var($var_expr)
- {
- $_has_math = false;
- $_has_php4_method_chaining = false;
- $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
-
- if(count($_math_vars) > 1) {
- $_first_var = "";
- $_complete_var = "";
- $_output = "";
- // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
- foreach($_math_vars as $_k => $_math_var) {
- $_math_var = $_math_vars[$_k];
-
- if(!empty($_math_var) || is_numeric($_math_var)) {
- // hit a math operator, so process the stuff which came before it
- if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
- $_has_math = true;
- if(!empty($_complete_var) || is_numeric($_complete_var)) {
- $_output .= $this->_parse_var($_complete_var);
- }
-
- // just output the math operator to php
- $_output .= $_math_var;
-
- if(empty($_first_var))
- $_first_var = $_complete_var;
-
- $_complete_var = "";
- } else {
- $_complete_var .= $_math_var;
- }
- }
- }
- if($_has_math) {
- if(!empty($_complete_var) || is_numeric($_complete_var))
- $_output .= $this->_parse_var($_complete_var);
-
- // get the modifiers working (only the last var from math + modifier is left)
- $var_expr = $_complete_var;
- }
- }
-
- // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
- if(is_numeric(substr($var_expr, 0, 1)))
- $_var_ref = $var_expr;
- else
- $_var_ref = substr($var_expr, 1);
-
- if(!$_has_math) {
-
- // get [foo] and .foo and ->foo and (...) pieces
- preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
-
- $_indexes = $match[0];
- $_var_name = array_shift($_indexes);
-
- /* Handle $smarty.* variable references as a special case. */
- if ($_var_name == 'smarty') {
- /*
- * If the reference could be compiled, use the compiled output;
- * otherwise, fall back on the $smarty variable generated at
- * run-time.
- */
- if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
- $_output = $smarty_ref;
- } else {
- $_var_name = substr(array_shift($_indexes), 1);
- $_output = "\$this->_smarty_vars['$_var_name']";
- }
- } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
- // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
- if(count($_indexes) > 0)
- {
- $_var_name .= implode("", $_indexes);
- $_indexes = array();
- }
- $_output = $_var_name;
- } else {
- $_output = "\$this->_tpl_vars['$_var_name']";
- }
-
- foreach ($_indexes as $_index) {
- if (substr($_index, 0, 1) == '[') {
- $_index = substr($_index, 1, -1);
- if (is_numeric($_index)) {
- $_output .= "[$_index]";
- } elseif (substr($_index, 0, 1) == '$') {
- if (strpos($_index, '.') !== false) {
- $_output .= '[' . $this->_parse_var($_index) . ']';
- } else {
- $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
- }
- } else {
- $_var_parts = explode('.', $_index);
- $_var_section = $_var_parts[0];
- $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
- $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
- }
- } else if (substr($_index, 0, 1) == '.') {
- if (substr($_index, 1, 1) == '$')
- $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
- else
- $_output .= "['" . substr($_index, 1) . "']";
- } else if (substr($_index,0,2) == '->') {
- if(substr($_index,2,2) == '__') {
- $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } elseif($this->security && substr($_index, 2, 1) == '_') {
- $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } elseif (substr($_index, 2, 1) == '$') {
- if ($this->security) {
- $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } else {
- $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
- }
- } else {
- if ($this->_phpversion < 5) {
- $_has_php4_method_chaining = true;
- $_output .= "; \$_foo = \$_foo";
- }
- $_output .= $_index;
- }
- } elseif (substr($_index, 0, 1) == '(') {
- $_index = $this->_parse_parenth_args($_index);
- $_output .= $_index;
- } else {
- $_output .= $_index;
- }
- }
- }
-
- if ($_has_php4_method_chaining) {
- $_tmp = str_replace("'","\'",'$_foo = '.$_output.'; return $_foo;');
- return "eval('".$_tmp."')";
- } else {
- return $_output;
- }
- }
-
- /**
- * parse arguments in function call parenthesis
- *
- * @param string $parenth_args
- * @return string
- */
- function _parse_parenth_args($parenth_args)
- {
- preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
- $orig_vals = $match = $match[0];
- $this->_parse_vars_props($match);
- $replace = array();
- for ($i = 0, $count = count($match); $i < $count; $i++) {
- $replace[$orig_vals[$i]] = $match[$i];
- }
- return strtr($parenth_args, $replace);
- }
-
- /**
- * parse configuration variable expression into PHP code
- *
- * @param string $conf_var_expr
- */
- function _parse_conf_var($conf_var_expr)
- {
- $parts = explode('|', $conf_var_expr, 2);
- $var_ref = $parts[0];
- $modifiers = isset($parts[1]) ? $parts[1] : '';
-
- $var_name = substr($var_ref, 1, -1);
-
- $output = "\$this->_config[0]['vars']['$var_name']";
-
- $this->_parse_modifiers($output, $modifiers);
-
- return $output;
- }
-
- /**
- * parse section property expression into PHP code
- *
- * @param string $section_prop_expr
- * @return string
- */
- function _parse_section_prop($section_prop_expr)
- {
- $parts = explode('|', $section_prop_expr, 2);
- $var_ref = $parts[0];
- $modifiers = isset($parts[1]) ? $parts[1] : '';
-
- preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
- $section_name = $match[1];
- $prop_name = $match[2];
-
- $output = "\$this->_sections['$section_name']['$prop_name']";
-
- $this->_parse_modifiers($output, $modifiers);
-
- return $output;
- }
-
-
- /**
- * parse modifier chain into PHP code
- *
- * sets $output to parsed modified chain
- * @param string $output
- * @param string $modifier_string
- */
- function _parse_modifiers(&$output, $modifier_string)
- {
- preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
- list(, $_modifiers, $modifier_arg_strings) = $_match;
-
- for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
- $_modifier_name = $_modifiers[$_i];
-
- if($_modifier_name == 'smarty') {
- // skip smarty modifier
- continue;
- }
-
- preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
- $_modifier_args = $_match[1];
-
- if (substr($_modifier_name, 0, 1) == '@') {
- $_map_array = false;
- $_modifier_name = substr($_modifier_name, 1);
- } else {
- $_map_array = true;
- }
-
- if (empty($this->_plugins['modifier'][$_modifier_name])
- && !$this->_get_plugin_filepath('modifier', $_modifier_name)
- && function_exists($_modifier_name)) {
- if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
- $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } else {
- $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false);
- }
- }
- $this->_add_plugin('modifier', $_modifier_name);
-
- $this->_parse_vars_props($_modifier_args);
-
- if($_modifier_name == 'default') {
- // supress notifications of default modifier vars and args
- if(substr($output, 0, 1) == '$') {
- $output = '@' . $output;
- }
- if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
- $_modifier_args[0] = '@' . $_modifier_args[0];
- }
- }
- if (count($_modifier_args) > 0)
- $_modifier_args = ', '.implode(', ', $_modifier_args);
- else
- $_modifier_args = '';
-
- if ($_map_array) {
- $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
-
- } else {
-
- $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
-
- }
- }
- }
-
-
- /**
- * add plugin
- *
- * @param string $type
- * @param string $name
- * @param boolean? $delayed_loading
- */
- function _add_plugin($type, $name, $delayed_loading = null)
- {
- if (!isset($this->_plugin_info[$type])) {
- $this->_plugin_info[$type] = array();
- }
- if (!isset($this->_plugin_info[$type][$name])) {
- $this->_plugin_info[$type][$name] = array($this->_current_file,
- $this->_current_line_no,
- $delayed_loading);
- }
- }
-
-
- /**
- * Compiles references of type $smarty.foo
- *
- * @param string $indexes
- * @return string
- */
- function _compile_smarty_ref(&$indexes)
- {
- /* Extract the reference name. */
- $_ref = substr($indexes[0], 1);
- foreach($indexes as $_index_no=>$_index) {
- if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
- $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
- }
- }
-
- switch ($_ref) {
- case 'now':
- $compiled_ref = 'time()';
- $_max_index = 1;
- break;
-
- case 'foreach':
- array_shift($indexes);
- $_var = $this->_parse_var_props(substr($indexes[0], 1));
- $_propname = substr($indexes[1], 1);
- $_max_index = 1;
- switch ($_propname) {
- case 'index':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
- break;
-
- case 'first':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
- break;
-
- case 'last':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
- break;
-
- case 'show':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
- break;
-
- default:
- unset($_max_index);
- $compiled_ref = "\$this->_foreach[$_var]";
- }
- break;
-
- case 'section':
- array_shift($indexes);
- $_var = $this->_parse_var_props(substr($indexes[0], 1));
- $compiled_ref = "\$this->_sections[$_var]";
- break;
-
- case 'get':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
- break;
-
- case 'post':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
- break;
-
- case 'cookies':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
- break;
-
- case 'env':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
- break;
-
- case 'server':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
- break;
-
- case 'session':
- $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
- break;
-
- /*
- * These cases are handled either at run-time or elsewhere in the
- * compiler.
- */
- case 'request':
- if ($this->request_use_auto_globals) {
- $compiled_ref = '$_REQUEST';
- break;
- } else {
- $this->_init_smarty_vars = true;
- }
- return null;
-
- case 'capture':
- return null;
-
- case 'template':
- $compiled_ref = "'$this->_current_file'";
- $_max_index = 1;
- break;
-
- case 'version':
- $compiled_ref = "'$this->_version'";
- $_max_index = 1;
- break;
-
- case 'const':
- if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
- $this->_syntax_error("(secure mode) constants not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- array_shift($indexes);
- if (preg_match('!^\.\w+$!', $indexes[0])) {
- $compiled_ref = '@' . substr($indexes[0], 1);
- } else {
- $_val = $this->_parse_var_props(substr($indexes[0], 1));
- $compiled_ref = '@constant(' . $_val . ')';
- }
- $_max_index = 1;
- break;
-
- case 'config':
- $compiled_ref = "\$this->_config[0]['vars']";
- $_max_index = 3;
- break;
-
- case 'ldelim':
- $compiled_ref = "'$this->left_delimiter'";
- break;
-
- case 'rdelim':
- $compiled_ref = "'$this->right_delimiter'";
- break;
-
- default:
- $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
-
- if (isset($_max_index) && count($indexes) > $_max_index) {
- $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
- }
-
- array_shift($indexes);
- return $compiled_ref;
- }
-
- /**
- * compiles call to plugin of type $type with name $name
- * returns a string containing the function-name or method call
- * without the paramter-list that would have follow to make the
- * call valid php-syntax
- *
- * @param string $type
- * @param string $name
- * @return string
- */
- function _compile_plugin_call($type, $name) {
- if (isset($this->_plugins[$type][$name])) {
- /* plugin loaded */
- if (is_array($this->_plugins[$type][$name][0])) {
- return ((is_object($this->_plugins[$type][$name][0][0])) ?
- "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */
- : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */
- ). $this->_plugins[$type][$name][0][1];
-
- } else {
- /* function callback */
- return $this->_plugins[$type][$name][0];
-
- }
- } else {
- /* plugin not loaded -> auto-loadable-plugin */
- return 'smarty_'.$type.'_'.$name;
-
- }
- }
-
- /**
- * load pre- and post-filters
- */
- function _load_filters()
- {
- if (count($this->_plugins['prefilter']) > 0) {
- foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
- if ($prefilter === false) {
- unset($this->_plugins['prefilter'][$filter_name]);
- $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- }
- }
- }
- if (count($this->_plugins['postfilter']) > 0) {
- foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
- if ($postfilter === false) {
- unset($this->_plugins['postfilter'][$filter_name]);
- $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- }
- }
- }
- }
-
-
- /**
- * Quote subpattern references
- *
- * @param string $string
- * @return string
- */
- function _quote_replace($string)
- {
- return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
- }
-
- /**
- * display Smarty syntax error
- *
- * @param string $error_msg
- * @param integer $error_type
- * @param string $file
- * @param integer $line
- */
- function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
- {
- $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
- }
-
-
- /**
- * check if the compilation changes from cacheable to
- * non-cacheable state with the beginning of the current
- * plugin. return php-code to reflect the transition.
- * @return string
- */
- function _push_cacheable_state($type, $name) {
- $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
- if ($_cacheable
- || 0<$this->_cacheable_state++) return '';
- if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
- $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
- . $this->_cache_serial . '#' . $this->_nocache_count
- . '}\'; endif;';
- return $_ret;
- }
-
-
- /**
- * check if the compilation changes from non-cacheable to
- * cacheable state with the end of the current plugin return
- * php-code to reflect the transition.
- * @return string
- */
- function _pop_cacheable_state($type, $name) {
- $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
- if ($_cacheable
- || --$this->_cacheable_state>0) return '';
- return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
- . $this->_cache_serial . '#' . ($this->_nocache_count++)
- . '}\'; endif;';
- }
-
-
- /**
- * push opening tag-name, file-name and line-number on the tag-stack
- * @param string the opening tag's name
- */
- function _push_tag($open_tag)
- {
- array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
- }
-
- /**
- * pop closing tag-name
- * raise an error if this stack-top doesn't match with the closing tag
- * @param string the closing tag's name
- * @return string the opening tag's name
- */
- function _pop_tag($close_tag)
- {
- $message = '';
- if (count($this->_tag_stack)>0) {
- list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
- if ($close_tag == $_open_tag) {
- return $_open_tag;
- }
- if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
- return $this->_pop_tag($close_tag);
- }
- if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
- $this->_pop_tag($close_tag);
- return $_open_tag;
- }
- if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
- $this->_pop_tag($close_tag);
- return $_open_tag;
- }
- if ($_open_tag == 'else' || $_open_tag == 'elseif') {
- $_open_tag = 'if';
- } elseif ($_open_tag == 'sectionelse') {
- $_open_tag = 'section';
- } elseif ($_open_tag == 'foreachelse') {
- $_open_tag = 'foreach';
- }
- $message = " expected {/$_open_tag} (opened line $_line_no).";
- }
- $this->_syntax_error("mismatched tag {/$close_tag}.$message",
- E_USER_ERROR, __FILE__, __LINE__);
- }
-
-}
-
-/**
- * compare to values by their string length
- *
- * @access private
- * @param string $a
- * @param string $b
- * @return 0|-1|1
- */
-function _smarty_sort_length($a, $b)
-{
- if($a == $b)
- return 0;
-
- if(strlen($a) == strlen($b))
- return ($a > $b) ? -1 : 1;
-
- return (strlen($a) > strlen($b)) ? -1 : 1;
-}
-
-
-/* vim: set et: */
-
-?>
+<?php + +/** + * Project: Smarty: the PHP compiling template engine + * File: Smarty_Compiler.class.php + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @link http://www.smarty.net/ + * @author Monte Ohrt <monte at ohrt dot com> + * @author Andrei Zmievski <andrei@php.net> + * @version 2.6.22 + * @copyright 2001-2005 New Digital Group, Inc. + * @package Smarty + */ + +/* $Id$ */ + +/** + * Template compiling class + * @package Smarty + */ +class Smarty_Compiler extends Smarty { + + // internal vars + /**#@+ + * @access private + */ + var $_folded_blocks = array(); // keeps folded template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_capture_stack = array(); // keeps track of nested capture buffers + var $_plugin_info = array(); // keeps track of plugins to load + var $_init_smarty_vars = false; + var $_permitted_tokens = array('true','false','yes','no','on','off','null'); + var $_db_qstr_regexp = null; // regexps are setup in the constructor + var $_si_qstr_regexp = null; + var $_qstr_regexp = null; + var $_func_regexp = null; + var $_reg_obj_regexp = null; + var $_var_bracket_regexp = null; + var $_num_const_regexp = null; + var $_dvar_guts_regexp = null; + var $_dvar_regexp = null; + var $_cvar_regexp = null; + var $_svar_regexp = null; + var $_avar_regexp = null; + var $_mod_regexp = null; + var $_var_regexp = null; + var $_parenth_param_regexp = null; + var $_func_call_regexp = null; + var $_obj_ext_regexp = null; + var $_obj_start_regexp = null; + var $_obj_params_regexp = null; + var $_obj_call_regexp = null; + var $_cacheable_state = 0; + var $_cache_attrs_count = 0; + var $_nocache_count = 0; + var $_cache_serial = null; + var $_cache_include = null; + + var $_strip_depth = 0; + var $_additional_newline = "\n"; + + var $_phpversion = 0; + + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty_Compiler() + { + $this->_phpversion = substr(phpversion(),0,1); + + // matches double quoted strings: + // "foobar" + // "foo\"bar" + $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; + + // matches single quoted strings: + // 'foobar' + // 'foo\'bar' + $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + // matches single or double quoted strings + $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; + + // matches bracket portion of vars + // [0] + // [foo] + // [$bar] + $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; + + // matches numerical constants + // 30 + // -12 + // 13.22 + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; + + // matches $ vars (not objects): + // $foo + // $foo.bar + // $foo.bar.foobar + // $foo[0] + // $foo[$bar] + // $foo[5][blah] + // $foo[5].bar[$foobar][4] + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; + $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; + $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; + $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; + + // matches config vars: + // #foo# + // #foobar123_foo# + $this->_cvar_regexp = '\#\w+\#'; + + // matches section vars: + // %foo.bar% + $this->_svar_regexp = '\%\w+\.\w+\%'; + + // matches all valid variables (no quotes, no modifiers) + $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' + . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; + + // matches valid variable syntax: + // $foo + // $foo + // #foo# + // #foo# + // "text" + // "text" + $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; + + // matches valid object call (one level of object nesting allowed in parameters): + // $foo->bar + // $foo->bar() + // $foo->bar("text") + // $foo->bar($foo, $bar, "text") + // $foo->bar($foo, "foo") + // $foo->bar->foo() + // $foo->bar->foo->bar() + // $foo->bar($foo->bar) + // $foo->bar($foo->bar()) + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) + // $foo->getBar()->getFoo() + // $foo->getBar()->foo + $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; + $this->_obj_restricted_param_regexp = '(?:' + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; + + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; + + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; + $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; + + // matches valid modifier syntax: + // |foo + // |@foo + // |foo:"bar" + // |foo:$bar + // |foo:"bar":$foobar + // |foo|bar + // |foo:$foo->bar + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' + . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; + + // matches valid function name: + // foo123 + // _foo_bar + $this->_func_regexp = '[a-zA-Z_]\w*'; + + // matches valid registered object: + // foo->bar + $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; + + // matches valid parameter values: + // true + // $foo + // $foo|bar + // #foo# + // #foo#|bar + // "text" + // "text"|bar + // $foo->bar + $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; + + // matches valid parenthesised function parameters: + // + // "text" + // $foo, $bar, "text" + // $foo|bar, "foo"|bar, $foo->bar($foo)|bar + $this->_parenth_param_regexp = '(?:\((?:\w+|' + . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_param_regexp . ')))*)?\))'; + + // matches valid function call: + // foo() + // foo_bar($foo) + // _foo_bar($foo,"bar") + // foo123($foo,$foo->bar(),"foo") + $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' + . $this->_parenth_param_regexp . '))'; + } + + /** + * compile a resource + * + * sets $compiled_content to the compiled source + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return true + */ + function _compile_file($resource_name, $source_content, &$compiled_content) + { + + if ($this->security) { + // do not allow php syntax to be executed unless specified + if ($this->php_handling == SMARTY_PHP_ALLOW && + !$this->security_settings['PHP_HANDLING']) { + $this->php_handling = SMARTY_PHP_PASSTHRU; + } + } + + $this->_load_filters(); + + $this->_current_file = $resource_name; + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '~'); + $rdq = preg_quote($this->right_delimiter, '~'); + + // run template source through prefilter functions + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) continue; + if ($prefilter[3] || is_callable($prefilter[0])) { + $source_content = call_user_func_array($prefilter[0], + array($source_content, &$this)); + $this->_plugins['prefilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); + } + } + } + + /* fetch all special blocks */ + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; + + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); + $this->_folded_blocks = $match; + reset($this->_folded_blocks); + + /* replace special blocks by "{php}" */ + $source_content = preg_replace($search.'e', "'" + . $this->_quote_replace($this->left_delimiter) . 'php' + . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" + . $this->_quote_replace($this->right_delimiter) + . "'" + , $source_content); + + /* Gather all template tags. */ + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); + $template_tags = $_match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); + + /* loop through text blocks */ + for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { + /* match anything resembling php tags */ + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { + /* replace tags with placeholders to prevent recursive replacements */ + $sp_match[1] = array_unique($sp_match[1]); + usort($sp_match[1], '_smarty_sort_length'); + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); + } + /* process each one */ + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + if ($this->php_handling == SMARTY_PHP_PASSTHRU) { + /* echo php contents */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_QUOTE) { + /* quote php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_REMOVE) { + /* remove php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); + } else { + /* SMARTY_PHP_ALLOW, but echo non php starting tags */ + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]); + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); + } + } + } + } + + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = end($this->_tag_stack); + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); + return; + } + + /* Reformat $text_blocks between 'strip' and '/strip' tags, + removing spaces, tabs and newlines. */ + $strip = false; + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '{strip}') { + $compiled_tags[$i] = ''; + $strip = true; + /* remove leading whitespaces */ + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); + } + if ($strip) { + /* strip all $text_blocks before the next '/strip' */ + for ($j = $i + 1; $j < $for_max; $j++) { + /* remove leading and trailing whitespaces of each line */ + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); + if ($compiled_tags[$j] == '{/strip}') { + /* remove trailing whitespaces from the last text_block */ + $text_blocks[$j] = rtrim($text_blocks[$j]); + } + $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>"; + if ($compiled_tags[$j] == '{/strip}') { + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary + if a newline is following the closing strip-tag */ + $strip = false; + $i = $j; + break; + } + } + } + } + $compiled_content = ''; + + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '') { + // tag result empty, remove first newline from following text block + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); + } + // replace legit PHP tags with placeholder + $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]); + $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]); + + $compiled_content .= $text_blocks[$i] . $compiled_tags[$i]; + } + $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]); + + // escape php tags created by interleaving + $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content); + $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content); + + // recover legit tags + $compiled_content = str_replace($tag_guard, '<?', $compiled_content); + + // remove \n from the end of the file, if any + if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) { + $compiled_content = substr($compiled_content, 0, -1); + } + + if (!empty($this->_cache_serial)) { + $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; + } + + // run compiled template through postfilter functions + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) continue; + if ($postfilter[3] || is_callable($postfilter[0])) { + $compiled_content = call_user_func_array($postfilter[0], + array($compiled_content, &$this)); + $this->_plugins['postfilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); + } + } + } + + // put header at the top of the compiled template + $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; + + /* Emit code to load needed plugins. */ + $this->_plugins_code = ''; + if (count($this->_plugin_info)) { + $_plugins_params = "array('plugins' => array("; + foreach ($this->_plugin_info as $plugin_type => $plugins) { + foreach ($plugins as $plugin_name => $plugin_info) { + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; + $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; + } + } + $_plugins_params .= '))'; + $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n"; + $template_header .= $plugins_code; + $this->_plugin_info = array(); + $this->_plugins_code = $plugins_code; + } + + if ($this->_init_smarty_vars) { + $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n"; + $this->_init_smarty_vars = false; + } + + $compiled_content = $template_header . $compiled_content; + return true; + } + + /** + * Compile a template tag + * + * @param string $template_tag + * @return string + */ + function _compile_tag($template_tag) + { + /* Matched comment. */ + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') + return ''; + + /* Split tag into two three parts: command, command modifiers and the arguments. */ + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp + . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) + (?:\s+(.*))?$ + ~xs', $template_tag, $match)) { + $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $tag_command = $match[1]; + $tag_modifier = isset($match[2]) ? $match[2] : null; + $tag_args = isset($match[3]) ? $match[3] : null; + + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { + /* tag name is a variable or object */ + $_return = $this->_parse_var_props($tag_command . $tag_modifier); + return "<?php echo $_return; ?>" . $this->_additional_newline; + } + + /* If the tag name is a registered object, we process it. */ + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { + return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'include_php': + return $this->_compile_include_php_tag($tag_args); + + case 'if': + $this->_push_tag('if'); + return $this->_compile_if_tag($tag_args); + + case 'else': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); + else + $this->_push_tag('else'); + return '<?php else: ?>'; + + case 'elseif': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); + if ($_open_tag == 'if') + $this->_push_tag('elseif'); + return $this->_compile_if_tag($tag_args, true); + + case '/if': + $this->_pop_tag('if'); + return '<?php endif; ?>'; + + case 'capture': + return $this->_compile_capture_tag(true, $tag_args); + + case '/capture': + return $this->_compile_capture_tag(false); + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + $this->_push_tag('section'); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_push_tag('sectionelse'); + return "<?php endfor; else: ?>"; + break; + + case '/section': + $_open_tag = $this->_pop_tag('section'); + if ($_open_tag == 'sectionelse') + return "<?php endif; ?>"; + else + return "<?php endfor; endif; ?>"; + + case 'foreach': + $this->_push_tag('foreach'); + return $this->_compile_foreach_start($tag_args); + break; + + case 'foreachelse': + $this->_push_tag('foreachelse'); + return "<?php endforeach; else: ?>"; + + case '/foreach': + $_open_tag = $this->_pop_tag('foreach'); + if ($_open_tag == 'foreachelse') + return "<?php endif; unset(\$_from); ?>"; + else + return "<?php endforeach; endif; unset(\$_from); ?>"; + break; + + case 'strip': + case '/strip': + if (substr($tag_command, 0, 1)=='/') { + $this->_pop_tag('strip'); + if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ + $this->_additional_newline = "\n"; + return '{' . $tag_command . '}'; + } + } else { + $this->_push_tag('strip'); + if ($this->_strip_depth++==0) { /* outermost opening {strip} */ + $this->_additional_newline = ""; + return '{' . $tag_command . '}'; + } + } + return ''; + + case 'php': + /* handle folded tags replaced by {php} */ + list(, $block) = each($this->_folded_blocks); + $this->_current_line_no += substr_count($block[0], "\n"); + /* the number of matched elements in the regexp in _compile_file() + determins the type of folded tag that was found */ + switch (count($block)) { + case 2: /* comment */ + return ''; + + case 3: /* literal */ + return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; + + case 4: /* php */ + if ($this->security && !$this->security_settings['PHP_TAGS']) { + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); + return; + } + return '<?php ' . $block[3] .' ?>'; + } + break; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { + return $output; + } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else { + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); + } + + } + } + + + /** + * compile the custom compiler tag + * + * sets $output to the compiled custom compiler tag + * @param string $tag_command + * @param string $tag_args + * @param string $output + * @return boolean + */ + function _compile_compiler_tag($tag_command, $tag_args, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the compiler function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['compiler'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['compiler'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "compiler function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_compiler_' . $tag_command; + if (!is_callable($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); + } + } + + /* + * True return value means that we either found a plugin or a + * dynamically registered function. False means that we didn't and the + * compiler should now emit code to load custom function plugin for this + * tag. + */ + if ($found) { + if ($have_function) { + $output = call_user_func_array($plugin_func, array($tag_args, &$this)); + if($output != '') { + $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command) + . $output + . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; + } + } else { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + } + return true; + } else { + return false; + } + } + + + /** + * compile block function tag + * + * sets $output to compiled block function tag + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @param string $output + * @return boolean + */ + function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else + $start_tag = true; + + $found = false; + $have_function = true; + + /* + * First we check if the block function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['block'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['block'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "block function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_block_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* + * Even though we've located the plugin function, compilation + * happens only once, so the plugin will still need to be loaded + * at runtime for future requests. + */ + $this->_add_plugin('block', $tag_command); + + if ($start_tag) + $this->_push_tag($tag_command); + else + $this->_pop_tag($tag_command); + + if ($start_tag) { + $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs=''; + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; + $output .= 'while ($_block_repeat) { ob_start(); ?>'; + } else { + $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); '; + $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; + if ($tag_modifier != '') { + $this->_parse_modifiers($_out_tag_text, $tag_modifier); + } + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; + $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; + } + + return true; + } + + + /** + * compile custom function tag + * + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @return string + */ + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the custom function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['function'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['function'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "custom function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_function_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* declare plugin to be loaded on display of the template that + we compile right now */ + $this->_add_plugin('function', $tag_command); + + $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs = ''; + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); + + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; + if($tag_modifier != '') { + $this->_parse_modifiers($output, $tag_modifier); + } + + if($output != '') { + $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';' + . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; + } + + return true; + } + + /** + * compile a registered object tag + * + * @param string $tag_command + * @param array $attrs + * @param string $tag_modifier + * @return string + */ + function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else { + $start_tag = true; + } + + list($object, $obj_comp) = explode('->', $tag_command); + + $arg_list = array(); + if(count($attrs)) { + $_assign_var = false; + foreach ($attrs as $arg_name => $arg_value) { + if($arg_name == 'assign') { + $_assign_var = $arg_value; + unset($attrs['assign']); + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + if($this->_reg_objects[$object][2]) { + // smarty object argument format + $args = "array(".implode(',', (array)$arg_list)."), \$this"; + } else { + // traditional argument format + $args = implode(',', array_values($attrs)); + if (empty($args)) { + $args = ''; + } + } + + $prefix = ''; + $postfix = ''; + $newline = ''; + if(!is_object($this->_reg_objects[$object][0])) { + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { + // method + if(in_array($obj_comp, $this->_reg_objects[$object][3])) { + // block method + if ($start_tag) { + $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; + $prefix .= "while (\$_block_repeat) { ob_start();"; + $return = null; + $postfix = ''; + } else { + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; + $postfix = "} array_pop(\$this->_tag_stack);"; + } + } else { + // non-block method + $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; + } + } else { + // property + $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; + } + + if($return != null) { + if($tag_modifier != '') { + $this->_parse_modifiers($return, $tag_modifier); + } + + if(!empty($_assign_var)) { + $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; + } else { + $output = 'echo ' . $return . ';'; + $newline = $this->_additional_newline; + } + } else { + $output = ''; + } + + return '<?php ' . $prefix . $output . $postfix . "?>" . $newline; + } + + /** + * Compile {insert ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!preg_match('~^\w+$~', $name)) { + return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!empty($attrs['script'])) { + $delayed_loading = true; + } else { + $delayed_loading = false; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $this->_add_plugin('insert', $name, $delayed_loading); + + $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; + + return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline; + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); + } + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') { + $include_file = $arg_value; + continue; + } else if ($arg_name == 'assign') { + $assign_var = $arg_value; + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $output = '<?php '; + + if (isset($assign_var)) { + $output .= "ob_start();\n"; + } + + $output .= + "\$_smarty_tpl_vars = \$this->_tpl_vars;\n"; + + + $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; + $output .= "\$this->_smarty_include($_params);\n" . + "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . + "unset(\$_smarty_tpl_vars);\n"; + + if (isset($assign_var)) { + $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; + } + + $output .= ' ?>'; + + return $output; + + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_php_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); + $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; + + $arg_list = array(); + foreach($attrs as $arg_name => $arg_value) { + if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { + if(is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; + + return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline; + } + + + /** + * Compile {section ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + $output = '<?php '; + $section_name = $attrs['name']; + if (empty($section_name)) { + $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); + } + + $output .= "unset(\$this->_sections[$section_name]);\n"; + $section_props = "\$this->_sections[$section_name]"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $show_attr_value = $attr_value ? 'true' : 'false'; + else + $show_attr_value = "(bool)$attr_value"; + $output .= "{$section_props}['show'] = $show_attr_value;\n"; + break; + + case 'name': + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + case 'max': + case 'start': + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; + break; + + case 'step': + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; + break; + + default: + $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + } + + if (!isset($attrs['show'])) + $output .= "{$section_props}['show'] = true;\n"; + + if (!isset($attrs['loop'])) + $output .= "{$section_props}['loop'] = 1;\n"; + + if (!isset($attrs['max'])) + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; + else + $output .= "if ({$section_props}['max'] < 0)\n" . + " {$section_props}['max'] = {$section_props}['loop'];\n"; + + if (!isset($attrs['step'])) + $output .= "{$section_props}['step'] = 1;\n"; + + if (!isset($attrs['start'])) + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; + else { + $output .= "if ({$section_props}['start'] < 0)\n" . + " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . + "else\n" . + " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; + } + + $output .= "if ({$section_props}['show']) {\n"; + if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; + } else { + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; + } + $output .= " if ({$section_props}['total'] == 0)\n" . + " {$section_props}['show'] = false;\n" . + "} else\n" . + " {$section_props}['total'] = 0;\n"; + + $output .= "if ({$section_props}['show']):\n"; + $output .= " + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; + {$section_props}['iteration'] <= {$section_props}['total']; + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; + + $output .= "?>"; + + return $output; + } + + + /** + * Compile {foreach ...} tag. + * + * @param string $tag_args + * @return string + */ + function _compile_foreach_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['from'])) { + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $from = $attrs['from']; + + if (empty($attrs['item'])) { + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $item = $this->_dequote($attrs['item']); + if (!preg_match('~^\w+$~', $item)) { + return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($attrs['key'])) { + $key = $this->_dequote($attrs['key']); + if (!preg_match('~^\w+$~', $key)) { + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + $key_part = "\$this->_tpl_vars['$key'] => "; + } else { + $key = null; + $key_part = ''; + } + + if (isset($attrs['name'])) { + $name = $attrs['name']; + } else { + $name = null; + } + + $output = '<?php '; + $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }"; + if (isset($name)) { + $foreach_props = "\$this->_foreach[$name]"; + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; + $output .= "if ({$foreach_props}['total'] > 0):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + $output .= " {$foreach_props}['iteration']++;\n"; + } else { + $output .= "if (count(\$_from)):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + } + $output .= '?>'; + + return $output; + } + + + /** + * Compile {capture} .. {/capture} tags + * + * @param boolean $start true if this is the {capture} tag + * @param string $tag_args + * @return string + */ + + function _compile_capture_tag($start, $tag_args = '') + { + $attrs = $this->_parse_attrs($tag_args); + + if ($start) { + $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; + $assign = isset($attrs['assign']) ? $attrs['assign'] : null; + $append = isset($attrs['append']) ? $attrs['append'] : null; + + $output = "<?php ob_start(); ?>"; + $this->_capture_stack[] = array($buffer, $assign, $append); + } else { + list($buffer, $assign, $append) = array_pop($this->_capture_stack); + $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; + if (isset($assign)) { + $output .= " \$this->assign($assign, ob_get_contents());"; + } + if (isset($append)) { + $output .= " \$this->append($append, ob_get_contents());"; + } + $output .= "ob_end_clean(); ?>"; + } + + return $output; + } + + /** + * Compile {if ...} tag + * + * @param string $tag_args + * @param boolean $elseif if true, uses elseif instead of if + * @return string + */ + function _compile_if_tag($tag_args, $elseif = false) + { + + /* Tokenize args for 'if' tag. */ + preg_match_all('~(?> + ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call + ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string + \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token + \b\w+\b | # valid word token + \S+ # anything else + )~x', $tag_args, $match); + + $tokens = $match[0]; + + if(empty($tokens)) { + $_error_msg = $elseif ? "'elseif'" : "'if'"; + $_error_msg .= ' statement requires arguments'; + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); + } + + + // make sure we have balanced parenthesis + $token_count = array_count_values($tokens); + if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { + $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + + $token = &$tokens[$i]; + + switch (strtolower($token)) { + case '!': + case '%': + case '!==': + case '==': + case '===': + case '>': + case '<': + case '!=': + case '<>': + case '<<': + case '>>': + case '<=': + case '>=': + case '&&': + case '||': + case '|': + case '^': + case '&': + case '~': + case ')': + case ',': + case '+': + case '-': + case '*': + case '/': + case '@': + break; + + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') { + $is_arg_start = array_pop($is_arg_stack); + if ($is_arg_start != 0) { + if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { + $is_arg_start--; + } + } + } else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + + default: + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { + // function call + if($this->security && + !in_array($token, $this->security_settings['IF_FUNCS'])) { + $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { + // variable function call + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { + // object or variable + $token = $this->_parse_var_props($token); + } elseif(is_numeric($token)) { + // number, skip it + } else { + $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + } + } + + if ($elseif) + return '<?php elseif ('.implode(' ', $tokens).'): ?>'; + else + return '<?php if ('.implode(' ', $tokens).'): ?>'; + } + + + function _compile_arg_list($type, $name, $attrs, &$cache_code) { + $arg_list = array(); + + if (isset($type) && isset($name) + && isset($this->_plugins[$type]) + && isset($this->_plugins[$type][$name]) + && empty($this->_plugins[$type][$name][4]) + && is_array($this->_plugins[$type][$name][5]) + ) { + /* we have a list of parameters that should be cached */ + $_cache_attrs = $this->_plugins[$type][$name][5]; + $_count = $this->_cache_attrs_count++; + $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; + + } else { + /* no parameters are cached */ + $_cache_attrs = null; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + if (is_null($arg_value)) + $arg_value = 'null'; + if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { + $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; + } else { + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + return $arg_list; + } + + /** + * Parse is expression + * + * @param string $is_arg + * @param array $tokens + * @return array + */ + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + $negate_expr = false; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "!(1 & $is_arg)"; + break; + + case 'odd': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "(1 & $is_arg)"; + break; + + case 'div': + if (@$tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; + } else { + $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + + /** + * Parse attribute string + * + * @param string $tag_args + * @return array + */ + function _parse_attrs($tag_args) + { + + /* Tokenize tag attributes. */ + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) + )+ | + [=] + ~x', $tag_args, $match); + $tokens = $match[0]; + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('~^\w+$~', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('~^(on|yes|true)$~', $token)) { + $token = 'true'; + } else if (preg_match('~^(off|no|false)$~', $token)) { + $token = 'false'; + } else if ($token == 'null') { + $token = 'null'; + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { + /* treat integer literally */ + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { + /* treat as a string, double-quote it escaping quotes */ + $token = '"'.addslashes($token).'"'; + } + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); + break; + } + $last_token = $token; + } + + if($state != 0) { + if($state == 1) { + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + } else { + $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + /** + * compile multiple variables and section properties tokens into + * PHP code + * + * @param array $tokens + */ + function _parse_vars_props(&$tokens) + { + foreach($tokens as $key => $val) { + $tokens[$key] = $this->_parse_var_props($val); + } + } + + /** + * compile single variable and section properties token into + * PHP code + * + * @param string $val + * @param string $tag_attrs + * @return string + */ + function _parse_var_props($val) + { + $val = trim($val); + + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { + // $ variable or object + $return = $this->_parse_var($match[1]); + $modifiers = $match[2]; + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { + $_default_mod_string = implode('|',(array)$this->default_modifiers); + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; + } + $this->_parse_modifiers($return, $modifiers); + return $return; + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // double quoted text + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + $return = $this->_expand_quoted_text($match[1]); + if($match[2] != '') { + $this->_parse_modifiers($return, $match[2]); + } + return $return; + } + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // numerical constant + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // single quoted text + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // config var + return $this->_parse_conf_var($val); + } + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // section var + return $this->_parse_section_prop($val); + } + elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { + // literal string + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); + } + return $val; + } + + /** + * expand quoted text with embedded variables + * + * @param string $var_expr + * @return string + */ + function _expand_quoted_text($var_expr) + { + // if contains unescaped $, expand it + if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) { + $_match = $_match[0]; + $_replace = array(); + foreach($_match as $_var) { + $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."'; + } + $var_expr = strtr($var_expr, $_replace); + $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr); + } else { + $_return = $var_expr; + } + // replace double quoted literal string with single quotes + $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return); + // escape dollar sign if not printing a var + $_return = preg_replace('~\$(\W)~',"\\\\\$\\1",$_return); + return $_return; + } + + /** + * parse variable expression into PHP code + * + * @param string $var_expr + * @param string $output + * @return string + */ + function _parse_var($var_expr) + { + $_has_math = false; + $_has_php4_method_chaining = false; + $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); + + if(count($_math_vars) > 1) { + $_first_var = ""; + $_complete_var = ""; + $_output = ""; + // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) + foreach($_math_vars as $_k => $_math_var) { + $_math_var = $_math_vars[$_k]; + + if(!empty($_math_var) || is_numeric($_math_var)) { + // hit a math operator, so process the stuff which came before it + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { + $_has_math = true; + if(!empty($_complete_var) || is_numeric($_complete_var)) { + $_output .= $this->_parse_var($_complete_var); + } + + // just output the math operator to php + $_output .= $_math_var; + + if(empty($_first_var)) + $_first_var = $_complete_var; + + $_complete_var = ""; + } else { + $_complete_var .= $_math_var; + } + } + } + if($_has_math) { + if(!empty($_complete_var) || is_numeric($_complete_var)) + $_output .= $this->_parse_var($_complete_var); + + // get the modifiers working (only the last var from math + modifier is left) + $var_expr = $_complete_var; + } + } + + // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) + if(is_numeric(substr($var_expr, 0, 1))) + $_var_ref = $var_expr; + else + $_var_ref = substr($var_expr, 1); + + if(!$_has_math) { + + // get [foo] and .foo and ->foo and (...) pieces + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); + + $_indexes = $match[0]; + $_var_name = array_shift($_indexes); + + /* Handle $smarty.* variable references as a special case. */ + if ($_var_name == 'smarty') { + /* + * If the reference could be compiled, use the compiled output; + * otherwise, fall back on the $smarty variable generated at + * run-time. + */ + if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { + $_output = $smarty_ref; + } else { + $_var_name = substr(array_shift($_indexes), 1); + $_output = "\$this->_smarty_vars['$_var_name']"; + } + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { + // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers + if(count($_indexes) > 0) + { + $_var_name .= implode("", $_indexes); + $_indexes = array(); + } + $_output = $_var_name; + } else { + $_output = "\$this->_tpl_vars['$_var_name']"; + } + + foreach ($_indexes as $_index) { + if (substr($_index, 0, 1) == '[') { + $_index = substr($_index, 1, -1); + if (is_numeric($_index)) { + $_output .= "[$_index]"; + } elseif (substr($_index, 0, 1) == '$') { + if (strpos($_index, '.') !== false) { + $_output .= '[' . $this->_parse_var($_index) . ']'; + } else { + $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; + } + } else { + $_var_parts = explode('.', $_index); + $_var_section = $_var_parts[0]; + $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; + $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; + } + } else if (substr($_index, 0, 1) == '.') { + if (substr($_index, 1, 1) == '$') + $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; + else + $_output .= "['" . substr($_index, 1) . "']"; + } else if (substr($_index,0,2) == '->') { + if(substr($_index,2,2) == '__') { + $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif($this->security && substr($_index, 2, 1) == '_') { + $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif (substr($_index, 2, 1) == '$') { + if ($this->security) { + $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } else { + $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; + } + } else { + if ($this->_phpversion < 5) { + $_has_php4_method_chaining = true; + $_output .= "; \$_foo = \$_foo"; + } + $_output .= $_index; + } + } elseif (substr($_index, 0, 1) == '(') { + $_index = $this->_parse_parenth_args($_index); + $_output .= $_index; + } else { + $_output .= $_index; + } + } + } + + if ($_has_php4_method_chaining) { + $_tmp = str_replace("'","\'",'$_foo = '.$_output.'; return $_foo;'); + return "eval('".$_tmp."')"; + } else { + return $_output; + } + } + + /** + * parse arguments in function call parenthesis + * + * @param string $parenth_args + * @return string + */ + function _parse_parenth_args($parenth_args) + { + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); + $orig_vals = $match = $match[0]; + $this->_parse_vars_props($match); + $replace = array(); + for ($i = 0, $count = count($match); $i < $count; $i++) { + $replace[$orig_vals[$i]] = $match[$i]; + } + return strtr($parenth_args, $replace); + } + + /** + * parse configuration variable expression into PHP code + * + * @param string $conf_var_expr + */ + function _parse_conf_var($conf_var_expr) + { + $parts = explode('|', $conf_var_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + $var_name = substr($var_ref, 1, -1); + + $output = "\$this->_config[0]['vars']['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + /** + * parse section property expression into PHP code + * + * @param string $section_prop_expr + * @return string + */ + function _parse_section_prop($section_prop_expr) + { + $parts = explode('|', $section_prop_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$this->_sections['$section_name']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + + /** + * parse modifier chain into PHP code + * + * sets $output to parsed modified chain + * @param string $output + * @param string $modifier_string + */ + function _parse_modifiers(&$output, $modifier_string) + { + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); + list(, $_modifiers, $modifier_arg_strings) = $_match; + + for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { + $_modifier_name = $_modifiers[$_i]; + + if($_modifier_name == 'smarty') { + // skip smarty modifier + continue; + } + + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); + $_modifier_args = $_match[1]; + + if (substr($_modifier_name, 0, 1) == '@') { + $_map_array = false; + $_modifier_name = substr($_modifier_name, 1); + } else { + $_map_array = true; + } + + if (empty($this->_plugins['modifier'][$_modifier_name]) + && !$this->_get_plugin_filepath('modifier', $_modifier_name) + && function_exists($_modifier_name)) { + if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } else { + $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); + } + } + $this->_add_plugin('modifier', $_modifier_name); + + $this->_parse_vars_props($_modifier_args); + + if($_modifier_name == 'default') { + // supress notifications of default modifier vars and args + if(substr($output, 0, 1) == '$') { + $output = '@' . $output; + } + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { + $_modifier_args[0] = '@' . $_modifier_args[0]; + } + } + if (count($_modifier_args) > 0) + $_modifier_args = ', '.implode(', ', $_modifier_args); + else + $_modifier_args = ''; + + if ($_map_array) { + $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; + + } else { + + $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; + + } + } + } + + + /** + * add plugin + * + * @param string $type + * @param string $name + * @param boolean? $delayed_loading + */ + function _add_plugin($type, $name, $delayed_loading = null) + { + if (!isset($this->_plugin_info[$type])) { + $this->_plugin_info[$type] = array(); + } + if (!isset($this->_plugin_info[$type][$name])) { + $this->_plugin_info[$type][$name] = array($this->_current_file, + $this->_current_line_no, + $delayed_loading); + } + } + + + /** + * Compiles references of type $smarty.foo + * + * @param string $indexes + * @return string + */ + function _compile_smarty_ref(&$indexes) + { + /* Extract the reference name. */ + $_ref = substr($indexes[0], 1); + foreach($indexes as $_index_no=>$_index) { + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { + $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + } + + switch ($_ref) { + case 'now': + $compiled_ref = 'time()'; + $_max_index = 1; + break; + + case 'foreach': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $_propname = substr($indexes[1], 1); + $_max_index = 1; + switch ($_propname) { + case 'index': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; + break; + + case 'first': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; + break; + + case 'last': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; + break; + + case 'show': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; + break; + + default: + unset($_max_index); + $compiled_ref = "\$this->_foreach[$_var]"; + } + break; + + case 'section': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = "\$this->_sections[$_var]"; + break; + + case 'get': + $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']"; + break; + + case 'post': + $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']"; + break; + + case 'cookies': + $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']"; + break; + + case 'env': + $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']"; + break; + + case 'server': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']"; + break; + + case 'session': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']"; + break; + + /* + * These cases are handled either at run-time or elsewhere in the + * compiler. + */ + case 'request': + if ($this->request_use_auto_globals) { + $compiled_ref = '$_REQUEST'; + break; + } else { + $this->_init_smarty_vars = true; + } + return null; + + case 'capture': + return null; + + case 'template': + $compiled_ref = "'$this->_current_file'"; + $_max_index = 1; + break; + + case 'version': + $compiled_ref = "'$this->_version'"; + $_max_index = 1; + break; + + case 'const': + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { + $this->_syntax_error("(secure mode) constants not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + array_shift($indexes); + if (preg_match('!^\.\w+$!', $indexes[0])) { + $compiled_ref = '@' . substr($indexes[0], 1); + } else { + $_val = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = '@constant(' . $_val . ')'; + } + $_max_index = 1; + break; + + case 'config': + $compiled_ref = "\$this->_config[0]['vars']"; + $_max_index = 3; + break; + + case 'ldelim': + $compiled_ref = "'$this->left_delimiter'"; + break; + + case 'rdelim': + $compiled_ref = "'$this->right_delimiter'"; + break; + + default: + $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if (isset($_max_index) && count($indexes) > $_max_index) { + $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + + array_shift($indexes); + return $compiled_ref; + } + + /** + * compiles call to plugin of type $type with name $name + * returns a string containing the function-name or method call + * without the paramter-list that would have follow to make the + * call valid php-syntax + * + * @param string $type + * @param string $name + * @return string + */ + function _compile_plugin_call($type, $name) { + if (isset($this->_plugins[$type][$name])) { + /* plugin loaded */ + if (is_array($this->_plugins[$type][$name][0])) { + return ((is_object($this->_plugins[$type][$name][0][0])) ? + "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ + : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ + ). $this->_plugins[$type][$name][0][1]; + + } else { + /* function callback */ + return $this->_plugins[$type][$name][0]; + + } + } else { + /* plugin not loaded -> auto-loadable-plugin */ + return 'smarty_'.$type.'_'.$name; + + } + } + + /** + * load pre- and post-filters + */ + function _load_filters() + { + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) { + unset($this->_plugins['prefilter'][$filter_name]); + $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) { + unset($this->_plugins['postfilter'][$filter_name]); + $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + } + + + /** + * Quote subpattern references + * + * @param string $string + * @return string + */ + function _quote_replace($string) + { + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); + } + + /** + * display Smarty syntax error + * + * @param string $error_msg + * @param integer $error_type + * @param string $file + * @param integer $line + */ + function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) + { + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); + } + + + /** + * check if the compilation changes from cacheable to + * non-cacheable state with the beginning of the current + * plugin. return php-code to reflect the transition. + * @return string + */ + function _push_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || 0<$this->_cacheable_state++) return ''; + if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); + $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' + . $this->_cache_serial . '#' . $this->_nocache_count + . '}\'; endif;'; + return $_ret; + } + + + /** + * check if the compilation changes from non-cacheable to + * cacheable state with the end of the current plugin return + * php-code to reflect the transition. + * @return string + */ + function _pop_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || --$this->_cacheable_state>0) return ''; + return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' + . $this->_cache_serial . '#' . ($this->_nocache_count++) + . '}\'; endif;'; + } + + + /** + * push opening tag-name, file-name and line-number on the tag-stack + * @param string the opening tag's name + */ + function _push_tag($open_tag) + { + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); + } + + /** + * pop closing tag-name + * raise an error if this stack-top doesn't match with the closing tag + * @param string the closing tag's name + * @return string the opening tag's name + */ + function _pop_tag($close_tag) + { + $message = ''; + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); + if ($close_tag == $_open_tag) { + return $_open_tag; + } + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { + return $this->_pop_tag($close_tag); + } + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($_open_tag == 'else' || $_open_tag == 'elseif') { + $_open_tag = 'if'; + } elseif ($_open_tag == 'sectionelse') { + $_open_tag = 'section'; + } elseif ($_open_tag == 'foreachelse') { + $_open_tag = 'foreach'; + } + $message = " expected {/$_open_tag} (opened line $_line_no)."; + } + $this->_syntax_error("mismatched tag {/$close_tag}.$message", + E_USER_ERROR, __FILE__, __LINE__); + } + +} + +/** + * compare to values by their string length + * + * @access private + * @param string $a + * @param string $b + * @return 0|-1|1 + */ +function _smarty_sort_length($a, $b) +{ + if($a == $b) + return 0; + + if(strlen($a) == strlen($b)) + return ($a > $b) ? -1 : 1; + + return (strlen($a) > strlen($b)) ? -1 : 1; +} + + +/* vim: set et: */ + +?> diff --git a/libs/Smarty/debug.tpl b/libs/Smarty/debug.tpl index c05ef5d0b5..06c88e7964 100755 --- a/libs/Smarty/debug.tpl +++ b/libs/Smarty/debug.tpl @@ -154,4 +154,4 @@ td { _smarty_console.document.close(); // ]]> </script> -{/if}
\ No newline at end of file +{/if} diff --git a/libs/Smarty/internals/core.process_compiled_include.php b/libs/Smarty/internals/core.process_compiled_include.php index 0d22d2c60a..904d597452 100755 --- a/libs/Smarty/internals/core.process_compiled_include.php +++ b/libs/Smarty/internals/core.process_compiled_include.php @@ -1,37 +1,37 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Replace nocache-tags by results of the corresponding non-cacheable
- * functions and return it
- *
- * @param string $compiled_tpl
- * @param string $cached_source
- * @return string
- */
-
-function smarty_core_process_compiled_include($params, &$smarty)
-{
- $_cache_including = $smarty->_cache_including;
- $smarty->_cache_including = true;
-
- $_return = $params['results'];
-
- foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
- $smarty->_include($_include_file_path, true);
- }
-
- foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
- $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
- array(&$smarty, '_process_compiled_include_callback'),
- $_return);
- }
- $smarty->_cache_including = $_cache_including;
- return $_return;
-}
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + +/** + * Replace nocache-tags by results of the corresponding non-cacheable + * functions and return it + * + * @param string $compiled_tpl + * @param string $cached_source + * @return string + */ + +function smarty_core_process_compiled_include($params, &$smarty) +{ + $_cache_including = $smarty->_cache_including; + $smarty->_cache_including = true; + + $_return = $params['results']; + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $smarty->_include($_include_file_path, true); + } + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', + array(&$smarty, '_process_compiled_include_callback'), + $_return); + } + $smarty->_cache_including = $_cache_including; + return $_return; +} + +?> diff --git a/libs/Smarty/internals/core.write_cache_file.php b/libs/Smarty/internals/core.write_cache_file.php index 230343dcb1..fa3cdd746d 100755 --- a/libs/Smarty/internals/core.write_cache_file.php +++ b/libs/Smarty/internals/core.write_cache_file.php @@ -1,96 +1,96 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Prepend the cache information to the cache file
- * and write it
- *
- * @param string $tpl_file
- * @param string $cache_id
- * @param string $compile_id
- * @param string $results
- * @return true|null
- */
-
- // $tpl_file, $cache_id, $compile_id, $results
-
-function smarty_core_write_cache_file($params, &$smarty)
-{
-
- // put timestamp in cache header
- $smarty->_cache_info['timestamp'] = time();
- if ($smarty->cache_lifetime > -1){
- // expiration set
- $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
- } else {
- // cache will never expire
- $smarty->_cache_info['expires'] = -1;
- }
-
- // collapse nocache.../nocache-tags
- if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
- // remove everything between every pair of outermost noache.../nocache-tags
- // and replace it by a single nocache-tag
- // this new nocache-tag will be replaced by dynamic contents in
- // smarty_core_process_compiled_includes() on a cache-read
-
- $match_count = count($match[0]);
- $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
-
- $level = 0;
- $j = 0;
- for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
- if ($results[$i] == $match[0][$j]) {
- // nocache tag
- if ($match[1][$j]) { // closing tag
- $level--;
- unset($results[$i]);
- } else { // opening tag
- if ($level++ > 0) unset($results[$i]);
- }
- $j++;
- } elseif ($level > 0) {
- unset($results[$i]);
- }
- }
- $params['results'] = implode('', $results);
- }
- $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
-
- // prepend the cache header info into cache file
- $_cache_info = serialize($smarty->_cache_info);
- $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
-
- if (!empty($smarty->cache_handler_func)) {
- // use cache_handler function
- call_user_func_array($smarty->cache_handler_func,
- array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
- } else {
- // use local cache file
-
- if(!@is_writable($smarty->cache_dir)) {
- // cache_dir not writable, see if it exists
- if(!@is_dir($smarty->cache_dir)) {
- $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
- return false;
- }
- $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
- return false;
- }
-
- $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
- $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
- $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
- require_once(SMARTY_CORE_DIR . 'core.write_file.php');
- smarty_core_write_file($_params, $smarty);
- return true;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + +/** + * Prepend the cache information to the cache file + * and write it + * + * @param string $tpl_file + * @param string $cache_id + * @param string $compile_id + * @param string $results + * @return true|null + */ + + // $tpl_file, $cache_id, $compile_id, $results + +function smarty_core_write_cache_file($params, &$smarty) +{ + + // put timestamp in cache header + $smarty->_cache_info['timestamp'] = time(); + if ($smarty->cache_lifetime > -1){ + // expiration set + $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; + } else { + // cache will never expire + $smarty->_cache_info['expires'] = -1; + } + + // collapse nocache.../nocache-tags + if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { + // remove everything between every pair of outermost noache.../nocache-tags + // and replace it by a single nocache-tag + // this new nocache-tag will be replaced by dynamic contents in + // smarty_core_process_compiled_includes() on a cache-read + + $match_count = count($match[0]); + $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); + + $level = 0; + $j = 0; + for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { + if ($results[$i] == $match[0][$j]) { + // nocache tag + if ($match[1][$j]) { // closing tag + $level--; + unset($results[$i]); + } else { // opening tag + if ($level++ > 0) unset($results[$i]); + } + $j++; + } elseif ($level > 0) { + unset($results[$i]); + } + } + $params['results'] = implode('', $results); + } + $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; + + // prepend the cache header info into cache file + $_cache_info = serialize($smarty->_cache_info); + $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; + + if (!empty($smarty->cache_handler_func)) { + // use cache_handler function + call_user_func_array($smarty->cache_handler_func, + array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires'])); + } else { + // use local cache file + + if(!@is_writable($smarty->cache_dir)) { + // cache_dir not writable, see if it exists + if(!@is_dir($smarty->cache_dir)) { + $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); + return false; + } + $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); + return false; + } + + $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); + $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); + $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/libs/Smarty/internals/core.write_file.php b/libs/Smarty/internals/core.write_file.php index 8a3a3b3984..2a5f24fd87 100755 --- a/libs/Smarty/internals/core.write_file.php +++ b/libs/Smarty/internals/core.write_file.php @@ -51,4 +51,4 @@ function smarty_core_write_file($params, &$smarty) /* vim: set expandtab: */ -?>
\ No newline at end of file +?> diff --git a/libs/Smarty/plugins/compiler.assign.php b/libs/Smarty/plugins/compiler.assign.php index 4d5f8413dc..abef377f8c 100755 --- a/libs/Smarty/plugins/compiler.assign.php +++ b/libs/Smarty/plugins/compiler.assign.php @@ -1,40 +1,40 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {assign} compiler function plugin
- *
- * Type: compiler function<br>
- * Name: assign<br>
- * Purpose: assign a value to a template variable
- * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com> (initial author)
- * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
- * @param string containing var-attribute and value-attribute
- * @param Smarty_Compiler
- */
-function smarty_compiler_assign($tag_attrs, &$compiler)
-{
- $_params = $compiler->_parse_attrs($tag_attrs);
-
- if (!isset($_params['var'])) {
- $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
- return;
- }
-
- if (!isset($_params['value'])) {
- $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
- return;
- }
-
- return "\$this->assign({$_params['var']}, {$_params['value']});";
-}
-
-/* vim: set expandtab: */
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + +/** + * Smarty {assign} compiler function plugin + * + * Type: compiler function<br> + * Name: assign<br> + * Purpose: assign a value to a template variable + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} + * (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> (initial author) + * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function) + * @param string containing var-attribute and value-attribute + * @param Smarty_Compiler + */ +function smarty_compiler_assign($tag_attrs, &$compiler) +{ + $_params = $compiler->_parse_attrs($tag_attrs); + + if (!isset($_params['var'])) { + $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); + return; + } + + if (!isset($_params['value'])) { + $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); + return; + } + + return "\$this->assign({$_params['var']}, {$_params['value']});"; +} + +/* vim: set expandtab: */ + +?> diff --git a/libs/Smarty/plugins/modifier.escape.php b/libs/Smarty/plugins/modifier.escape.php index d588b16297..9108ef6612 100755 --- a/libs/Smarty/plugins/modifier.escape.php +++ b/libs/Smarty/plugins/modifier.escape.php @@ -1,94 +1,94 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty escape modifier plugin
- *
- * Type: modifier<br>
- * Name: escape<br>
- * Purpose: Escape the string according to escapement type
- * @link http://smarty.php.net/manual/en/language.modifier.escape.php
- * escape (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param html|htmlall|url|quotes|hex|hexentity|javascript
- * @return string
- */
-function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
-{
- switch ($esc_type) {
- case 'html':
- return htmlspecialchars($string, ENT_QUOTES, $char_set);
-
- case 'htmlall':
- return htmlentities($string, ENT_QUOTES, $char_set);
-
- case 'url':
- return rawurlencode($string);
-
- case 'urlpathinfo':
- return str_replace('%2F','/',rawurlencode($string));
-
- case 'quotes':
- // escape unescaped single quotes
- return preg_replace("%(?<!\\\\)'%", "\\'", $string);
-
- case 'hex':
- // escape every character into hex
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '%' . bin2hex($string[$x]);
- }
- return $return;
-
- case 'hexentity':
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '&#x' . bin2hex($string[$x]) . ';';
- }
- return $return;
-
- case 'decentity':
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '&#' . ord($string[$x]) . ';';
- }
- return $return;
-
- case 'javascript':
- // escape quotes and backslashes, newlines, etc.
-// return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
- return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/','script'=>"sc'+'ript")); // piwik
-
- case 'mail':
- // safe way to display e-mail address on a web page
- return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
-
- case 'nonstd':
- // escape non-standard chars, such as ms document quotes
- $_res = '';
- for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
- $_ord = ord(substr($string, $_i, 1));
- // non-standard char, escape it
- if($_ord >= 126){
- $_res .= '&#' . $_ord . ';';
- }
- else {
- $_res .= substr($string, $_i, 1);
- }
- }
- return $_res;
-
- default:
- return $string;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + + +/** + * Smarty escape modifier plugin + * + * Type: modifier<br> + * Name: escape<br> + * Purpose: Escape the string according to escapement type + * @link http://smarty.php.net/manual/en/language.modifier.escape.php + * escape (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string + * @param html|htmlall|url|quotes|hex|hexentity|javascript + * @return string + */ +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1') +{ + switch ($esc_type) { + case 'html': + return htmlspecialchars($string, ENT_QUOTES, $char_set); + + case 'htmlall': + return htmlentities($string, ENT_QUOTES, $char_set); + + case 'url': + return rawurlencode($string); + + case 'urlpathinfo': + return str_replace('%2F','/',rawurlencode($string)); + + case 'quotes': + // escape unescaped single quotes + return preg_replace("%(?<!\\\\)'%", "\\'", $string); + + case 'hex': + // escape every character into hex + $return = ''; + for ($x=0; $x < strlen($string); $x++) { + $return .= '%' . bin2hex($string[$x]); + } + return $return; + + case 'hexentity': + $return = ''; + for ($x=0; $x < strlen($string); $x++) { + $return .= '&#x' . bin2hex($string[$x]) . ';'; + } + return $return; + + case 'decentity': + $return = ''; + for ($x=0; $x < strlen($string); $x++) { + $return .= '&#' . ord($string[$x]) . ';'; + } + return $return; + + case 'javascript': + // escape quotes and backslashes, newlines, etc. +// return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/')); + return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/','script'=>"sc'+'ript")); // piwik + + case 'mail': + // safe way to display e-mail address on a web page + return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string); + + case 'nonstd': + // escape non-standard chars, such as ms document quotes + $_res = ''; + for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) { + $_ord = ord(substr($string, $_i, 1)); + // non-standard char, escape it + if($_ord >= 126){ + $_res .= '&#' . $_ord . ';'; + } + else { + $_res .= substr($string, $_i, 1); + } + } + return $_res; + + default: + return $string; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/libs/Smarty/plugins/modifier.regex_replace.php b/libs/Smarty/plugins/modifier.regex_replace.php index 39cdf0a08f..100b58ce4b 100755 --- a/libs/Smarty/plugins/modifier.regex_replace.php +++ b/libs/Smarty/plugins/modifier.regex_replace.php @@ -1,48 +1,48 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty regex_replace modifier plugin
- *
- * Type: modifier<br>
- * Name: regex_replace<br>
- * Purpose: regular expression search/replace
- * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
- * regex_replace (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string|array
- * @param string|array
- * @return string
- */
-function smarty_modifier_regex_replace($string, $search, $replace)
-{
- if(is_array($search)) {
- foreach($search as $idx => $s)
- $search[$idx] = _smarty_regex_replace_check($s);
- } else {
- $search = _smarty_regex_replace_check($search);
- }
-
- return preg_replace($search, $replace, $string);
-}
-
-function _smarty_regex_replace_check($search)
-{
- if (($pos = strpos($search,"\0")) !== false)
- $search = substr($search,0,$pos);
- if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
- /* remove eval-modifier from $search */
- $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
- }
- return $search;
-}
-
-/* vim: set expandtab: */
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + + +/** + * Smarty regex_replace modifier plugin + * + * Type: modifier<br> + * Name: regex_replace<br> + * Purpose: regular expression search/replace + * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php + * regex_replace (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string + * @param string|array + * @param string|array + * @return string + */ +function smarty_modifier_regex_replace($string, $search, $replace) +{ + if(is_array($search)) { + foreach($search as $idx => $s) + $search[$idx] = _smarty_regex_replace_check($s); + } else { + $search = _smarty_regex_replace_check($search); + } + + return preg_replace($search, $replace, $string); +} + +function _smarty_regex_replace_check($search) +{ + if (($pos = strpos($search,"\0")) !== false) + $search = substr($search,0,$pos); + if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { + /* remove eval-modifier from $search */ + $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); + } + return $search; +} + +/* vim: set expandtab: */ + +?> diff --git a/libs/Smarty/plugins/outputfilter.trimwhitespace.php b/libs/Smarty/plugins/outputfilter.trimwhitespace.php index 66e1e0968b..739fa39b02 100755 --- a/libs/Smarty/plugins/outputfilter.trimwhitespace.php +++ b/libs/Smarty/plugins/outputfilter.trimwhitespace.php @@ -1,75 +1,75 @@ -<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty trimwhitespace outputfilter plugin
- *
- * File: outputfilter.trimwhitespace.php<br>
- * Type: outputfilter<br>
- * Name: trimwhitespace<br>
- * Date: Jan 25, 2003<br>
- * Purpose: trim leading white space and blank lines from
- * template source after it gets interpreted, cleaning
- * up code and saving bandwidth. Does not affect
- * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
- * Install: Drop into the plugin directory, call
- * <code>$smarty->load_filter('output','trimwhitespace');</code>
- * from application.
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
- * @version 1.3
- * @param string
- * @param Smarty
- */
-function smarty_outputfilter_trimwhitespace($source, &$smarty)
-{
- // Pull out the script blocks
- preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
- $_script_blocks = $match[0];
- $source = preg_replace("!<script[^>]*?>.*?</script>!is",
- '@@@SMARTY:TRIM:SCRIPT@@@', $source);
-
- // Pull out the pre blocks
- preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
- $_pre_blocks = $match[0];
- $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
- '@@@SMARTY:TRIM:PRE@@@', $source);
-
- // Pull out the textarea blocks
- preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
- $_textarea_blocks = $match[0];
- $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
- '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
-
- // remove all leading spaces, tabs and carriage returns NOT
- // preceeded by a php close tag.
- $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
-
- // replace textarea blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
-
- // replace pre blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
-
- // replace script blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
-
- return $source;
-}
-
-function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
- $_len = strlen($search_str);
- $_pos = 0;
- for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
- if (($_pos=strpos($subject, $search_str, $_pos))!==false)
- $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
- else
- break;
-
-}
-
-?>
+<?php +/** + * Smarty plugin + * @package Smarty + * @subpackage plugins + */ + +/** + * Smarty trimwhitespace outputfilter plugin + * + * File: outputfilter.trimwhitespace.php<br> + * Type: outputfilter<br> + * Name: trimwhitespace<br> + * Date: Jan 25, 2003<br> + * Purpose: trim leading white space and blank lines from + * template source after it gets interpreted, cleaning + * up code and saving bandwidth. Does not affect + * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br> + * Install: Drop into the plugin directory, call + * <code>$smarty->load_filter('output','trimwhitespace');</code> + * from application. + * @author Monte Ohrt <monte at ohrt dot com> + * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de> + * @version 1.3 + * @param string + * @param Smarty + */ +function smarty_outputfilter_trimwhitespace($source, &$smarty) +{ + // Pull out the script blocks + preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match); + $_script_blocks = $match[0]; + $source = preg_replace("!<script[^>]*?>.*?</script>!is", + '@@@SMARTY:TRIM:SCRIPT@@@', $source); + + // Pull out the pre blocks + preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match); + $_pre_blocks = $match[0]; + $source = preg_replace("!<pre[^>]*?>.*?</pre>!is", + '@@@SMARTY:TRIM:PRE@@@', $source); + + // Pull out the textarea blocks + preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match); + $_textarea_blocks = $match[0]; + $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is", + '@@@SMARTY:TRIM:TEXTAREA@@@', $source); + + // remove all leading spaces, tabs and carriage returns NOT + // preceeded by a php close tag. + $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source)); + + // replace textarea blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); + + // replace pre blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); + + // replace script blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); + + return $source; +} + +function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) { + $_len = strlen($search_str); + $_pos = 0; + for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) + if (($_pos=strpos($subject, $search_str, $_pos))!==false) + $subject = substr_replace($subject, $replace[$_i], $_pos, $_len); + else + break; + +} + +?> diff --git a/libs/Zend/Auth/Adapter/DbTable.php b/libs/Zend/Auth/Adapter/DbTable.php index 6451b6a726..191565092e 100755 --- a/libs/Zend/Auth/Adapter/DbTable.php +++ b/libs/Zend/Auth/Adapter/DbTable.php @@ -351,4 +351,4 @@ class Zend_Auth_Adapter_DbTable implements Zend_Auth_Adapter_Interface return new Zend_Auth_Result($authResult['code'], $authResult['identity'], $authResult['messages']); } -}
\ No newline at end of file +} diff --git a/libs/Zend/Cache/EXAMPLES.txt b/libs/Zend/Cache/EXAMPLES.txt index cfe60f8413..fc49aca774 100755 --- a/libs/Zend/Cache/EXAMPLES.txt +++ b/libs/Zend/Cache/EXAMPLES.txt @@ -370,4 +370,4 @@ $cache = Zend_Cache::factory('File', 'File', $frontendOptions, $backendOptions); // [...] identical to the "Core" use -?>
\ No newline at end of file +?> diff --git a/libs/Zend/Cache/Frontend/Output.php b/libs/Zend/Cache/Frontend/Output.php index 6ea8ca3ff1..7a3ef18ce7 100755 --- a/libs/Zend/Cache/Frontend/Output.php +++ b/libs/Zend/Cache/Frontend/Output.php @@ -81,4 +81,4 @@ class Zend_Cache_Frontend_Output extends Zend_Cache_Core echo($data); } -}
\ No newline at end of file +} diff --git a/libs/Zend/Feed/Builder.php b/libs/Zend/Feed/Builder.php index 343a312b8c..28883d9173 100644 --- a/libs/Zend/Feed/Builder.php +++ b/libs/Zend/Feed/Builder.php @@ -392,4 +392,4 @@ class Zend_Feed_Builder implements Zend_Feed_Builder_Interface $this->_entries[] = $entry; } } -}
\ No newline at end of file +} diff --git a/libs/Zend/Feed/Builder/Header/Itunes.php b/libs/Zend/Feed/Builder/Header/Itunes.php index b8c3cff6d6..c6e3dc629b 100644 --- a/libs/Zend/Feed/Builder/Header/Itunes.php +++ b/libs/Zend/Feed/Builder/Header/Itunes.php @@ -282,4 +282,4 @@ class Zend_Feed_Builder_Header_Itunes extends ArrayObject } } -}
\ No newline at end of file +} diff --git a/libs/Zend/Log.php b/libs/Zend/Log.php index 327da7b9f8..31f35dec46 100755 --- a/libs/Zend/Log.php +++ b/libs/Zend/Log.php @@ -208,4 +208,4 @@ class Zend_Log $this->_extras = array_merge($this->_extras, array($name => $value)); } -}
\ No newline at end of file +} diff --git a/libs/Zend/Log/Writer/Abstract.php b/libs/Zend/Log/Writer/Abstract.php index d8803304b7..aa5cee4750 100755 --- a/libs/Zend/Log/Writer/Abstract.php +++ b/libs/Zend/Log/Writer/Abstract.php @@ -106,4 +106,4 @@ abstract class Zend_Log_Writer_Abstract */ abstract protected function _write($event); -}
\ No newline at end of file +} diff --git a/libs/Zend/Log/Writer/Mock.php b/libs/Zend/Log/Writer/Mock.php index 4c2e78bb80..2334d5ddb0 100755 --- a/libs/Zend/Log/Writer/Mock.php +++ b/libs/Zend/Log/Writer/Mock.php @@ -63,4 +63,4 @@ class Zend_Log_Writer_Mock extends Zend_Log_Writer_Abstract { $this->shutdown = true; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Log/Writer/Null.php b/libs/Zend/Log/Writer/Null.php index 8150e1b2da..95e68a7190 100755 --- a/libs/Zend/Log/Writer/Null.php +++ b/libs/Zend/Log/Writer/Null.php @@ -43,4 +43,4 @@ class Zend_Log_Writer_Null extends Zend_Log_Writer_Abstract { } -}
\ No newline at end of file +} diff --git a/libs/Zend/Mail.php b/libs/Zend/Mail.php index e6da4dce85..958eee02d4 100644 --- a/libs/Zend/Mail.php +++ b/libs/Zend/Mail.php @@ -1,725 +1,725 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Mail.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Transport_Abstract
- */
-require_once 'Zend/Mail/Transport/Abstract.php';
-
-/**
- * @see Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-/**
- * @see Zend_Mail_Transport_Abstract
- */
-require_once 'Zend/Mail/Transport/Abstract.php';
-
-/**
- * @see Zend_Mime_Message
- */
-require_once 'Zend/Mime/Message.php';
-
-/**
- * @see Zend_Mime_Part
- */
-require_once 'Zend/Mime/Part.php';
-
-
-/**
- * Class for sending an email.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail extends Zend_Mime_Message
-{
- /**#@+
- * @access protected
- */
-
- /**
- * @var Zend_Mail_Transport_Abstract
- * @static
- */
- protected static $_defaultTransport = null;
-
- /**
- * Mail character set
- * @var string
- */
- protected $_charset = null;
-
- /**
- * Mail headers
- * @var array
- */
- protected $_headers = array();
-
- /**
- * From: address
- * @var string
- */
- protected $_from = null;
-
- /**
- * To: addresses
- * @var array
- */
- protected $_to = array();
-
- /**
- * Array of all recipients
- * @var array
- */
- protected $_recipients = array();
-
- /**
- * Return-Path header
- * @var string
- */
- protected $_returnPath = null;
-
- /**
- * Subject: header
- * @var string
- */
- protected $_subject = null;
-
- /**
- * Date: header
- * @var string
- */
- protected $_date = null;
-
- /**
- * text/plain MIME part
- * @var false|Zend_Mime_Part
- */
- protected $_bodyText = false;
-
- /**
- * text/html MIME part
- * @var false|Zend_Mime_Part
- */
- protected $_bodyHtml = false;
-
- /**
- * MIME boundary string
- * @var string
- */
- protected $_mimeBoundary = null;
-
- /**
- * Content type of the message
- * @var string
- */
- protected $_type = null;
-
- /**#@-*/
-
- /**
- * Flag: whether or not email has attachments
- * @var boolean
- */
- public $hasAttachments = false;
-
-
- /**
- * Sets the default mail transport for all following uses of
- * Zend_Mail::send();
- *
- * @todo Allow passing a string to indicate the transport to load
- * @todo Allow passing in optional options for the transport to load
- * @param Zend_Mail_Transport_Abstract $transport
- */
- public static function setDefaultTransport(Zend_Mail_Transport_Abstract $transport)
- {
- self::$_defaultTransport = $transport;
- }
-
- /**
- * Public constructor
- *
- * @param string $charset
- */
- public function __construct($charset='iso-8859-1')
- {
- $this->_charset = $charset;
- }
-
- /**
- * Return charset string
- *
- * @return string
- */
- public function getCharset()
- {
- return $this->_charset;
- }
-
- /**
- * Set content type
- *
- * Should only be used for manually setting multipart content types.
- *
- * @param string $type Content type
- * @return Zend_Mail Implements fluent interface
- * @throws Zend_Mail_Exception for types not supported by Zend_Mime
- */
- public function setType($type)
- {
- $allowed = array(
- Zend_Mime::MULTIPART_ALTERNATIVE,
- Zend_Mime::MULTIPART_MIXED,
- Zend_Mime::MULTIPART_RELATED,
- );
- if (!in_array($type, $allowed)) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('Invalid content type "' . $type . '"');
- }
-
- $this->_type = $type;
- return $this;
- }
-
- /**
- * Get content type of the message
- *
- * @return string
- */
- public function getType()
- {
- return $this->_type;
- }
-
- /**
- * Set an arbitrary mime boundary for the message
- *
- * If not set, Zend_Mime will generate one.
- *
- * @param string $boundary
- * @return Zend_Mail Provides fluent interface
- */
- public function setMimeBoundary($boundary)
- {
- $this->_mimeBoundary = $boundary;
-
- return $this;
- }
-
- /**
- * Return the boundary string used for the message
- *
- * @return string
- */
- public function getMimeBoundary()
- {
- return $this->_mimeBoundary;
- }
-
- /**
- * Sets the text body for the message.
- *
- * @param string $txt
- * @param string $charset
- * @param string $encoding
- * @return Zend_Mail Provides fluent interface
- */
- public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
- {
- if ($charset === null) {
- $charset = $this->_charset;
- }
-
- $mp = new Zend_Mime_Part($txt);
- $mp->encoding = $encoding;
- $mp->type = Zend_Mime::TYPE_TEXT;
- $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
- $mp->charset = $charset;
-
- $this->_bodyText = $mp;
-
- return $this;
- }
-
- /**
- * Return text body Zend_Mime_Part or string
- *
- * @param bool textOnly Whether to return just the body text content or the MIME part; defaults to false, the MIME part
- * @return false|Zend_Mime_Part|string
- */
- public function getBodyText($textOnly = false)
- {
- if ($textOnly && $this->_bodyText) {
- $body = $this->_bodyText;
- return $body->getContent();
- }
-
- return $this->_bodyText;
- }
-
- /**
- * Sets the HTML body for the message
- *
- * @param string $html
- * @param string $charset
- * @param string $encoding
- * @return Zend_Mail Provides fluent interface
- */
- public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
- {
- if ($charset === null) {
- $charset = $this->_charset;
- }
-
- $mp = new Zend_Mime_Part($html);
- $mp->encoding = $encoding;
- $mp->type = Zend_Mime::TYPE_HTML;
- $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
- $mp->charset = $charset;
-
- $this->_bodyHtml = $mp;
-
- return $this;
- }
-
- /**
- * Return Zend_Mime_Part representing body HTML
- *
- * @param bool $htmlOnly Whether to return the body HTML only, or the MIME part; defaults to false, the MIME part
- * @return false|Zend_Mime_Part|string
- */
- public function getBodyHtml($htmlOnly = false)
- {
- if ($htmlOnly && $this->_bodyHtml) {
- $body = $this->_bodyHtml;
- return $body->getContent();
- }
-
- return $this->_bodyHtml;
- }
-
- /**
- * Adds an existing attachment to the mail message
- *
- * @param Zend_Mime_Part $attachment
- * @return Zend_Mail Provides fluent interface
- */
- public function addAttachment(Zend_Mime_Part $attachment)
- {
- $this->addPart($attachment);
- $this->hasAttachments = true;
-
- return $this;
- }
-
- /**
- * Creates a Zend_Mime_Part attachment
- *
- * Attachment is automatically added to the mail object after creation. The
- * attachment object is returned to allow for further manipulation.
- *
- * @param string $body
- * @param string $mimeType
- * @param string $disposition
- * @param string $encoding
- * @param string $filename OPTIONAL A filename for the attachment
- * @return Zend_Mime_Part Newly created Zend_Mime_Part object (to allow
- * advanced settings)
- */
- public function createAttachment($body,
- $mimeType = Zend_Mime::TYPE_OCTETSTREAM,
- $disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
- $encoding = Zend_Mime::ENCODING_BASE64,
- $filename = null)
- {
-
- $mp = new Zend_Mime_Part($body);
- $mp->encoding = $encoding;
- $mp->type = $mimeType;
- $mp->disposition = $disposition;
- $mp->filename = $filename;
-
- $this->addAttachment($mp);
-
- return $mp;
- }
-
- /**
- * Return a count of message parts
- *
- * @return integer
- */
- public function getPartCount()
- {
- return count($this->_parts);
- }
-
- /**
- * Encode header fields
- *
- * Encodes header content according to RFC1522 if it contains non-printable
- * characters.
- *
- * @param string $value
- * @return string
- */
- protected function _encodeHeader($value)
- {
- if (Zend_Mime::isPrintable($value)) {
- return $value;
- } else {
- $quotedValue = Zend_Mime::encodeQuotedPrintable($value);
- $quotedValue = str_replace(array('?', ' '), array('=3F', '=20'), $quotedValue);
- return '=?' . $this->_charset . '?Q?' . $quotedValue . '?=';
- }
- }
-
- /**
- * Add a header to the message
- *
- * Adds a header to this message. If append is true and the header already
- * exists, raises a flag indicating that the header should be appended.
- *
- * @param string $headerName
- * @param string $value
- * @param boolean $append
- */
- protected function _storeHeader($headerName, $value, $append=false)
- {
-// ?? $value = strtr($value,"\r\n\t",'???');
- if (isset($this->_headers[$headerName])) {
- $this->_headers[$headerName][] = $value;
- } else {
- $this->_headers[$headerName] = array($value);
- }
-
- if ($append) {
- $this->_headers[$headerName]['append'] = true;
- }
-
- }
-
- /**
- * Add a recipient
- *
- * @param string $email
- */
- protected function _addRecipient($email, $to = false)
- {
- // prevent duplicates
- $this->_recipients[$email] = 1;
-
- if ($to) {
- $this->_to[] = $email;
- }
- }
-
- /**
- * Helper function for adding a recipient and the corresponding header
- *
- * @param string $headerName
- * @param string $name
- * @param string $email
- */
- protected function _addRecipientAndHeader($headerName, $name, $email)
- {
- $email = strtr($email,"\r\n\t",'???');
- $this->_addRecipient($email, ('To' == $headerName) ? true : false);
- if ($name != '') {
- $name = '"' . $this->_encodeHeader($name) . '" ';
- }
-
- $this->_storeHeader($headerName, $name .'<'. $email . '>', true);
- }
-
- /**
- * Adds To-header and recipient
- *
- * @param string $name
- * @param string $email
- * @return Zend_Mail Provides fluent interface
- */
- public function addTo($email, $name='')
- {
- $this->_addRecipientAndHeader('To', $name, $email);
- return $this;
- }
-
- /**
- * Adds Cc-header and recipient
- *
- * @param string $name
- * @param string $email
- * @return Zend_Mail Provides fluent interface
- */
- public function addCc($email, $name='')
- {
- $this->_addRecipientAndHeader('Cc', $name, $email);
- return $this;
- }
-
- /**
- * Adds Bcc recipient
- *
- * @param string $email
- * @return Zend_Mail Provides fluent interface
- */
- public function addBcc($email)
- {
- $this->_addRecipientAndHeader('Bcc', '', $email);
- return $this;
- }
-
- /**
- * Return list of recipient email addresses
- *
- * @return array (of strings)
- */
- public function getRecipients()
- {
- return array_keys($this->_recipients);
- }
-
- /**
- * Sets From-header and sender of the message
- *
- * @param string $email
- * @param string $name
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception if called subsequent times
- */
- public function setFrom($email, $name = '')
- {
- if ($this->_from === null) {
- $email = strtr($email,"\r\n\t",'???');
- $this->_from = $email;
- $this->_storeHeader('From', $this->_encodeHeader('"'.$name.'"').' <'.$email.'>', true);
- } else {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('From Header set twice');
- }
- return $this;
- }
-
- /**
- * Returns the sender of the mail
- *
- * @return string
- */
- public function getFrom()
- {
- return $this->_from;
- }
-
- /**
- * Sets the Return-Path header for an email
- *
- * @param string $email
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception if set multiple times
- */
- public function setReturnPath($email)
- {
- if ($this->_returnPath === null) {
- $email = strtr($email,"\r\n\t",'???');
- $this->_returnPath = $email;
- $this->_storeHeader('Return-Path', $email, false);
- } else {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('Return-Path Header set twice');
- }
- return $this;
- }
-
- /**
- * Returns the current Return-Path address for the email
- *
- * If no Return-Path header is set, returns the value of {@link $_from}.
- *
- * @return string
- */
- public function getReturnPath()
- {
- if (null !== $this->_returnPath) {
- return $this->_returnPath;
- }
-
- return $this->_from;
- }
-
- /**
- * Sets the subject of the message
- *
- * @param string $subject
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception
- */
- public function setSubject($subject)
- {
- if ($this->_subject === null) {
- $subject = strtr($subject,"\r\n\t",'???');
- $this->_subject = $this->_encodeHeader($subject);
- $this->_storeHeader('Subject', $this->_subject);
- } else {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('Subject set twice');
- }
- return $this;
- }
-
- /**
- * Returns the encoded subject of the message
- *
- * @return string
- */
- public function getSubject()
- {
- return $this->_subject;
- }
-
- /**
- * Sets Date-header
- *
- * @param string $date
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception if called subsequent times
- */
- public function setDate($date = null)
- {
- if ($this->_date === null) {
- if ($date === null) {
- $date = date('r');
- } else if (is_int($date)) {
- $date = date('r', $date);
- } else if (is_string($date)) {
- $date = strtotime($date);
- if ($date === false || $date < 0) {
- throw new Zend_Mail_Exception('String representations of Date Header must be ' .
- 'strtotime()-compatible');
- }
- $date = date('r', $date);
- } else if ($date instanceof Zend_Date) {
- $date = $date->get(Zend_Date::RFC_2822);
- } else {
- throw new Zend_Mail_Exception(__METHOD__ . ' only accepts UNIX timestamps, Zend_Date objects, ' .
- ' and strtotime()-compatible strings');
- }
- $this->_date = $date;
- $this->_storeHeader('Date', $date);
- } else {
- throw new Zend_Mail_Exception('Date Header set twice');
- }
- return $this;
- }
-
- /**
- * Returns the formatted date of the message
- *
- * @return string
- */
- public function getDate()
- {
- return $this->_date;
- }
-
- /**
- * Add a custom header to the message
- *
- * @param string $name
- * @param string $value
- * @param boolean $append
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception on attempts to create standard headers
- */
- public function addHeader($name, $value, $append = false)
- {
- if (in_array(strtolower($name), array('to', 'cc', 'bcc', 'from', 'subject', 'return-path', 'date'))) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('Cannot set standard header from addHeader()');
- }
-
- $value = strtr($value,"\r\n\t",'???');
- $value = $this->_encodeHeader($value);
- $this->_storeHeader($name, $value, $append);
-
- return $this;
- }
-
- /**
- * Return mail headers
- *
- * @return void
- */
- public function getHeaders()
- {
- return $this->_headers;
- }
-
- /**
- * Sends this email using the given transport or a previously
- * set DefaultTransport or the internal mail function if no
- * default transport had been set.
- *
- * @param Zend_Mail_Transport_Abstract $transport
- * @return Zend_Mail Provides fluent interface
- */
- public function send($transport = null)
- {
- if ($transport === null) {
- if (! self::$_defaultTransport instanceof Zend_Mail_Transport_Abstract) {
- require_once 'Zend/Mail/Transport/Sendmail.php';
- $transport = new Zend_Mail_Transport_Sendmail();
- } else {
- $transport = self::$_defaultTransport;
- }
- }
-
- if (is_null($this->_date)) {
- $this->setDate();
- }
-
- $transport->send($this);
-
- return $this;
- }
-
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Mail.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Transport_Abstract + */ +require_once 'Zend/Mail/Transport/Abstract.php'; + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * @see Zend_Mail_Transport_Abstract + */ +require_once 'Zend/Mail/Transport/Abstract.php'; + +/** + * @see Zend_Mime_Message + */ +require_once 'Zend/Mime/Message.php'; + +/** + * @see Zend_Mime_Part + */ +require_once 'Zend/Mime/Part.php'; + + +/** + * Class for sending an email. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail extends Zend_Mime_Message +{ + /**#@+ + * @access protected + */ + + /** + * @var Zend_Mail_Transport_Abstract + * @static + */ + protected static $_defaultTransport = null; + + /** + * Mail character set + * @var string + */ + protected $_charset = null; + + /** + * Mail headers + * @var array + */ + protected $_headers = array(); + + /** + * From: address + * @var string + */ + protected $_from = null; + + /** + * To: addresses + * @var array + */ + protected $_to = array(); + + /** + * Array of all recipients + * @var array + */ + protected $_recipients = array(); + + /** + * Return-Path header + * @var string + */ + protected $_returnPath = null; + + /** + * Subject: header + * @var string + */ + protected $_subject = null; + + /** + * Date: header + * @var string + */ + protected $_date = null; + + /** + * text/plain MIME part + * @var false|Zend_Mime_Part + */ + protected $_bodyText = false; + + /** + * text/html MIME part + * @var false|Zend_Mime_Part + */ + protected $_bodyHtml = false; + + /** + * MIME boundary string + * @var string + */ + protected $_mimeBoundary = null; + + /** + * Content type of the message + * @var string + */ + protected $_type = null; + + /**#@-*/ + + /** + * Flag: whether or not email has attachments + * @var boolean + */ + public $hasAttachments = false; + + + /** + * Sets the default mail transport for all following uses of + * Zend_Mail::send(); + * + * @todo Allow passing a string to indicate the transport to load + * @todo Allow passing in optional options for the transport to load + * @param Zend_Mail_Transport_Abstract $transport + */ + public static function setDefaultTransport(Zend_Mail_Transport_Abstract $transport) + { + self::$_defaultTransport = $transport; + } + + /** + * Public constructor + * + * @param string $charset + */ + public function __construct($charset='iso-8859-1') + { + $this->_charset = $charset; + } + + /** + * Return charset string + * + * @return string + */ + public function getCharset() + { + return $this->_charset; + } + + /** + * Set content type + * + * Should only be used for manually setting multipart content types. + * + * @param string $type Content type + * @return Zend_Mail Implements fluent interface + * @throws Zend_Mail_Exception for types not supported by Zend_Mime + */ + public function setType($type) + { + $allowed = array( + Zend_Mime::MULTIPART_ALTERNATIVE, + Zend_Mime::MULTIPART_MIXED, + Zend_Mime::MULTIPART_RELATED, + ); + if (!in_array($type, $allowed)) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('Invalid content type "' . $type . '"'); + } + + $this->_type = $type; + return $this; + } + + /** + * Get content type of the message + * + * @return string + */ + public function getType() + { + return $this->_type; + } + + /** + * Set an arbitrary mime boundary for the message + * + * If not set, Zend_Mime will generate one. + * + * @param string $boundary + * @return Zend_Mail Provides fluent interface + */ + public function setMimeBoundary($boundary) + { + $this->_mimeBoundary = $boundary; + + return $this; + } + + /** + * Return the boundary string used for the message + * + * @return string + */ + public function getMimeBoundary() + { + return $this->_mimeBoundary; + } + + /** + * Sets the text body for the message. + * + * @param string $txt + * @param string $charset + * @param string $encoding + * @return Zend_Mail Provides fluent interface + */ + public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) + { + if ($charset === null) { + $charset = $this->_charset; + } + + $mp = new Zend_Mime_Part($txt); + $mp->encoding = $encoding; + $mp->type = Zend_Mime::TYPE_TEXT; + $mp->disposition = Zend_Mime::DISPOSITION_INLINE; + $mp->charset = $charset; + + $this->_bodyText = $mp; + + return $this; + } + + /** + * Return text body Zend_Mime_Part or string + * + * @param bool textOnly Whether to return just the body text content or the MIME part; defaults to false, the MIME part + * @return false|Zend_Mime_Part|string + */ + public function getBodyText($textOnly = false) + { + if ($textOnly && $this->_bodyText) { + $body = $this->_bodyText; + return $body->getContent(); + } + + return $this->_bodyText; + } + + /** + * Sets the HTML body for the message + * + * @param string $html + * @param string $charset + * @param string $encoding + * @return Zend_Mail Provides fluent interface + */ + public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) + { + if ($charset === null) { + $charset = $this->_charset; + } + + $mp = new Zend_Mime_Part($html); + $mp->encoding = $encoding; + $mp->type = Zend_Mime::TYPE_HTML; + $mp->disposition = Zend_Mime::DISPOSITION_INLINE; + $mp->charset = $charset; + + $this->_bodyHtml = $mp; + + return $this; + } + + /** + * Return Zend_Mime_Part representing body HTML + * + * @param bool $htmlOnly Whether to return the body HTML only, or the MIME part; defaults to false, the MIME part + * @return false|Zend_Mime_Part|string + */ + public function getBodyHtml($htmlOnly = false) + { + if ($htmlOnly && $this->_bodyHtml) { + $body = $this->_bodyHtml; + return $body->getContent(); + } + + return $this->_bodyHtml; + } + + /** + * Adds an existing attachment to the mail message + * + * @param Zend_Mime_Part $attachment + * @return Zend_Mail Provides fluent interface + */ + public function addAttachment(Zend_Mime_Part $attachment) + { + $this->addPart($attachment); + $this->hasAttachments = true; + + return $this; + } + + /** + * Creates a Zend_Mime_Part attachment + * + * Attachment is automatically added to the mail object after creation. The + * attachment object is returned to allow for further manipulation. + * + * @param string $body + * @param string $mimeType + * @param string $disposition + * @param string $encoding + * @param string $filename OPTIONAL A filename for the attachment + * @return Zend_Mime_Part Newly created Zend_Mime_Part object (to allow + * advanced settings) + */ + public function createAttachment($body, + $mimeType = Zend_Mime::TYPE_OCTETSTREAM, + $disposition = Zend_Mime::DISPOSITION_ATTACHMENT, + $encoding = Zend_Mime::ENCODING_BASE64, + $filename = null) + { + + $mp = new Zend_Mime_Part($body); + $mp->encoding = $encoding; + $mp->type = $mimeType; + $mp->disposition = $disposition; + $mp->filename = $filename; + + $this->addAttachment($mp); + + return $mp; + } + + /** + * Return a count of message parts + * + * @return integer + */ + public function getPartCount() + { + return count($this->_parts); + } + + /** + * Encode header fields + * + * Encodes header content according to RFC1522 if it contains non-printable + * characters. + * + * @param string $value + * @return string + */ + protected function _encodeHeader($value) + { + if (Zend_Mime::isPrintable($value)) { + return $value; + } else { + $quotedValue = Zend_Mime::encodeQuotedPrintable($value); + $quotedValue = str_replace(array('?', ' '), array('=3F', '=20'), $quotedValue); + return '=?' . $this->_charset . '?Q?' . $quotedValue . '?='; + } + } + + /** + * Add a header to the message + * + * Adds a header to this message. If append is true and the header already + * exists, raises a flag indicating that the header should be appended. + * + * @param string $headerName + * @param string $value + * @param boolean $append + */ + protected function _storeHeader($headerName, $value, $append=false) + { +// ?? $value = strtr($value,"\r\n\t",'???'); + if (isset($this->_headers[$headerName])) { + $this->_headers[$headerName][] = $value; + } else { + $this->_headers[$headerName] = array($value); + } + + if ($append) { + $this->_headers[$headerName]['append'] = true; + } + + } + + /** + * Add a recipient + * + * @param string $email + */ + protected function _addRecipient($email, $to = false) + { + // prevent duplicates + $this->_recipients[$email] = 1; + + if ($to) { + $this->_to[] = $email; + } + } + + /** + * Helper function for adding a recipient and the corresponding header + * + * @param string $headerName + * @param string $name + * @param string $email + */ + protected function _addRecipientAndHeader($headerName, $name, $email) + { + $email = strtr($email,"\r\n\t",'???'); + $this->_addRecipient($email, ('To' == $headerName) ? true : false); + if ($name != '') { + $name = '"' . $this->_encodeHeader($name) . '" '; + } + + $this->_storeHeader($headerName, $name .'<'. $email . '>', true); + } + + /** + * Adds To-header and recipient + * + * @param string $name + * @param string $email + * @return Zend_Mail Provides fluent interface + */ + public function addTo($email, $name='') + { + $this->_addRecipientAndHeader('To', $name, $email); + return $this; + } + + /** + * Adds Cc-header and recipient + * + * @param string $name + * @param string $email + * @return Zend_Mail Provides fluent interface + */ + public function addCc($email, $name='') + { + $this->_addRecipientAndHeader('Cc', $name, $email); + return $this; + } + + /** + * Adds Bcc recipient + * + * @param string $email + * @return Zend_Mail Provides fluent interface + */ + public function addBcc($email) + { + $this->_addRecipientAndHeader('Bcc', '', $email); + return $this; + } + + /** + * Return list of recipient email addresses + * + * @return array (of strings) + */ + public function getRecipients() + { + return array_keys($this->_recipients); + } + + /** + * Sets From-header and sender of the message + * + * @param string $email + * @param string $name + * @return Zend_Mail Provides fluent interface + * @throws Zend_Mail_Exception if called subsequent times + */ + public function setFrom($email, $name = '') + { + if ($this->_from === null) { + $email = strtr($email,"\r\n\t",'???'); + $this->_from = $email; + $this->_storeHeader('From', $this->_encodeHeader('"'.$name.'"').' <'.$email.'>', true); + } else { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('From Header set twice'); + } + return $this; + } + + /** + * Returns the sender of the mail + * + * @return string + */ + public function getFrom() + { + return $this->_from; + } + + /** + * Sets the Return-Path header for an email + * + * @param string $email + * @return Zend_Mail Provides fluent interface + * @throws Zend_Mail_Exception if set multiple times + */ + public function setReturnPath($email) + { + if ($this->_returnPath === null) { + $email = strtr($email,"\r\n\t",'???'); + $this->_returnPath = $email; + $this->_storeHeader('Return-Path', $email, false); + } else { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('Return-Path Header set twice'); + } + return $this; + } + + /** + * Returns the current Return-Path address for the email + * + * If no Return-Path header is set, returns the value of {@link $_from}. + * + * @return string + */ + public function getReturnPath() + { + if (null !== $this->_returnPath) { + return $this->_returnPath; + } + + return $this->_from; + } + + /** + * Sets the subject of the message + * + * @param string $subject + * @return Zend_Mail Provides fluent interface + * @throws Zend_Mail_Exception + */ + public function setSubject($subject) + { + if ($this->_subject === null) { + $subject = strtr($subject,"\r\n\t",'???'); + $this->_subject = $this->_encodeHeader($subject); + $this->_storeHeader('Subject', $this->_subject); + } else { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('Subject set twice'); + } + return $this; + } + + /** + * Returns the encoded subject of the message + * + * @return string + */ + public function getSubject() + { + return $this->_subject; + } + + /** + * Sets Date-header + * + * @param string $date + * @return Zend_Mail Provides fluent interface + * @throws Zend_Mail_Exception if called subsequent times + */ + public function setDate($date = null) + { + if ($this->_date === null) { + if ($date === null) { + $date = date('r'); + } else if (is_int($date)) { + $date = date('r', $date); + } else if (is_string($date)) { + $date = strtotime($date); + if ($date === false || $date < 0) { + throw new Zend_Mail_Exception('String representations of Date Header must be ' . + 'strtotime()-compatible'); + } + $date = date('r', $date); + } else if ($date instanceof Zend_Date) { + $date = $date->get(Zend_Date::RFC_2822); + } else { + throw new Zend_Mail_Exception(__METHOD__ . ' only accepts UNIX timestamps, Zend_Date objects, ' . + ' and strtotime()-compatible strings'); + } + $this->_date = $date; + $this->_storeHeader('Date', $date); + } else { + throw new Zend_Mail_Exception('Date Header set twice'); + } + return $this; + } + + /** + * Returns the formatted date of the message + * + * @return string + */ + public function getDate() + { + return $this->_date; + } + + /** + * Add a custom header to the message + * + * @param string $name + * @param string $value + * @param boolean $append + * @return Zend_Mail Provides fluent interface + * @throws Zend_Mail_Exception on attempts to create standard headers + */ + public function addHeader($name, $value, $append = false) + { + if (in_array(strtolower($name), array('to', 'cc', 'bcc', 'from', 'subject', 'return-path', 'date'))) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('Cannot set standard header from addHeader()'); + } + + $value = strtr($value,"\r\n\t",'???'); + $value = $this->_encodeHeader($value); + $this->_storeHeader($name, $value, $append); + + return $this; + } + + /** + * Return mail headers + * + * @return void + */ + public function getHeaders() + { + return $this->_headers; + } + + /** + * Sends this email using the given transport or a previously + * set DefaultTransport or the internal mail function if no + * default transport had been set. + * + * @param Zend_Mail_Transport_Abstract $transport + * @return Zend_Mail Provides fluent interface + */ + public function send($transport = null) + { + if ($transport === null) { + if (! self::$_defaultTransport instanceof Zend_Mail_Transport_Abstract) { + require_once 'Zend/Mail/Transport/Sendmail.php'; + $transport = new Zend_Mail_Transport_Sendmail(); + } else { + $transport = self::$_defaultTransport; + } + } + + if (is_null($this->_date)) { + $this->setDate(); + } + + $transport->send($this); + + return $this; + } + +} diff --git a/libs/Zend/Mail/Exception.php b/libs/Zend/Mail/Exception.php index 742cd607ea..bab758e83d 100644 --- a/libs/Zend/Mail/Exception.php +++ b/libs/Zend/Mail/Exception.php @@ -1,37 +1,37 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Exception
- */
-require_once 'Zend/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Exception extends Zend_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Exception + */ +require_once 'Zend/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Exception extends Zend_Exception +{} + diff --git a/libs/Zend/Mail/Message.php b/libs/Zend/Mail/Message.php index 7236b19c5b..9f4396e8c5 100644 --- a/libs/Zend/Mail/Message.php +++ b/libs/Zend/Mail/Message.php @@ -1,108 +1,108 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Message.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * Zend_Mail_Part
- */
-require_once 'Zend/Mail/Part.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Message extends Zend_Mail_Part
-{
- /**
- * flags for this message
- * @var array
- */
- protected $_flags = array();
-
- /**
- * Public constructor
- *
- * In addition to the parameters of Zend_Mail_Part::__construct() this constructor supports:
- * - file filename or file handle of a file with raw message content
- * - flags array with flags for message, keys are ignored, use constants defined in Zend_Mail_Storage
- *
- * @param string $rawMessage full message with or without headers
- * @throws Zend_Mail_Exception
- */
- public function __construct(array $params)
- {
- if (isset($params['file'])) {
- if (!is_resource($params['file'])) {
- $params['raw'] = @file_get_contents($params['file']);
- if ($params['raw'] === false) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('could not open file');
- }
- } else {
- $params['raw'] = stream_get_contents($params['file']);
- }
- }
-
- if (!empty($params['flags'])) {
- // set key and value to the same value for easy lookup
- $this->_flags = array_combine($params['flags'], $params['flags']);
- }
-
- parent::__construct($params);
- }
-
- /**
- * return toplines as found after headers
- *
- * @return string toplines
- */
- public function getTopLines()
- {
- return $this->_topLines;
- }
-
- /**
- * check if flag is set
- *
- * @param mixed $flag a flag name, use constants defined in Zend_Mail_Storage
- * @return bool true if set, otherwise false
- */
- public function hasFlag($flag)
- {
- return isset($this->_flags[$flag]);
- }
-
- /**
- * get all set flags
- *
- * @return array array with flags, key and value are the same for easy lookup
- */
- public function getFlags()
- {
- return $this->_flags;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Message.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * Zend_Mail_Part + */ +require_once 'Zend/Mail/Part.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Message extends Zend_Mail_Part +{ + /** + * flags for this message + * @var array + */ + protected $_flags = array(); + + /** + * Public constructor + * + * In addition to the parameters of Zend_Mail_Part::__construct() this constructor supports: + * - file filename or file handle of a file with raw message content + * - flags array with flags for message, keys are ignored, use constants defined in Zend_Mail_Storage + * + * @param string $rawMessage full message with or without headers + * @throws Zend_Mail_Exception + */ + public function __construct(array $params) + { + if (isset($params['file'])) { + if (!is_resource($params['file'])) { + $params['raw'] = @file_get_contents($params['file']); + if ($params['raw'] === false) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('could not open file'); + } + } else { + $params['raw'] = stream_get_contents($params['file']); + } + } + + if (!empty($params['flags'])) { + // set key and value to the same value for easy lookup + $this->_flags = array_combine($params['flags'], $params['flags']); + } + + parent::__construct($params); + } + + /** + * return toplines as found after headers + * + * @return string toplines + */ + public function getTopLines() + { + return $this->_topLines; + } + + /** + * check if flag is set + * + * @param mixed $flag a flag name, use constants defined in Zend_Mail_Storage + * @return bool true if set, otherwise false + */ + public function hasFlag($flag) + { + return isset($this->_flags[$flag]); + } + + /** + * get all set flags + * + * @return array array with flags, key and value are the same for easy lookup + */ + public function getFlags() + { + return $this->_flags; + } +} diff --git a/libs/Zend/Mail/Part.php b/libs/Zend/Mail/Part.php index 12c262ae0b..53a9a0a47e 100644 --- a/libs/Zend/Mail/Part.php +++ b/libs/Zend/Mail/Part.php @@ -1,469 +1,469 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Part.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mime_Decode
- */
-require_once 'Zend/Mime/Decode.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Part implements RecursiveIterator
-{
- /**
- * headers of part as array
- * @var null|array
- */
- protected $_headers;
-
- /**
- * raw part body
- * @var null|string
- */
- protected $_content;
-
- /**
- * toplines as fetched with headers
- * @var string
- */
- protected $_topLines = '';
-
- /**
- * parts of multipart message
- * @var array
- */
- protected $_parts = array();
-
- /**
- * count of parts of a multipart message
- * @var null|int
- */
- protected $_countParts;
-
- /**
- * current position of iterator
- * @var int
- */
- protected $_iterationPos = 1;
-
- /**
- * mail handler, if late fetch is active
- * @var null|Zend_Mail_Storage_Abstract
- */
- protected $_mail;
-
- /**
- * message number for mail handler
- * @var int
- */
- protected $_messageNum = 0;
-
- /**
- * Public constructor
- *
- * Zend_Mail_Part supports different sources for content. The possible params are:
- * - handler a instance of Zend_Mail_Storage_Abstract for late fetch
- * - id number of message for handler
- * - raw raw content with header and body as string
- * - headers headers as array (name => value) or string, if a content part is found it's used as toplines
- * - noToplines ignore content found after headers in param 'headers'
- * - content content as string
- *
- * @param array $params full message with or without headers
- * @throws Zend_Mail_Exception
- */
- public function __construct(array $params)
- {
- if (isset($params['handler'])) {
- if (!$params['handler'] instanceof Zend_Mail_Storage_Abstract) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('handler is not a valid mail handler');
- }
- if (!isset($params['id'])) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('need a message id with a handler');
- }
-
- $this->_mail = $params['handler'];
- $this->_messageNum = $params['id'];
- }
-
- if (isset($params['raw'])) {
- Zend_Mime_Decode::splitMessage($params['raw'], $this->_headers, $this->_content);
- } else if (isset($params['headers'])) {
- if (is_array($params['headers'])) {
- $this->_headers = $params['headers'];
- } else {
- if (!empty($params['noToplines'])) {
- Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $null);
- } else {
- Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $this->_topLines);
- }
- }
- if (isset($params['content'])) {
- $this->_content = $params['content'];
- }
- }
- }
-
- /**
- * Check if part is a multipart message
- *
- * @return bool if part is multipart
- */
- public function isMultipart()
- {
- try {
- return stripos($this->contentType, 'multipart/') === 0;
- } catch(Zend_Mail_Exception $e) {
- return false;
- }
- }
-
-
- /**
- * Body of part
- *
- * If part is multipart the raw content of this part with all sub parts is returned
- *
- * @return string body
- * @throws Zend_Mail_Exception
- */
- public function getContent()
- {
- if ($this->_content !== null) {
- return $this->_content;
- }
-
- if ($this->_mail) {
- return $this->_mail->getRawContent($this->_messageNum);
- } else {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('no content');
- }
- }
-
- /**
- * Cache content and split in parts if multipart
- *
- * @return null
- * @throws Zend_Mail_Exception
- */
- protected function _cacheContent()
- {
- // caching content if we can't fetch parts
- if ($this->_content === null && $this->_mail) {
- $this->_content = $this->_mail->getRawContent($this->_messageNum);
- }
-
- if (!$this->isMultipart()) {
- return;
- }
-
- // split content in parts
- $boundary = $this->getHeaderField('content-type', 'boundary');
- if (!$boundary) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('no boundary found in content type to split message');
- }
- $parts = Zend_Mime_Decode::splitMessageStruct($this->_content, $boundary);
- $counter = 1;
- foreach ($parts as $part) {
- $this->_parts[$counter++] = new self(array('headers' => $part['header'], 'content' => $part['body']));
- }
- }
-
- /**
- * Get part of multipart message
- *
- * @param int $num number of part starting with 1 for first part
- * @return Zend_Mail_Part wanted part
- * @throws Zend_Mail_Exception
- */
- public function getPart($num)
- {
- if (isset($this->_parts[$num])) {
- return $this->_parts[$num];
- }
-
- if (!$this->_mail && $this->_content === null) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('part not found');
- }
-
- if ($this->_mail && $this->_mail->hasFetchPart) {
- // TODO: fetch part
- // return
- }
-
- $this->_cacheContent();
-
- if (!isset($this->_parts[$num])) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception('part not found');
- }
-
- return $this->_parts[$num];
- }
-
- /**
- * Count parts of a multipart part
- *
- * @return int number of sub-parts
- */
- public function countParts()
- {
- if ($this->_countParts) {
- return $this->_countParts;
- }
-
- $this->_countParts = count($this->_parts);
- if ($this->_countParts) {
- return $this->_countParts;
- }
-
- if ($this->_mail && $this->_mail->hasFetchPart) {
- // TODO: fetch part
- // return
- }
-
- $this->_cacheContent();
-
- $this->_countParts = count($this->_parts);
- return $this->_countParts;
- }
-
-
- /**
- * Get all headers
- *
- * The returned headers are as saved internally. All names are lowercased. The value is a string or an array
- * if a header with the same name occurs more than once.
- *
- * @return array headers as array(name => value)
- */
- public function getHeaders()
- {
- if ($this->_headers === null) {
- if (!$this->_mail) {
- $this->_headers = array();
- } else {
- $part = $this->_mail->getRawHeader($this->_messageNum);
- Zend_Mime_Decode::splitMessage($part, $this->_headers, $null);
- }
- }
-
- return $this->_headers;
- }
-
- /**
- * Get a header in specificed format
- *
- * Internally headers that occur more than once are saved as array, all other as string. If $format
- * is set to string implode is used to concat the values (with Zend_Mime::LINEEND as delim).
- *
- * @param string $name name of header, matches case-insensitive, but camel-case is replaced with dashes
- * @param string $format change type of return value to 'string' or 'array'
- * @return string|array value of header in wanted or internal format
- * @throws Zend_Mail_Exception
- */
- public function getHeader($name, $format = null)
- {
- if ($this->_headers === null) {
- $this->getHeaders();
- }
-
- $lowerName = strtolower($name);
-
- if (!isset($this->_headers[$lowerName])) {
- $lowerName = strtolower(preg_replace('%([a-z])([A-Z])%', '\1-\2', $name));
- if (!isset($this->_headers[$lowerName])) {
- /**
- * @see Zend_Mail_Exception
- */
- require_once 'Zend/Mail/Exception.php';
- throw new Zend_Mail_Exception("no Header with Name $name found");
- }
- }
- $name = $lowerName;
-
- $header = $this->_headers[$name];
-
- switch ($format) {
- case 'string':
- if (is_array($header)) {
- $header = implode(Zend_Mime::LINEEND, $header);
- }
- break;
- case 'array':
- $header = (array)$header;
- default:
- // do nothing
- }
-
- return $header;
- }
-
- /**
- * Get a specific field from a header like content type or all fields as array
- *
- * If the header occurs more than once, only the value from the first header
- * is returned.
- *
- * Throws a Zend_Mail_Exception if the requested header does not exist. If
- * the specific header field does not exist, returns null.
- *
- * @param string $name name of header, like in getHeader()
- * @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned
- * @param string $firstName key name for the first part
- * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
- * @throws Zend_Exception, Zend_Mail_Exception
- */
- public function getHeaderField($name, $wantedPart = 0, $firstName = 0) {
- return Zend_Mime_Decode::splitHeaderField(current($this->getHeader($name, 'array')), $wantedPart, $firstName);
- }
-
-
- /**
- * Getter for mail headers - name is matched in lowercase
- *
- * This getter is short for Zend_Mail_Part::getHeader($name, 'string')
- *
- * @see Zend_Mail_Part::getHeader()
- *
- * @param string $name header name
- * @return string value of header
- * @throws Zend_Mail_Exception
- */
- public function __get($name)
- {
- return $this->getHeader($name, 'string');
- }
-
- /**
- * magic method to get content of part
- *
- * @return string content
- */
- public function __toString()
- {
- return $this->getContent();
- }
-
- /**
- * implements RecursiveIterator::hasChildren()
- *
- * @return bool current element has children/is multipart
- */
- public function hasChildren()
- {
- $current = $this->current();
- return $current && $current instanceof Zend_Mail_Part && $current->isMultipart();
- }
-
- /**
- * implements RecursiveIterator::getChildren()
- *
- * @return Zend_Mail_Part same as self::current()
- */
- public function getChildren()
- {
- return $this->current();
- }
-
- /**
- * implements Iterator::valid()
- *
- * @return bool check if there's a current element
- */
- public function valid()
- {
- if ($this->_countParts === null) {
- $this->countParts();
- }
- return $this->_iterationPos && $this->_iterationPos <= $this->_countParts;
- }
-
- /**
- * implements Iterator::next()
- *
- * @return null
- */
- public function next()
- {
- ++$this->_iterationPos;
- }
-
- /**
- * implements Iterator::key()
- *
- * @return string key/number of current part
- */
- public function key()
- {
- return $this->_iterationPos;
- }
-
- /**
- * implements Iterator::current()
- *
- * @return Zend_Mail_Part current part
- */
- public function current()
- {
- return $this->getPart($this->_iterationPos);
- }
-
- /**
- * implements Iterator::rewind()
- *
- * @return null
- */
- public function rewind()
- {
- $this->countParts();
- $this->_iterationPos = 1;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Part.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mime_Decode + */ +require_once 'Zend/Mime/Decode.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Part implements RecursiveIterator +{ + /** + * headers of part as array + * @var null|array + */ + protected $_headers; + + /** + * raw part body + * @var null|string + */ + protected $_content; + + /** + * toplines as fetched with headers + * @var string + */ + protected $_topLines = ''; + + /** + * parts of multipart message + * @var array + */ + protected $_parts = array(); + + /** + * count of parts of a multipart message + * @var null|int + */ + protected $_countParts; + + /** + * current position of iterator + * @var int + */ + protected $_iterationPos = 1; + + /** + * mail handler, if late fetch is active + * @var null|Zend_Mail_Storage_Abstract + */ + protected $_mail; + + /** + * message number for mail handler + * @var int + */ + protected $_messageNum = 0; + + /** + * Public constructor + * + * Zend_Mail_Part supports different sources for content. The possible params are: + * - handler a instance of Zend_Mail_Storage_Abstract for late fetch + * - id number of message for handler + * - raw raw content with header and body as string + * - headers headers as array (name => value) or string, if a content part is found it's used as toplines + * - noToplines ignore content found after headers in param 'headers' + * - content content as string + * + * @param array $params full message with or without headers + * @throws Zend_Mail_Exception + */ + public function __construct(array $params) + { + if (isset($params['handler'])) { + if (!$params['handler'] instanceof Zend_Mail_Storage_Abstract) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('handler is not a valid mail handler'); + } + if (!isset($params['id'])) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('need a message id with a handler'); + } + + $this->_mail = $params['handler']; + $this->_messageNum = $params['id']; + } + + if (isset($params['raw'])) { + Zend_Mime_Decode::splitMessage($params['raw'], $this->_headers, $this->_content); + } else if (isset($params['headers'])) { + if (is_array($params['headers'])) { + $this->_headers = $params['headers']; + } else { + if (!empty($params['noToplines'])) { + Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $null); + } else { + Zend_Mime_Decode::splitMessage($params['headers'], $this->_headers, $this->_topLines); + } + } + if (isset($params['content'])) { + $this->_content = $params['content']; + } + } + } + + /** + * Check if part is a multipart message + * + * @return bool if part is multipart + */ + public function isMultipart() + { + try { + return stripos($this->contentType, 'multipart/') === 0; + } catch(Zend_Mail_Exception $e) { + return false; + } + } + + + /** + * Body of part + * + * If part is multipart the raw content of this part with all sub parts is returned + * + * @return string body + * @throws Zend_Mail_Exception + */ + public function getContent() + { + if ($this->_content !== null) { + return $this->_content; + } + + if ($this->_mail) { + return $this->_mail->getRawContent($this->_messageNum); + } else { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('no content'); + } + } + + /** + * Cache content and split in parts if multipart + * + * @return null + * @throws Zend_Mail_Exception + */ + protected function _cacheContent() + { + // caching content if we can't fetch parts + if ($this->_content === null && $this->_mail) { + $this->_content = $this->_mail->getRawContent($this->_messageNum); + } + + if (!$this->isMultipart()) { + return; + } + + // split content in parts + $boundary = $this->getHeaderField('content-type', 'boundary'); + if (!$boundary) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('no boundary found in content type to split message'); + } + $parts = Zend_Mime_Decode::splitMessageStruct($this->_content, $boundary); + $counter = 1; + foreach ($parts as $part) { + $this->_parts[$counter++] = new self(array('headers' => $part['header'], 'content' => $part['body'])); + } + } + + /** + * Get part of multipart message + * + * @param int $num number of part starting with 1 for first part + * @return Zend_Mail_Part wanted part + * @throws Zend_Mail_Exception + */ + public function getPart($num) + { + if (isset($this->_parts[$num])) { + return $this->_parts[$num]; + } + + if (!$this->_mail && $this->_content === null) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('part not found'); + } + + if ($this->_mail && $this->_mail->hasFetchPart) { + // TODO: fetch part + // return + } + + $this->_cacheContent(); + + if (!isset($this->_parts[$num])) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception('part not found'); + } + + return $this->_parts[$num]; + } + + /** + * Count parts of a multipart part + * + * @return int number of sub-parts + */ + public function countParts() + { + if ($this->_countParts) { + return $this->_countParts; + } + + $this->_countParts = count($this->_parts); + if ($this->_countParts) { + return $this->_countParts; + } + + if ($this->_mail && $this->_mail->hasFetchPart) { + // TODO: fetch part + // return + } + + $this->_cacheContent(); + + $this->_countParts = count($this->_parts); + return $this->_countParts; + } + + + /** + * Get all headers + * + * The returned headers are as saved internally. All names are lowercased. The value is a string or an array + * if a header with the same name occurs more than once. + * + * @return array headers as array(name => value) + */ + public function getHeaders() + { + if ($this->_headers === null) { + if (!$this->_mail) { + $this->_headers = array(); + } else { + $part = $this->_mail->getRawHeader($this->_messageNum); + Zend_Mime_Decode::splitMessage($part, $this->_headers, $null); + } + } + + return $this->_headers; + } + + /** + * Get a header in specificed format + * + * Internally headers that occur more than once are saved as array, all other as string. If $format + * is set to string implode is used to concat the values (with Zend_Mime::LINEEND as delim). + * + * @param string $name name of header, matches case-insensitive, but camel-case is replaced with dashes + * @param string $format change type of return value to 'string' or 'array' + * @return string|array value of header in wanted or internal format + * @throws Zend_Mail_Exception + */ + public function getHeader($name, $format = null) + { + if ($this->_headers === null) { + $this->getHeaders(); + } + + $lowerName = strtolower($name); + + if (!isset($this->_headers[$lowerName])) { + $lowerName = strtolower(preg_replace('%([a-z])([A-Z])%', '\1-\2', $name)); + if (!isset($this->_headers[$lowerName])) { + /** + * @see Zend_Mail_Exception + */ + require_once 'Zend/Mail/Exception.php'; + throw new Zend_Mail_Exception("no Header with Name $name found"); + } + } + $name = $lowerName; + + $header = $this->_headers[$name]; + + switch ($format) { + case 'string': + if (is_array($header)) { + $header = implode(Zend_Mime::LINEEND, $header); + } + break; + case 'array': + $header = (array)$header; + default: + // do nothing + } + + return $header; + } + + /** + * Get a specific field from a header like content type or all fields as array + * + * If the header occurs more than once, only the value from the first header + * is returned. + * + * Throws a Zend_Mail_Exception if the requested header does not exist. If + * the specific header field does not exist, returns null. + * + * @param string $name name of header, like in getHeader() + * @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned + * @param string $firstName key name for the first part + * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) + * @throws Zend_Exception, Zend_Mail_Exception + */ + public function getHeaderField($name, $wantedPart = 0, $firstName = 0) { + return Zend_Mime_Decode::splitHeaderField(current($this->getHeader($name, 'array')), $wantedPart, $firstName); + } + + + /** + * Getter for mail headers - name is matched in lowercase + * + * This getter is short for Zend_Mail_Part::getHeader($name, 'string') + * + * @see Zend_Mail_Part::getHeader() + * + * @param string $name header name + * @return string value of header + * @throws Zend_Mail_Exception + */ + public function __get($name) + { + return $this->getHeader($name, 'string'); + } + + /** + * magic method to get content of part + * + * @return string content + */ + public function __toString() + { + return $this->getContent(); + } + + /** + * implements RecursiveIterator::hasChildren() + * + * @return bool current element has children/is multipart + */ + public function hasChildren() + { + $current = $this->current(); + return $current && $current instanceof Zend_Mail_Part && $current->isMultipart(); + } + + /** + * implements RecursiveIterator::getChildren() + * + * @return Zend_Mail_Part same as self::current() + */ + public function getChildren() + { + return $this->current(); + } + + /** + * implements Iterator::valid() + * + * @return bool check if there's a current element + */ + public function valid() + { + if ($this->_countParts === null) { + $this->countParts(); + } + return $this->_iterationPos && $this->_iterationPos <= $this->_countParts; + } + + /** + * implements Iterator::next() + * + * @return null + */ + public function next() + { + ++$this->_iterationPos; + } + + /** + * implements Iterator::key() + * + * @return string key/number of current part + */ + public function key() + { + return $this->_iterationPos; + } + + /** + * implements Iterator::current() + * + * @return Zend_Mail_Part current part + */ + public function current() + { + return $this->getPart($this->_iterationPos); + } + + /** + * implements Iterator::rewind() + * + * @return null + */ + public function rewind() + { + $this->countParts(); + $this->_iterationPos = 1; + } +} diff --git a/libs/Zend/Mail/Protocol/Abstract.php b/libs/Zend/Mail/Protocol/Abstract.php index 06988c184e..5b55a22406 100644 --- a/libs/Zend/Mail/Protocol/Abstract.php +++ b/libs/Zend/Mail/Protocol/Abstract.php @@ -1,385 +1,385 @@ -<?php
-
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Validate
- */
-require_once 'Zend/Validate.php';
-
-
-/**
- * @see Zend_Validate_Hostname
- */
-require_once 'Zend/Validate/Hostname.php';
-
-
-/**
- * Zend_Mail_Protocol_Abstract
- *
- * Provides low-level methods for concrete adapters to communicate with a remote mail server and track requests and responses.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- * @todo Implement proxy settings
- */
-abstract class Zend_Mail_Protocol_Abstract
-{
- /**
- * Mail default EOL string
- */
- const EOL = "\r\n";
-
-
- /**
- * Default timeout in seconds for initiating session
- */
- const TIMEOUT_CONNECTION = 30;
-
-
- /**
- * Hostname or IP address of remote server
- * @var string
- */
- protected $_host;
-
-
- /**
- * Port number of connection
- * @var integer
- */
- protected $_port;
-
-
- /**
- * Instance of Zend_Validate to check hostnames
- * @var Zend_Validate
- */
- protected $_validHost;
-
-
- /**
- * Socket connection resource
- * @var resource
- */
- protected $_socket;
-
-
- /**
- * Last request sent to server
- * @var string
- */
- protected $_request;
-
-
- /**
- * Array of server responses to last request
- * @var array
- */
- protected $_response;
-
-
- /**
- * String template for parsing server responses using sscanf (default: 3 digit code and response string)
- * @var resource
- */
- protected $_template = '%d%s';
-
-
- /**
- * Log of mail requests and server responses for a session
- * @var string
- */
- private $_log;
-
-
- /**
- * Constructor.
- *
- * @param string $host OPTIONAL Hostname of remote connection (default: 127.0.0.1)
- * @param integer $port OPTIONAL Port number (default: null)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null)
- {
- $this->_validHost = new Zend_Validate();
- $this->_validHost->addValidator(new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL));
-
- if (!$this->_validHost->isValid($host)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages()));
- }
-
- $this->_host = $host;
- $this->_port = $port;
- }
-
-
- /**
- * Class destructor to cleanup open resources
- *
- * @return void
- */
- public function __destruct()
- {
- $this->_disconnect();
- }
-
-
- /**
- * Create a connection to the remote host
- *
- * Concrete adapters for this class will implement their own unique connect scripts, using the _connect() method to create the socket resource.
- */
- abstract public function connect();
-
-
- /**
- * Retrieve the last client request
- *
- * @return string
- */
- public function getRequest()
- {
- return $this->_request;
- }
-
-
- /**
- * Retrieve the last server response
- *
- * @return array
- */
- public function getResponse()
- {
- return $this->_response;
- }
-
-
- /**
- * Retrieve the transaction log
- *
- * @return string
- */
- public function getLog()
- {
- return $this->_log;
- }
-
-
- /**
- * Reset the transaction log
- *
- * @return void
- */
- public function resetLog()
- {
- $this->_log = '';
- }
-
-
- /**
- * Connect to the server using the supplied transport and target
- *
- * An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222'
- *
- * @param string $remote Remote
- * @throws Zend_Mail_Protocol_Exception
- * @return boolean
- */
- protected function _connect($remote)
- {
- $errorNum = 0;
- $errorStr = '';
-
- // open connection
- $this->_socket = stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);
-
- if ($this->_socket === false) {
- if ($errorNum == 0) {
- $errorStr = 'Could not open socket';
- }
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($errorStr);
- }
-
- if (($result = stream_set_timeout($this->_socket, self::TIMEOUT_CONNECTION)) === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not set stream timeout');
- }
-
- return $result;
- }
-
-
- /**
- * Disconnect from remote host and free resource
- *
- * @return void
- */
- protected function _disconnect()
- {
- if (is_resource($this->_socket)) {
- fclose($this->_socket);
- }
- }
-
-
- /**
- * Send the given request followed by a LINEEND to the server.
- *
- * @param string $request
- * @throws Zend_Mail_Protocol_Exception
- * @return integer|boolean Number of bytes written to remote host
- */
- protected function _send($request)
- {
- if (!is_resource($this->_socket)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
- }
-
- $this->_request = $request;
-
- $result = fwrite($this->_socket, $request . self::EOL);
-
- // Save request to internal log
- $this->_log .= $request . self::EOL;
-
- if ($result === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host);
- }
-
- return $result;
- }
-
-
- /**
- * Get a line from the stream.
- *
- * @var integer $timeout Per-request timeout value if applicable
- * @throws Zend_Mail_Protocol_Exception
- * @return string
- */
- protected function _receive($timeout = null)
- {
- if (!is_resource($this->_socket)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
- }
-
- // Adapters may wish to supply per-commend timeouts according to appropriate RFC
- if ($timeout !== null) {
- stream_set_timeout($this->_socket, $timeout);
- }
-
- // Retrieve response
- $reponse = fgets($this->_socket, 1024);
-
- // Save request to internal log
- $this->_log .= $reponse;
-
- // Check meta data to ensure connection is still valid
- $info = stream_get_meta_data($this->_socket);
-
- if (!empty($info['timed_out'])) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($this->_host . ' has timed out');
- }
-
- if ($reponse === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host);
- }
-
- return $reponse;
- }
-
-
- /**
- * Parse server response for successful codes
- *
- * Read the response from the stream and check for expected return code.
- * Throws a Zend_Mail_Protocol_Exception if an unexpected code is returned.
- *
- * @param string|array $code One or more codes that indicate a successful response
- * @throws Zend_Mail_Protocol_Exception
- * @return string Last line of response string
- */
- protected function _expect($code, $timeout = null)
- {
- $this->_response = array();
- $cmd = '';
- $msg = '';
-
- if (!is_array($code)) {
- $code = array($code);
- }
-
- do {
- $this->_response[] = $result = $this->_receive($timeout);
- sscanf($result, $this->_template, $cmd, $msg);
-
- if ($cmd === null || !in_array($cmd, $code)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($result);
- }
-
- } while (strpos($msg, '-') === 0); // The '-' message prefix indicates an information string instead of a response string.
-
- return $msg;
- }
-}
+<?php + +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Validate + */ +require_once 'Zend/Validate.php'; + + +/** + * @see Zend_Validate_Hostname + */ +require_once 'Zend/Validate/Hostname.php'; + + +/** + * Zend_Mail_Protocol_Abstract + * + * Provides low-level methods for concrete adapters to communicate with a remote mail server and track requests and responses. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + * @todo Implement proxy settings + */ +abstract class Zend_Mail_Protocol_Abstract +{ + /** + * Mail default EOL string + */ + const EOL = "\r\n"; + + + /** + * Default timeout in seconds for initiating session + */ + const TIMEOUT_CONNECTION = 30; + + + /** + * Hostname or IP address of remote server + * @var string + */ + protected $_host; + + + /** + * Port number of connection + * @var integer + */ + protected $_port; + + + /** + * Instance of Zend_Validate to check hostnames + * @var Zend_Validate + */ + protected $_validHost; + + + /** + * Socket connection resource + * @var resource + */ + protected $_socket; + + + /** + * Last request sent to server + * @var string + */ + protected $_request; + + + /** + * Array of server responses to last request + * @var array + */ + protected $_response; + + + /** + * String template for parsing server responses using sscanf (default: 3 digit code and response string) + * @var resource + */ + protected $_template = '%d%s'; + + + /** + * Log of mail requests and server responses for a session + * @var string + */ + private $_log; + + + /** + * Constructor. + * + * @param string $host OPTIONAL Hostname of remote connection (default: 127.0.0.1) + * @param integer $port OPTIONAL Port number (default: null) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null) + { + $this->_validHost = new Zend_Validate(); + $this->_validHost->addValidator(new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL)); + + if (!$this->_validHost->isValid($host)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages())); + } + + $this->_host = $host; + $this->_port = $port; + } + + + /** + * Class destructor to cleanup open resources + * + * @return void + */ + public function __destruct() + { + $this->_disconnect(); + } + + + /** + * Create a connection to the remote host + * + * Concrete adapters for this class will implement their own unique connect scripts, using the _connect() method to create the socket resource. + */ + abstract public function connect(); + + + /** + * Retrieve the last client request + * + * @return string + */ + public function getRequest() + { + return $this->_request; + } + + + /** + * Retrieve the last server response + * + * @return array + */ + public function getResponse() + { + return $this->_response; + } + + + /** + * Retrieve the transaction log + * + * @return string + */ + public function getLog() + { + return $this->_log; + } + + + /** + * Reset the transaction log + * + * @return void + */ + public function resetLog() + { + $this->_log = ''; + } + + + /** + * Connect to the server using the supplied transport and target + * + * An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222' + * + * @param string $remote Remote + * @throws Zend_Mail_Protocol_Exception + * @return boolean + */ + protected function _connect($remote) + { + $errorNum = 0; + $errorStr = ''; + + // open connection + $this->_socket = stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION); + + if ($this->_socket === false) { + if ($errorNum == 0) { + $errorStr = 'Could not open socket'; + } + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($errorStr); + } + + if (($result = stream_set_timeout($this->_socket, self::TIMEOUT_CONNECTION)) === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not set stream timeout'); + } + + return $result; + } + + + /** + * Disconnect from remote host and free resource + * + * @return void + */ + protected function _disconnect() + { + if (is_resource($this->_socket)) { + fclose($this->_socket); + } + } + + + /** + * Send the given request followed by a LINEEND to the server. + * + * @param string $request + * @throws Zend_Mail_Protocol_Exception + * @return integer|boolean Number of bytes written to remote host + */ + protected function _send($request) + { + if (!is_resource($this->_socket)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host); + } + + $this->_request = $request; + + $result = fwrite($this->_socket, $request . self::EOL); + + // Save request to internal log + $this->_log .= $request . self::EOL; + + if ($result === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host); + } + + return $result; + } + + + /** + * Get a line from the stream. + * + * @var integer $timeout Per-request timeout value if applicable + * @throws Zend_Mail_Protocol_Exception + * @return string + */ + protected function _receive($timeout = null) + { + if (!is_resource($this->_socket)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host); + } + + // Adapters may wish to supply per-commend timeouts according to appropriate RFC + if ($timeout !== null) { + stream_set_timeout($this->_socket, $timeout); + } + + // Retrieve response + $reponse = fgets($this->_socket, 1024); + + // Save request to internal log + $this->_log .= $reponse; + + // Check meta data to ensure connection is still valid + $info = stream_get_meta_data($this->_socket); + + if (!empty($info['timed_out'])) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($this->_host . ' has timed out'); + } + + if ($reponse === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host); + } + + return $reponse; + } + + + /** + * Parse server response for successful codes + * + * Read the response from the stream and check for expected return code. + * Throws a Zend_Mail_Protocol_Exception if an unexpected code is returned. + * + * @param string|array $code One or more codes that indicate a successful response + * @throws Zend_Mail_Protocol_Exception + * @return string Last line of response string + */ + protected function _expect($code, $timeout = null) + { + $this->_response = array(); + $cmd = ''; + $msg = ''; + + if (!is_array($code)) { + $code = array($code); + } + + do { + $this->_response[] = $result = $this->_receive($timeout); + sscanf($result, $this->_template, $cmd, $msg); + + if ($cmd === null || !in_array($cmd, $code)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($result); + } + + } while (strpos($msg, '-') === 0); // The '-' message prefix indicates an information string instead of a response string. + + return $msg; + } +} diff --git a/libs/Zend/Mail/Protocol/Exception.php b/libs/Zend/Mail/Protocol/Exception.php index 928c549a96..c3add11bbb 100644 --- a/libs/Zend/Mail/Protocol/Exception.php +++ b/libs/Zend/Mail/Protocol/Exception.php @@ -1,39 +1,39 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Exception
- */
-require_once 'Zend/Mail/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Exception extends Zend_Mail_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Exception + */ +require_once 'Zend/Mail/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Exception extends Zend_Mail_Exception +{} + diff --git a/libs/Zend/Mail/Protocol/Imap.php b/libs/Zend/Mail/Protocol/Imap.php index 8b78478867..e21a0025c9 100644 --- a/libs/Zend/Mail/Protocol/Imap.php +++ b/libs/Zend/Mail/Protocol/Imap.php @@ -1,805 +1,805 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Imap
-{
- /**
- * socket to imap server
- * @var resource|null
- */
- protected $_socket;
-
- /**
- * counter for request tag
- * @var int
- */
- protected $_tagCount = 0;
-
-
- /**
- * Public constructor
- *
- * @param string $host hostname of IP address of IMAP server, if given connect() is called
- * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl)
- * @param bool $ssl use ssl? 'SSL', 'TLS' or false
- * @throws Zend_Mail_Protocol_Exception
- */
- function __construct($host = '', $port = null, $ssl = false)
- {
- if ($host) {
- $this->connect($host, $port, $ssl);
- }
- }
-
- /**
- * Public destructor
- */
- public function __destruct()
- {
- $this->logout();
- }
-
- /**
- * Open connection to POP3 server
- *
- * @param string $host hostname of IP address of POP3 server
- * @param int|null $port of IMAP server, default is 143 (993 for ssl)
- * @param string|bool $ssl use 'SSL', 'TLS' or false
- * @return string welcome message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function connect($host, $port = null, $ssl = false)
- {
- if ($ssl == 'SSL') {
- $host = 'ssl://' . $host;
- }
-
- if ($port === null) {
- $port = $ssl === 'SSL' ? 993 : 143;
- }
-
- $this->_socket = @fsockopen($host, $port);
- if (!$this->_socket) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot connect to host');
- }
-
- if (!$this->_assumedNextLine('* OK')) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('host doesn\'t allow connection');
- }
-
- if ($ssl === 'TLS') {
- $result = $this->requestAndResponse('STARTTLS');
- $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
- }
- }
- }
-
- /**
- * get the next line from socket with error checking, but nothing else
- *
- * @return string next line
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _nextLine()
- {
- $line = @fgets($this->_socket);
- if ($line === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot read - connection closed?');
- }
-
- return $line;
- }
-
- /**
- * get next line and assume it starts with $start. some requests give a simple
- * feedback so we can quickly check if we can go on.
- *
- * @param string $start the first bytes we assume to be in the next line
- * @return bool line starts with $start
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _assumedNextLine($start)
- {
- $line = $this->_nextLine();
- return strpos($line, $start) === 0;
- }
-
- /**
- * get next line and split the tag. that's the normal case for a response line
- *
- * @param string $tag tag of line is returned by reference
- * @return string next line
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _nextTaggedLine(&$tag)
- {
- $line = $this->_nextLine();
-
- // seperate tag from line
- list($tag, $line) = explode(' ', $line, 2);
-
- return $line;
- }
-
- /**
- * split a given line in tokens. a token is literal of any form or a list
- *
- * @param string $line line to decode
- * @return array tokens, literals are returned as string, lists as array
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _decodeLine($line)
- {
- $tokens = array();
- $stack = array();
-
- /*
- We start to decode the response here. The unterstood tokens are:
- literal
- "literal" or also "lit\\er\"al"
- {bytes}<NL>literal
- (literals*)
- All tokens are returned in an array. Literals in braces (the last unterstood
- token in the list) are returned as an array of tokens. I.e. the following response:
- "foo" baz {3}<NL>bar ("f\\\"oo" bar)
- would be returned as:
- array('foo', 'baz', 'bar', array('f\\\"oo', 'bar'));
-
- // TODO: add handling of '[' and ']' to parser for easier handling of response text
- */
- // replace any trailling <NL> including spaces with a single space
- $line = rtrim($line) . ' ';
- while (($pos = strpos($line, ' ')) !== false) {
- $token = substr($line, 0, $pos);
- while ($token[0] == '(') {
- array_push($stack, $tokens);
- $tokens = array();
- $token = substr($token, 1);
- }
- if ($token[0] == '"') {
- if (preg_match('%^"((.|\\\\|\\")*?)" *%', $line, $matches)) {
- $tokens[] = $matches[1];
- $line = substr($line, strlen($matches[0]));
- continue;
- }
- }
- if ($token[0] == '{') {
- $endPos = strpos($token, '}');
- $chars = substr($token, 1, $endPos - 1);
- if (is_numeric($chars)) {
- $token = '';
- while (strlen($token) < $chars) {
- $token .= $this->_nextLine();
- }
- $line = '';
- if (strlen($token) > $chars) {
- $line = substr($token, $chars);
- $token = substr($token, 0, $chars);
- } else {
- $line .= $this->_nextLine();
- }
- $tokens[] = $token;
- $line = trim($line) . ' ';
- continue;
- }
- }
- if ($stack && $token[strlen($token) - 1] == ')') {
- // closing braces are not seperated by spaces, so we need to count them
- $braces = strlen($token);
- $token = rtrim($token, ')');
- // only count braces if more than one
- $braces -= strlen($token) + 1;
- // only add if token had more than just closing braces
- if ($token) {
- $tokens[] = $token;
- }
- $token = $tokens;
- $tokens = array_pop($stack);
- // special handline if more than one closing brace
- while ($braces-- > 0) {
- $tokens[] = $token;
- $token = $tokens;
- $tokens = array_pop($stack);
- }
- }
- $tokens[] = $token;
- $line = substr($line, $pos + 1);
- }
-
- // maybe the server forgot to send some closing braces
- while ($stack) {
- $child = $tokens;
- $tokens = array_pop($stack);
- $tokens[] = $child;
- }
-
- return $tokens;
- }
-
- /**
- * read a response "line" (could also be more than one real line if response has {..}<NL>)
- * and do a simple decode
- *
- * @param array|string $tokens decoded tokens are returned by reference, if $dontParse
- * is true the unparsed line is returned here
- * @param string $wantedTag check for this tag for response code. Default '*' is
- * continuation tag.
- * @param bool $dontParse if true only the unparsed line is returned $tokens
- * @return bool if returned tag matches wanted tag
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)
- {
- $line = $this->_nextTaggedLine($tag);
- if (!$dontParse) {
- $tokens = $this->_decodeLine($line);
- } else {
- $tokens = $line;
- }
-
- // if tag is wanted tag we might be at the end of a multiline response
- return $tag == $wantedTag;
- }
-
- /**
- * read all lines of response until given tag is found (last line of response)
- *
- * @param string $tag the tag of your request
- * @param string|array $filter you can filter the response so you get only the
- * given response lines
- * @param bool $dontParse if true every line is returned unparsed instead of
- * the decoded tokens
- * @return null|bool|array tokens if success, false if error, null if bad request
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readResponse($tag, $dontParse = false)
- {
- $lines = array();
- while (!$this->readLine($tokens, $tag, $dontParse)) {
- $lines[] = $tokens;
- }
-
- if ($dontParse) {
- // last to chars are still needed for response code
- $tokens = array(substr($tokens, 0, 2));
- }
- // last line has response code
- if ($tokens[0] == 'OK') {
- return $lines ? $lines : true;
- } else if ($tokens[0] == 'NO'){
- return false;
- }
- return null;
- }
-
- /**
- * send a request
- *
- * @param string $command your request command
- * @param array $tokens additional parameters to command, use escapeString() to prepare
- * @param string $tag provide a tag otherwise an autogenerated is returned
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function sendRequest($command, $tokens = array(), &$tag = null)
- {
- if (!$tag) {
- ++$this->_tagCount;
- $tag = 'TAG' . $this->_tagCount;
- }
-
- $line = $tag . ' ' . $command;
-
- foreach ($tokens as $token) {
- if (is_array($token)) {
- if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?');
- }
- if (!$this->_assumedNextLine('+ OK')) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot send literal string');
- }
- $line = $token[1];
- } else {
- $line .= ' ' . $token;
- }
- }
-
- if (@fputs($this->_socket, $line . "\r\n") === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?');
- }
- }
-
- /**
- * send a request and get response at once
- *
- * @param string $command command as in sendRequest()
- * @param array $tokens parameters as in sendRequest()
- * @param bool $dontParse if true unparsed lines are returned instead of tokens
- * @return mixed response as in readResponse()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function requestAndResponse($command, $tokens = array(), $dontParse = false)
- {
- $this->sendRequest($command, $tokens, $tag);
- $response = $this->readResponse($tag, $dontParse);
-
- return $response;
- }
-
- /**
- * escape one or more literals i.e. for sendRequest
- *
- * @param string|array $string the literal/-s
- * @return string|array escape literals, literals with newline ar returned
- * as array('{size}', 'string');
- */
- public function escapeString($string)
- {
- if (func_num_args() < 2) {
- if (strpos($string, "\n") !== false) {
- return array('{' . strlen($string) . '}', $string);
- } else {
- return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"';
- }
- }
- $result = array();
- foreach (func_get_args() as $string) {
- $result[] = $this->escapeString($string);
- }
- return $result;
- }
-
- /**
- * escape a list with literals or lists
- *
- * @param array $list list with literals or lists as PHP array
- * @return string escaped list for imap
- */
- public function escapeList($list)
- {
- $result = array();
- foreach ($list as $k => $v) {
- if (!is_array($v)) {
-// $result[] = $this->escapeString($v);
- $result[] = $v;
- continue;
- }
- $result[] = $this->escapeList($v);
- }
- return '(' . implode(' ', $result) . ')';
- }
-
- /**
- * Login to IMAP server.
- *
- * @param string $user username
- * @param string $password password
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function login($user, $password)
- {
- return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true);
- }
-
- /**
- * logout of imap server
- *
- * @return bool success
- */
- public function logout()
- {
- $result = false;
- if ($this->_socket) {
- try {
- $result = $this->requestAndResponse('LOGOUT', array(), true);
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignoring exception
- }
- fclose($this->_socket);
- $this->_socket = null;
- }
- return $result;
- }
-
-
- /**
- * Get capabilities from IMAP server
- *
- * @return array list of capabilities
- * @throws Zend_Mail_Protocol_Exception
- */
- public function capability()
- {
- $response = $this->requestAndResponse('CAPABILITY');
-
- if (!$response) {
- return $response;
- }
-
- $capabilities = array();
- foreach ($response as $line) {
- $capabilities = array_merge($capabilities, $line);
- }
- return $capabilities;
- }
-
- /**
- * Examine and select have the same response. The common code for both
- * is in this method
- *
- * @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command
- * @param string $box which folder to change to or examine
- * @return bool|array false if error, array with returned information
- * otherwise (flags, exists, recent, uidvalidity)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX')
- {
- $this->sendRequest($command, array($this->escapeString($box)), $tag);
-
- $result = array();
- while (!$this->readLine($tokens, $tag)) {
- if ($tokens[0] == 'FLAGS') {
- array_shift($tokens);
- $result['flags'] = $tokens;
- continue;
- }
- switch ($tokens[1]) {
- case 'EXISTS':
- case 'RECENT':
- $result[strtolower($tokens[1])] = $tokens[0];
- break;
- case '[UIDVALIDITY':
- $result['uidvalidity'] = (int)$tokens[2];
- break;
- default:
- // ignore
- }
- }
-
- if ($tokens[0] != 'OK') {
- return false;
- }
- return $result;
- }
-
- /**
- * change folder
- *
- * @param string $box change to this folder
- * @return bool|array see examineOrselect()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function select($box = 'INBOX')
- {
- return $this->examineOrSelect('SELECT', $box);
- }
-
- /**
- * examine folder
- *
- * @param string $box examine this folder
- * @return bool|array see examineOrselect()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function examine($box = 'INBOX')
- {
- return $this->examineOrSelect('EXAMINE', $box);
- }
-
- /**
- * fetch one or more items of one or more messages
- *
- * @param string|array $items items to fetch from message(s) as string (if only one item)
- * or array of strings
- * @param int $from message for items or start message if $to !== null
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @return string|array if only one item of one message is fetched it's returned as string
- * if items of one message are fetched it's returned as (name => value)
- * if one items of messages are fetched it's returned as (msgno => value)
- * if items of messages are fetchted it's returned as (msgno => (name => value))
- * @throws Zend_Mail_Protocol_Exception
- */
- public function fetch($items, $from, $to = null)
- {
- if (is_array($from)) {
- $set = implode(',', $from);
- } else if ($to === null) {
- $set = (int)$from;
- } else if ($to === INF) {
- $set = (int)$from . ':*';
- } else {
- $set = (int)$from . ':' . (int)$to;
- }
-
- $items = (array)$items;
- $itemList = $this->escapeList($items);
-
- $this->sendRequest('FETCH', array($set, $itemList), $tag);
-
- $result = array();
- while (!$this->readLine($tokens, $tag)) {
- // ignore other responses
- if ($tokens[1] != 'FETCH') {
- continue;
- }
- // ignore other messages
- if ($to === null && !is_array($from) && $tokens[0] != $from) {
- continue;
- }
- // if we only want one item we return that one directly
- if (count($items) == 1) {
- if ($tokens[2][0] == $items[0]) {
- $data = $tokens[2][1];
- } else {
- // maybe the server send an other field we didn't wanted
- $count = count($tokens[2]);
- // we start with 2, because 0 was already checked
- for ($i = 2; $i < $count; $i += 2) {
- if ($tokens[2][$i] != $items[0]) {
- continue;
- }
- $data = $tokens[2][$i + 1];
- break;
- }
- }
- } else {
- $data = array();
- while (key($tokens[2]) !== null) {
- $data[current($tokens[2])] = next($tokens[2]);
- next($tokens[2]);
- }
- }
- // if we want only one message we can ignore everything else and just return
- if ($to === null && !is_array($from) && $tokens[0] == $from) {
- // we still need to read all lines
- while (!$this->readLine($tokens, $tag));
- return $data;
- }
- $result[$tokens[0]] = $data;
- }
-
- if ($to === null && !is_array($from)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('the single id was not found in response');
- }
-
- return $result;
- }
-
- /**
- * get mailbox list
- *
- * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword
- *
- * @param string $reference mailbox reference for list
- * @param string $mailbox mailbox name match with wildcards
- * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..))
- * @throws Zend_Mail_Protocol_Exception
- */
- public function listMailbox($reference = '', $mailbox = '*')
- {
- $result = array();
- $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox));
- if (!$list) {
- return $result;
- }
-
- foreach ($list as $item) {
- if (count($item) != 4 || $item[0] != 'LIST') {
- continue;
- }
- $result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]);
- }
-
- return $result;
- }
-
- /**
- * set flags
- *
- * @param array $flags flags to set, add or remove - see $mode
- * @param int $from message for items or start message if $to !== null
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
- * @param bool $silent if false the return values are the new flags for the wanted messages
- * @return bool|array new flags if $silent is false, else true or false depending on success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function store(array $flags, $from, $to = null, $mode = null, $silent = true)
- {
- $item = 'FLAGS';
- if ($mode == '+' || $mode == '-') {
- $item = $mode . $item;
- }
- if ($silent) {
- $item .= '.SILENT';
- }
-
- $flags = $this->escapeList($flags);
- $set = (int)$from;
- if ($to != null) {
- $set .= ':' . ($to == INF ? '*' : (int)$to);
- }
-
- $result = $this->requestAndResponse('STORE', array($set, $item, $flags), $silent);
-
- if ($silent) {
- return $result ? true : false;
- }
-
- $tokens = $result;
- $result = array();
- foreach ($tokens as $token) {
- if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') {
- continue;
- }
- $result[$token[0]] = $token[2][1];
- }
-
- return $result;
- }
-
- /**
- * append a new message to given folder
- *
- * @param string $folder name of target folder
- * @param string $message full message content
- * @param array $flags flags for new message
- * @param string $date date for new message
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function append($folder, $message, $flags = null, $date = null)
- {
- $tokens = array();
- $tokens[] = $this->escapeString($folder);
- if ($flags !== null) {
- $tokens[] = $this->escapeList($flags);
- }
- if ($date !== null) {
- $tokens[] = $this->escapeString($date);
- }
- $tokens[] = $this->escapeString($message);
-
- return $this->requestAndResponse('APPEND', $tokens, true);
- }
-
- /**
- * copy message set from current folder to other folder
- *
- * @param string $folder destination folder
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function copy($folder, $from, $to = null)
- {
- $set = (int)$from;
- if ($to != null) {
- $set .= ':' . ($to == INF ? '*' : (int)$to);
- }
-
- return $this->requestAndResponse('COPY', array($set, $this->escapeString($folder)), true);
- }
-
- /**
- * create a new folder (and parent folders if needed)
- *
- * @param string $folder folder name
- * @return bool success
- */
- public function create($folder)
- {
- return $this->requestAndResponse('CREATE', array($this->escapeString($folder)), true);
- }
-
- /**
- * rename an existing folder
- *
- * @param string $old old name
- * @param string $new new name
- * @return bool success
- */
- public function rename($old, $new)
- {
- return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true);
- }
-
- /**
- * remove a folder
- *
- * @param string $folder folder name
- * @return bool success
- */
- public function delete($folder)
- {
- return $this->requestAndResponse('DELETE', array($this->escapeString($folder)), true);
- }
-
- /**
- * permanently remove messages
- *
- * @return bool success
- */
- public function expunge()
- {
- // TODO: parse response?
- return $this->requestAndResponse('EXPUNGE');
- }
-
- /**
- * send noop
- *
- * @return bool success
- */
- public function noop()
- {
- // TODO: parse response
- return $this->requestAndResponse('NOOP');
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Imap +{ + /** + * socket to imap server + * @var resource|null + */ + protected $_socket; + + /** + * counter for request tag + * @var int + */ + protected $_tagCount = 0; + + + /** + * Public constructor + * + * @param string $host hostname of IP address of IMAP server, if given connect() is called + * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl) + * @param bool $ssl use ssl? 'SSL', 'TLS' or false + * @throws Zend_Mail_Protocol_Exception + */ + function __construct($host = '', $port = null, $ssl = false) + { + if ($host) { + $this->connect($host, $port, $ssl); + } + } + + /** + * Public destructor + */ + public function __destruct() + { + $this->logout(); + } + + /** + * Open connection to POP3 server + * + * @param string $host hostname of IP address of POP3 server + * @param int|null $port of IMAP server, default is 143 (993 for ssl) + * @param string|bool $ssl use 'SSL', 'TLS' or false + * @return string welcome message + * @throws Zend_Mail_Protocol_Exception + */ + public function connect($host, $port = null, $ssl = false) + { + if ($ssl == 'SSL') { + $host = 'ssl://' . $host; + } + + if ($port === null) { + $port = $ssl === 'SSL' ? 993 : 143; + } + + $this->_socket = @fsockopen($host, $port); + if (!$this->_socket) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot connect to host'); + } + + if (!$this->_assumedNextLine('* OK')) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('host doesn\'t allow connection'); + } + + if ($ssl === 'TLS') { + $result = $this->requestAndResponse('STARTTLS'); + $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot enable TLS'); + } + } + } + + /** + * get the next line from socket with error checking, but nothing else + * + * @return string next line + * @throws Zend_Mail_Protocol_Exception + */ + protected function _nextLine() + { + $line = @fgets($this->_socket); + if ($line === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot read - connection closed?'); + } + + return $line; + } + + /** + * get next line and assume it starts with $start. some requests give a simple + * feedback so we can quickly check if we can go on. + * + * @param string $start the first bytes we assume to be in the next line + * @return bool line starts with $start + * @throws Zend_Mail_Protocol_Exception + */ + protected function _assumedNextLine($start) + { + $line = $this->_nextLine(); + return strpos($line, $start) === 0; + } + + /** + * get next line and split the tag. that's the normal case for a response line + * + * @param string $tag tag of line is returned by reference + * @return string next line + * @throws Zend_Mail_Protocol_Exception + */ + protected function _nextTaggedLine(&$tag) + { + $line = $this->_nextLine(); + + // seperate tag from line + list($tag, $line) = explode(' ', $line, 2); + + return $line; + } + + /** + * split a given line in tokens. a token is literal of any form or a list + * + * @param string $line line to decode + * @return array tokens, literals are returned as string, lists as array + * @throws Zend_Mail_Protocol_Exception + */ + protected function _decodeLine($line) + { + $tokens = array(); + $stack = array(); + + /* + We start to decode the response here. The unterstood tokens are: + literal + "literal" or also "lit\\er\"al" + {bytes}<NL>literal + (literals*) + All tokens are returned in an array. Literals in braces (the last unterstood + token in the list) are returned as an array of tokens. I.e. the following response: + "foo" baz {3}<NL>bar ("f\\\"oo" bar) + would be returned as: + array('foo', 'baz', 'bar', array('f\\\"oo', 'bar')); + + // TODO: add handling of '[' and ']' to parser for easier handling of response text + */ + // replace any trailling <NL> including spaces with a single space + $line = rtrim($line) . ' '; + while (($pos = strpos($line, ' ')) !== false) { + $token = substr($line, 0, $pos); + while ($token[0] == '(') { + array_push($stack, $tokens); + $tokens = array(); + $token = substr($token, 1); + } + if ($token[0] == '"') { + if (preg_match('%^"((.|\\\\|\\")*?)" *%', $line, $matches)) { + $tokens[] = $matches[1]; + $line = substr($line, strlen($matches[0])); + continue; + } + } + if ($token[0] == '{') { + $endPos = strpos($token, '}'); + $chars = substr($token, 1, $endPos - 1); + if (is_numeric($chars)) { + $token = ''; + while (strlen($token) < $chars) { + $token .= $this->_nextLine(); + } + $line = ''; + if (strlen($token) > $chars) { + $line = substr($token, $chars); + $token = substr($token, 0, $chars); + } else { + $line .= $this->_nextLine(); + } + $tokens[] = $token; + $line = trim($line) . ' '; + continue; + } + } + if ($stack && $token[strlen($token) - 1] == ')') { + // closing braces are not seperated by spaces, so we need to count them + $braces = strlen($token); + $token = rtrim($token, ')'); + // only count braces if more than one + $braces -= strlen($token) + 1; + // only add if token had more than just closing braces + if ($token) { + $tokens[] = $token; + } + $token = $tokens; + $tokens = array_pop($stack); + // special handline if more than one closing brace + while ($braces-- > 0) { + $tokens[] = $token; + $token = $tokens; + $tokens = array_pop($stack); + } + } + $tokens[] = $token; + $line = substr($line, $pos + 1); + } + + // maybe the server forgot to send some closing braces + while ($stack) { + $child = $tokens; + $tokens = array_pop($stack); + $tokens[] = $child; + } + + return $tokens; + } + + /** + * read a response "line" (could also be more than one real line if response has {..}<NL>) + * and do a simple decode + * + * @param array|string $tokens decoded tokens are returned by reference, if $dontParse + * is true the unparsed line is returned here + * @param string $wantedTag check for this tag for response code. Default '*' is + * continuation tag. + * @param bool $dontParse if true only the unparsed line is returned $tokens + * @return bool if returned tag matches wanted tag + * @throws Zend_Mail_Protocol_Exception + */ + public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false) + { + $line = $this->_nextTaggedLine($tag); + if (!$dontParse) { + $tokens = $this->_decodeLine($line); + } else { + $tokens = $line; + } + + // if tag is wanted tag we might be at the end of a multiline response + return $tag == $wantedTag; + } + + /** + * read all lines of response until given tag is found (last line of response) + * + * @param string $tag the tag of your request + * @param string|array $filter you can filter the response so you get only the + * given response lines + * @param bool $dontParse if true every line is returned unparsed instead of + * the decoded tokens + * @return null|bool|array tokens if success, false if error, null if bad request + * @throws Zend_Mail_Protocol_Exception + */ + public function readResponse($tag, $dontParse = false) + { + $lines = array(); + while (!$this->readLine($tokens, $tag, $dontParse)) { + $lines[] = $tokens; + } + + if ($dontParse) { + // last to chars are still needed for response code + $tokens = array(substr($tokens, 0, 2)); + } + // last line has response code + if ($tokens[0] == 'OK') { + return $lines ? $lines : true; + } else if ($tokens[0] == 'NO'){ + return false; + } + return null; + } + + /** + * send a request + * + * @param string $command your request command + * @param array $tokens additional parameters to command, use escapeString() to prepare + * @param string $tag provide a tag otherwise an autogenerated is returned + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function sendRequest($command, $tokens = array(), &$tag = null) + { + if (!$tag) { + ++$this->_tagCount; + $tag = 'TAG' . $this->_tagCount; + } + + $line = $tag . ' ' . $command; + + foreach ($tokens as $token) { + if (is_array($token)) { + if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); + } + if (!$this->_assumedNextLine('+ OK')) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot send literal string'); + } + $line = $token[1]; + } else { + $line .= ' ' . $token; + } + } + + if (@fputs($this->_socket, $line . "\r\n") === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); + } + } + + /** + * send a request and get response at once + * + * @param string $command command as in sendRequest() + * @param array $tokens parameters as in sendRequest() + * @param bool $dontParse if true unparsed lines are returned instead of tokens + * @return mixed response as in readResponse() + * @throws Zend_Mail_Protocol_Exception + */ + public function requestAndResponse($command, $tokens = array(), $dontParse = false) + { + $this->sendRequest($command, $tokens, $tag); + $response = $this->readResponse($tag, $dontParse); + + return $response; + } + + /** + * escape one or more literals i.e. for sendRequest + * + * @param string|array $string the literal/-s + * @return string|array escape literals, literals with newline ar returned + * as array('{size}', 'string'); + */ + public function escapeString($string) + { + if (func_num_args() < 2) { + if (strpos($string, "\n") !== false) { + return array('{' . strlen($string) . '}', $string); + } else { + return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"'; + } + } + $result = array(); + foreach (func_get_args() as $string) { + $result[] = $this->escapeString($string); + } + return $result; + } + + /** + * escape a list with literals or lists + * + * @param array $list list with literals or lists as PHP array + * @return string escaped list for imap + */ + public function escapeList($list) + { + $result = array(); + foreach ($list as $k => $v) { + if (!is_array($v)) { +// $result[] = $this->escapeString($v); + $result[] = $v; + continue; + } + $result[] = $this->escapeList($v); + } + return '(' . implode(' ', $result) . ')'; + } + + /** + * Login to IMAP server. + * + * @param string $user username + * @param string $password password + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function login($user, $password) + { + return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true); + } + + /** + * logout of imap server + * + * @return bool success + */ + public function logout() + { + $result = false; + if ($this->_socket) { + try { + $result = $this->requestAndResponse('LOGOUT', array(), true); + } catch (Zend_Mail_Protocol_Exception $e) { + // ignoring exception + } + fclose($this->_socket); + $this->_socket = null; + } + return $result; + } + + + /** + * Get capabilities from IMAP server + * + * @return array list of capabilities + * @throws Zend_Mail_Protocol_Exception + */ + public function capability() + { + $response = $this->requestAndResponse('CAPABILITY'); + + if (!$response) { + return $response; + } + + $capabilities = array(); + foreach ($response as $line) { + $capabilities = array_merge($capabilities, $line); + } + return $capabilities; + } + + /** + * Examine and select have the same response. The common code for both + * is in this method + * + * @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command + * @param string $box which folder to change to or examine + * @return bool|array false if error, array with returned information + * otherwise (flags, exists, recent, uidvalidity) + * @throws Zend_Mail_Protocol_Exception + */ + public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX') + { + $this->sendRequest($command, array($this->escapeString($box)), $tag); + + $result = array(); + while (!$this->readLine($tokens, $tag)) { + if ($tokens[0] == 'FLAGS') { + array_shift($tokens); + $result['flags'] = $tokens; + continue; + } + switch ($tokens[1]) { + case 'EXISTS': + case 'RECENT': + $result[strtolower($tokens[1])] = $tokens[0]; + break; + case '[UIDVALIDITY': + $result['uidvalidity'] = (int)$tokens[2]; + break; + default: + // ignore + } + } + + if ($tokens[0] != 'OK') { + return false; + } + return $result; + } + + /** + * change folder + * + * @param string $box change to this folder + * @return bool|array see examineOrselect() + * @throws Zend_Mail_Protocol_Exception + */ + public function select($box = 'INBOX') + { + return $this->examineOrSelect('SELECT', $box); + } + + /** + * examine folder + * + * @param string $box examine this folder + * @return bool|array see examineOrselect() + * @throws Zend_Mail_Protocol_Exception + */ + public function examine($box = 'INBOX') + { + return $this->examineOrSelect('EXAMINE', $box); + } + + /** + * fetch one or more items of one or more messages + * + * @param string|array $items items to fetch from message(s) as string (if only one item) + * or array of strings + * @param int $from message for items or start message if $to !== null + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @return string|array if only one item of one message is fetched it's returned as string + * if items of one message are fetched it's returned as (name => value) + * if one items of messages are fetched it's returned as (msgno => value) + * if items of messages are fetchted it's returned as (msgno => (name => value)) + * @throws Zend_Mail_Protocol_Exception + */ + public function fetch($items, $from, $to = null) + { + if (is_array($from)) { + $set = implode(',', $from); + } else if ($to === null) { + $set = (int)$from; + } else if ($to === INF) { + $set = (int)$from . ':*'; + } else { + $set = (int)$from . ':' . (int)$to; + } + + $items = (array)$items; + $itemList = $this->escapeList($items); + + $this->sendRequest('FETCH', array($set, $itemList), $tag); + + $result = array(); + while (!$this->readLine($tokens, $tag)) { + // ignore other responses + if ($tokens[1] != 'FETCH') { + continue; + } + // ignore other messages + if ($to === null && !is_array($from) && $tokens[0] != $from) { + continue; + } + // if we only want one item we return that one directly + if (count($items) == 1) { + if ($tokens[2][0] == $items[0]) { + $data = $tokens[2][1]; + } else { + // maybe the server send an other field we didn't wanted + $count = count($tokens[2]); + // we start with 2, because 0 was already checked + for ($i = 2; $i < $count; $i += 2) { + if ($tokens[2][$i] != $items[0]) { + continue; + } + $data = $tokens[2][$i + 1]; + break; + } + } + } else { + $data = array(); + while (key($tokens[2]) !== null) { + $data[current($tokens[2])] = next($tokens[2]); + next($tokens[2]); + } + } + // if we want only one message we can ignore everything else and just return + if ($to === null && !is_array($from) && $tokens[0] == $from) { + // we still need to read all lines + while (!$this->readLine($tokens, $tag)); + return $data; + } + $result[$tokens[0]] = $data; + } + + if ($to === null && !is_array($from)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('the single id was not found in response'); + } + + return $result; + } + + /** + * get mailbox list + * + * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword + * + * @param string $reference mailbox reference for list + * @param string $mailbox mailbox name match with wildcards + * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..)) + * @throws Zend_Mail_Protocol_Exception + */ + public function listMailbox($reference = '', $mailbox = '*') + { + $result = array(); + $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox)); + if (!$list) { + return $result; + } + + foreach ($list as $item) { + if (count($item) != 4 || $item[0] != 'LIST') { + continue; + } + $result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]); + } + + return $result; + } + + /** + * set flags + * + * @param array $flags flags to set, add or remove - see $mode + * @param int $from message for items or start message if $to !== null + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given + * @param bool $silent if false the return values are the new flags for the wanted messages + * @return bool|array new flags if $silent is false, else true or false depending on success + * @throws Zend_Mail_Protocol_Exception + */ + public function store(array $flags, $from, $to = null, $mode = null, $silent = true) + { + $item = 'FLAGS'; + if ($mode == '+' || $mode == '-') { + $item = $mode . $item; + } + if ($silent) { + $item .= '.SILENT'; + } + + $flags = $this->escapeList($flags); + $set = (int)$from; + if ($to != null) { + $set .= ':' . ($to == INF ? '*' : (int)$to); + } + + $result = $this->requestAndResponse('STORE', array($set, $item, $flags), $silent); + + if ($silent) { + return $result ? true : false; + } + + $tokens = $result; + $result = array(); + foreach ($tokens as $token) { + if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') { + continue; + } + $result[$token[0]] = $token[2][1]; + } + + return $result; + } + + /** + * append a new message to given folder + * + * @param string $folder name of target folder + * @param string $message full message content + * @param array $flags flags for new message + * @param string $date date for new message + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function append($folder, $message, $flags = null, $date = null) + { + $tokens = array(); + $tokens[] = $this->escapeString($folder); + if ($flags !== null) { + $tokens[] = $this->escapeList($flags); + } + if ($date !== null) { + $tokens[] = $this->escapeString($date); + } + $tokens[] = $this->escapeString($message); + + return $this->requestAndResponse('APPEND', $tokens, true); + } + + /** + * copy message set from current folder to other folder + * + * @param string $folder destination folder + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function copy($folder, $from, $to = null) + { + $set = (int)$from; + if ($to != null) { + $set .= ':' . ($to == INF ? '*' : (int)$to); + } + + return $this->requestAndResponse('COPY', array($set, $this->escapeString($folder)), true); + } + + /** + * create a new folder (and parent folders if needed) + * + * @param string $folder folder name + * @return bool success + */ + public function create($folder) + { + return $this->requestAndResponse('CREATE', array($this->escapeString($folder)), true); + } + + /** + * rename an existing folder + * + * @param string $old old name + * @param string $new new name + * @return bool success + */ + public function rename($old, $new) + { + return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true); + } + + /** + * remove a folder + * + * @param string $folder folder name + * @return bool success + */ + public function delete($folder) + { + return $this->requestAndResponse('DELETE', array($this->escapeString($folder)), true); + } + + /** + * permanently remove messages + * + * @return bool success + */ + public function expunge() + { + // TODO: parse response? + return $this->requestAndResponse('EXPUNGE'); + } + + /** + * send noop + * + * @return bool success + */ + public function noop() + { + // TODO: parse response + return $this->requestAndResponse('NOOP'); + } +} diff --git a/libs/Zend/Mail/Protocol/Pop3.php b/libs/Zend/Mail/Protocol/Pop3.php index e9a7a2275d..55d2704569 100644 --- a/libs/Zend/Mail/Protocol/Pop3.php +++ b/libs/Zend/Mail/Protocol/Pop3.php @@ -1,461 +1,461 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Pop3
-{
- /**
- * saves if server supports top
- * @var null|bool
- */
- public $hasTop = null;
-
- /**
- * socket to pop3
- * @var null|resource
- */
- protected $_socket;
-
- /**
- * greeting timestamp for apop
- * @var null|string
- */
- protected $_timestamp;
-
-
- /**
- * Public constructor
- *
- * @param string $host hostname of IP address of POP3 server, if given connect() is called
- * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl)
- * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($host = '', $port = null, $ssl = false)
- {
- if ($host) {
- $this->connect($host, $port, $ssl);
- }
- }
-
-
- /**
- * Public destructor
- */
- public function __destruct()
- {
- $this->logout();
- }
-
-
- /**
- * Open connection to POP3 server
- *
- * @param string $host hostname of IP address of POP3 server
- * @param int|null $port of POP3 server, default is 110 (995 for ssl)
- * @param string|bool $ssl use 'SSL', 'TLS' or false
- * @return string welcome message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function connect($host, $port = null, $ssl = false)
- {
- if ($ssl == 'SSL') {
- $host = 'ssl://' . $host;
- }
-
- if ($port === null) {
- $port = $ssl == 'SSL' ? 995 : 110;
- }
-
- $this->_socket = @fsockopen($host, $port);
- if (!$this->_socket) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot connect to host');
- }
-
- $welcome = $this->readResponse();
-
- strtok($welcome, '<');
- $this->_timestamp = strtok('>');
- if (!strpos($this->_timestamp, '@')) {
- $this->_timestamp = null;
- } else {
- $this->_timestamp = '<' . $this->_timestamp . '>';
- }
-
- if ($ssl === 'TLS') {
- $this->request('STLS');
- $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
- }
- }
-
- return $welcome;
- }
-
-
- /**
- * Send a request
- *
- * @param string $request your request without newline
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function sendRequest($request)
- {
- $result = @fputs($this->_socket, $request . "\r\n");
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('send failed - connection closed?');
- }
- }
-
-
- /**
- * read a response
- *
- * @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
- * @return string response
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readResponse($multiline = false)
- {
- $result = @fgets($this->_socket);
- if (!is_string($result)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('read failed - connection closed?');
- }
-
- $result = trim($result);
- if (strpos($result, ' ')) {
- list($status, $message) = explode(' ', $result, 2);
- } else {
- $status = $result;
- $message = '';
- }
-
- if ($status != '+OK') {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('last request failed');
- }
-
- if ($multiline) {
- $message = '';
- $line = fgets($this->_socket);
- while ($line && trim($line) != '.') {
- $message .= $line;
- $line = fgets($this->_socket);
- };
- }
-
- return $message;
- }
-
-
- /**
- * Send request and get resposne
- *
- * @see sendRequest(), readResponse()
- *
- * @param string $request request
- * @param bool $multiline multiline response?
- * @return string result from readResponse()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function request($request, $multiline = false)
- {
- $this->sendRequest($request);
- return $this->readResponse($multiline);
- }
-
-
- /**
- * End communication with POP3 server (also closes socket)
- *
- * @return null
- */
- public function logout()
- {
- if (!$this->_socket) {
- return;
- }
-
- try {
- $this->request('QUIT');
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignore error - we're closing the socket anyway
- }
-
- fclose($this->_socket);
- $this->_socket = null;
- }
-
-
- /**
- * Get capabilities from POP3 server
- *
- * @return array list of capabilities
- * @throws Zend_Mail_Protocol_Exception
- */
- public function capa()
- {
- $result = $this->request('CAPA', true);
- return explode("\n", $result);
- }
-
-
- /**
- * Login to POP3 server. Can use APOP
- *
- * @param string $user username
- * @param string $password password
- * @param bool $try_apop should APOP be tried?
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function login($user, $password, $tryApop = true)
- {
- if ($tryApop && $this->_timestamp) {
- try {
- $this->request("APOP $user " . md5($this->_timestamp . $password));
- return;
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignore
- }
- }
-
- $result = $this->request("USER $user");
- $result = $this->request("PASS $password");
- }
-
-
- /**
- * Make STAT call for message count and size sum
- *
- * @param int $messages out parameter with count of messages
- * @param int $octets out parameter with size in octects of messages
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function status(&$messages, &$octets)
- {
- $messages = 0;
- $octets = 0;
- $result = $this->request('STAT');
-
- list($messages, $octets) = explode(' ', $result);
- }
-
-
- /**
- * Make LIST call for size of message(s)
- *
- * @param int|null $msgno number of message, null for all
- * @return int|array size of given message or list with array(num => size)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getList($msgno = null)
- {
- if ($msgno !== null) {
- $result = $this->request("LIST $msgno");
-
- list(, $result) = explode(' ', $result);
- return (int)$result;
- }
-
- $result = $this->request('LIST', true);
- $messages = array();
- $line = strtok($result, "\n");
- while ($line) {
- list($no, $size) = explode(' ', trim($line));
- $messages[(int)$no] = (int)$size;
- $line = strtok("\n");
- }
-
- return $messages;
- }
-
-
- /**
- * Make UIDL call for getting a uniqueid
- *
- * @param int|null $msgno number of message, null for all
- * @return string|array uniqueid of message or list with array(num => uniqueid)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function uniqueid($msgno = null)
- {
- if ($msgno !== null) {
- $result = $this->request("UIDL $msgno");
-
- list(, $result) = explode(' ', $result);
- return $result;
- }
-
- $result = $this->request('UIDL', true);
-
- $result = explode("\n", $result);
- $messages = array();
- foreach ($result as $line) {
- if (!$line) {
- continue;
- }
- list($no, $id) = explode(' ', trim($line), 2);
- $messages[(int)$no] = $id;
- }
-
- return $messages;
-
- }
-
-
- /**
- * Make TOP call for getting headers and maybe some body lines
- * This method also sets hasTop - before it it's not known if top is supported
- *
- * The fallback makes normale RETR call, which retrieves the whole message. Additional
- * lines are not removed.
- *
- * @param int $msgno number of message
- * @param int $lines number of wanted body lines (empty line is inserted after header lines)
- * @param bool $fallback fallback with full retrieve if top is not supported
- * @return string message headers with wanted body lines
- * @throws Zend_Mail_Protocol_Exception
- */
- public function top($msgno, $lines = 0, $fallback = false)
- {
- if ($this->hasTop === false) {
- if ($fallback) {
- return $this->retrieve($msgno);
- } else {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
- }
- }
- $this->hasTop = true;
-
- $lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
-
- try {
- $result = $this->request("TOP $msgno $lines", true);
- } catch (Zend_Mail_Protocol_Exception $e) {
- $this->hasTop = false;
- if ($fallback) {
- $result = $this->retrieve($msgno);
- } else {
- throw $e;
- }
- }
-
- return $result;
- }
-
-
- /**
- * Make a RETR call for retrieving a full message with headers and body
- *
- * @deprecated since 1.1.0; this method has a typo - please use retrieve()
- * @param int $msgno message number
- * @return string message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function retrive($msgno)
- {
- return $this->retrieve($msgno);
- }
-
-
- /**
- * Make a RETR call for retrieving a full message with headers and body
- *
- * @param int $msgno message number
- * @return string message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function retrieve($msgno)
- {
- $result = $this->request("RETR $msgno", true);
- return $result;
- }
-
- /**
- * Make a NOOP call, maybe needed for keeping the server happy
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function noop()
- {
- $this->request('NOOP');
- }
-
-
- /**
- * Make a DELE count to remove a message
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function delete($msgno)
- {
- $this->request("DELE $msgno");
- }
-
-
- /**
- * Make RSET call, which rollbacks delete requests
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function undelete()
- {
- $this->request('RSET');
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Pop3 +{ + /** + * saves if server supports top + * @var null|bool + */ + public $hasTop = null; + + /** + * socket to pop3 + * @var null|resource + */ + protected $_socket; + + /** + * greeting timestamp for apop + * @var null|string + */ + protected $_timestamp; + + + /** + * Public constructor + * + * @param string $host hostname of IP address of POP3 server, if given connect() is called + * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl) + * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($host = '', $port = null, $ssl = false) + { + if ($host) { + $this->connect($host, $port, $ssl); + } + } + + + /** + * Public destructor + */ + public function __destruct() + { + $this->logout(); + } + + + /** + * Open connection to POP3 server + * + * @param string $host hostname of IP address of POP3 server + * @param int|null $port of POP3 server, default is 110 (995 for ssl) + * @param string|bool $ssl use 'SSL', 'TLS' or false + * @return string welcome message + * @throws Zend_Mail_Protocol_Exception + */ + public function connect($host, $port = null, $ssl = false) + { + if ($ssl == 'SSL') { + $host = 'ssl://' . $host; + } + + if ($port === null) { + $port = $ssl == 'SSL' ? 995 : 110; + } + + $this->_socket = @fsockopen($host, $port); + if (!$this->_socket) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot connect to host'); + } + + $welcome = $this->readResponse(); + + strtok($welcome, '<'); + $this->_timestamp = strtok('>'); + if (!strpos($this->_timestamp, '@')) { + $this->_timestamp = null; + } else { + $this->_timestamp = '<' . $this->_timestamp . '>'; + } + + if ($ssl === 'TLS') { + $this->request('STLS'); + $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot enable TLS'); + } + } + + return $welcome; + } + + + /** + * Send a request + * + * @param string $request your request without newline + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function sendRequest($request) + { + $result = @fputs($this->_socket, $request . "\r\n"); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('send failed - connection closed?'); + } + } + + + /** + * read a response + * + * @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>" + * @return string response + * @throws Zend_Mail_Protocol_Exception + */ + public function readResponse($multiline = false) + { + $result = @fgets($this->_socket); + if (!is_string($result)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('read failed - connection closed?'); + } + + $result = trim($result); + if (strpos($result, ' ')) { + list($status, $message) = explode(' ', $result, 2); + } else { + $status = $result; + $message = ''; + } + + if ($status != '+OK') { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('last request failed'); + } + + if ($multiline) { + $message = ''; + $line = fgets($this->_socket); + while ($line && trim($line) != '.') { + $message .= $line; + $line = fgets($this->_socket); + }; + } + + return $message; + } + + + /** + * Send request and get resposne + * + * @see sendRequest(), readResponse() + * + * @param string $request request + * @param bool $multiline multiline response? + * @return string result from readResponse() + * @throws Zend_Mail_Protocol_Exception + */ + public function request($request, $multiline = false) + { + $this->sendRequest($request); + return $this->readResponse($multiline); + } + + + /** + * End communication with POP3 server (also closes socket) + * + * @return null + */ + public function logout() + { + if (!$this->_socket) { + return; + } + + try { + $this->request('QUIT'); + } catch (Zend_Mail_Protocol_Exception $e) { + // ignore error - we're closing the socket anyway + } + + fclose($this->_socket); + $this->_socket = null; + } + + + /** + * Get capabilities from POP3 server + * + * @return array list of capabilities + * @throws Zend_Mail_Protocol_Exception + */ + public function capa() + { + $result = $this->request('CAPA', true); + return explode("\n", $result); + } + + + /** + * Login to POP3 server. Can use APOP + * + * @param string $user username + * @param string $password password + * @param bool $try_apop should APOP be tried? + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function login($user, $password, $tryApop = true) + { + if ($tryApop && $this->_timestamp) { + try { + $this->request("APOP $user " . md5($this->_timestamp . $password)); + return; + } catch (Zend_Mail_Protocol_Exception $e) { + // ignore + } + } + + $result = $this->request("USER $user"); + $result = $this->request("PASS $password"); + } + + + /** + * Make STAT call for message count and size sum + * + * @param int $messages out parameter with count of messages + * @param int $octets out parameter with size in octects of messages + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function status(&$messages, &$octets) + { + $messages = 0; + $octets = 0; + $result = $this->request('STAT'); + + list($messages, $octets) = explode(' ', $result); + } + + + /** + * Make LIST call for size of message(s) + * + * @param int|null $msgno number of message, null for all + * @return int|array size of given message or list with array(num => size) + * @throws Zend_Mail_Protocol_Exception + */ + public function getList($msgno = null) + { + if ($msgno !== null) { + $result = $this->request("LIST $msgno"); + + list(, $result) = explode(' ', $result); + return (int)$result; + } + + $result = $this->request('LIST', true); + $messages = array(); + $line = strtok($result, "\n"); + while ($line) { + list($no, $size) = explode(' ', trim($line)); + $messages[(int)$no] = (int)$size; + $line = strtok("\n"); + } + + return $messages; + } + + + /** + * Make UIDL call for getting a uniqueid + * + * @param int|null $msgno number of message, null for all + * @return string|array uniqueid of message or list with array(num => uniqueid) + * @throws Zend_Mail_Protocol_Exception + */ + public function uniqueid($msgno = null) + { + if ($msgno !== null) { + $result = $this->request("UIDL $msgno"); + + list(, $result) = explode(' ', $result); + return $result; + } + + $result = $this->request('UIDL', true); + + $result = explode("\n", $result); + $messages = array(); + foreach ($result as $line) { + if (!$line) { + continue; + } + list($no, $id) = explode(' ', trim($line), 2); + $messages[(int)$no] = $id; + } + + return $messages; + + } + + + /** + * Make TOP call for getting headers and maybe some body lines + * This method also sets hasTop - before it it's not known if top is supported + * + * The fallback makes normale RETR call, which retrieves the whole message. Additional + * lines are not removed. + * + * @param int $msgno number of message + * @param int $lines number of wanted body lines (empty line is inserted after header lines) + * @param bool $fallback fallback with full retrieve if top is not supported + * @return string message headers with wanted body lines + * @throws Zend_Mail_Protocol_Exception + */ + public function top($msgno, $lines = 0, $fallback = false) + { + if ($this->hasTop === false) { + if ($fallback) { + return $this->retrieve($msgno); + } else { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted'); + } + } + $this->hasTop = true; + + $lines = (!$lines || $lines < 1) ? 0 : (int)$lines; + + try { + $result = $this->request("TOP $msgno $lines", true); + } catch (Zend_Mail_Protocol_Exception $e) { + $this->hasTop = false; + if ($fallback) { + $result = $this->retrieve($msgno); + } else { + throw $e; + } + } + + return $result; + } + + + /** + * Make a RETR call for retrieving a full message with headers and body + * + * @deprecated since 1.1.0; this method has a typo - please use retrieve() + * @param int $msgno message number + * @return string message + * @throws Zend_Mail_Protocol_Exception + */ + public function retrive($msgno) + { + return $this->retrieve($msgno); + } + + + /** + * Make a RETR call for retrieving a full message with headers and body + * + * @param int $msgno message number + * @return string message + * @throws Zend_Mail_Protocol_Exception + */ + public function retrieve($msgno) + { + $result = $this->request("RETR $msgno", true); + return $result; + } + + /** + * Make a NOOP call, maybe needed for keeping the server happy + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function noop() + { + $this->request('NOOP'); + } + + + /** + * Make a DELE count to remove a message + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function delete($msgno) + { + $this->request("DELE $msgno"); + } + + + /** + * Make RSET call, which rollbacks delete requests + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function undelete() + { + $this->request('RSET'); + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp.php b/libs/Zend/Mail/Protocol/Smtp.php index e804d1b1a5..baae3253f0 100644 --- a/libs/Zend/Mail/Protocol/Smtp.php +++ b/libs/Zend/Mail/Protocol/Smtp.php @@ -1,443 +1,443 @@ -<?php
-
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-
-/**
- * @see Zend_Mail_Protocol_Abstract
- */
-require_once 'Zend/Mail/Protocol/Abstract.php';
-
-
-/**
- * Smtp implementation of Zend_Mail_Protocol_Abstract
- *
- * Minimum implementation according to RFC2821: EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp extends Zend_Mail_Protocol_Abstract
-{
- /**
- * The transport method for the socket
- *
- * @var string
- */
- protected $_transport = 'tcp';
-
-
- /**
- * Indicates that a session is requested to be secure
- *
- * @var string
- */
- protected $_secure;
-
-
- /**
- * Indicates an smtp session has been started by the HELO command
- *
- * @var boolean
- */
- protected $_sess = false;
-
-
- /**
- * Indicates the HELO command has been issues
- *
- * @var unknown_type
- */
- protected $_helo = false;
-
-
- /**
- * Indicates an smtp AUTH has been issued and authenticated
- *
- * @var unknown_type
- */
- protected $_auth = false;
-
-
- /**
- * Indicates a MAIL command has been issued
- *
- * @var unknown_type
- */
- protected $_mail = false;
-
-
- /**
- * Indicates one or more RCTP commands have been issued
- *
- * @var unknown_type
- */
- protected $_rcpt = false;
-
-
- /**
- * Indicates that DATA has been issued and sent
- *
- * @var unknown_type
- */
- protected $_data = null;
-
-
- /**
- * Constructor.
- *
- * @param string $host
- * @param integer $port
- * @param array $config
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($host = '127.0.0.1', $port = null, array $config = array())
- {
- if (isset($config['ssl'])) {
- switch (strtolower($config['ssl'])) {
- case 'tls':
- $this->_secure = 'tls';
- break;
-
- case 'ssl':
- $this->_transport = 'ssl';
- $this->_secure = 'ssl';
- if ($port == null) {
- $port = 465;
- }
- break;
-
- default:
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($config['ssl'] . ' is unsupported SSL type');
- break;
- }
- }
-
- // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null.
- if ($port == null) {
- if (($port = ini_get('smtp_port')) == '') {
- $port = 25;
- }
- }
-
- parent::__construct($host, $port);
- }
-
-
- /**
- * Connect to the server with the parameters given in the constructor.
- *
- * @return boolean
- */
- public function connect()
- {
- return $this->_connect($this->_transport . '://' . $this->_host . ':'. $this->_port);
- }
-
-
- /**
- * Initiate HELO/EHLO sequence and set flag to indicate valid smtp session
- *
- * @param string $host The client hostname or IP address (default: 127.0.0.1)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function helo($host = '127.0.0.1')
- {
- // Respect RFC 2821 and disallow HELO attempts if session is already initiated.
- if ($this->_sess === true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Cannot issue HELO to existing session');
- }
-
- // Validate client hostname
- if (!$this->_validHost->isValid($host)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessage()));
- }
-
- // Initiate helo sequence
- $this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_ehlo($host);
-
- // If a TLS session is required, commence negotiation
- if ($this->_secure == 'tls') {
- $this->_send('STARTTLS');
- $this->_expect(220, 180);
- if (!stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Unable to connect via TLS');
- }
- $this->_ehlo($host);
- }
-
- $this->_startSession();
- $this->auth();
- }
-
-
- /**
- * Send EHLO or HELO depending on capabilities of smtp host
- *
- * @param string $host The client hostname or IP address (default: 127.0.0.1)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- protected function _ehlo($host)
- {
- // Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO.
- try {
- $this->_send('EHLO ' . $host);
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- } catch (Zend_Mail_Protocol_Exception $e) {
- $this->_send('HELO ' . $host);
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- } catch (Zend_Mail_Protocol_Exception $e) {
- throw $e;
- }
- }
-
-
- /**
- * Issues MAIL command
- *
- * @param string $from Sender mailbox
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function mail($from)
- {
- if ($this->_sess !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('A valid session has not been started');
- }
-
- $this->_send('MAIL FROM:<' . $from . '>');
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
-
- // Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821
- $this->_mail = true;
- $this->_rcpt = false;
- $this->_data = false;
- }
-
-
- /**
- * Issues RCPT command
- *
- * @param string $to Receiver(s) mailbox
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function rcpt($to)
- {
- if ($this->_mail !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No sender reverse path has been supplied');
- }
-
- // Set rcpt to true, as per 4.1.1.3 of RFC 2821
- $this->_send('RCPT TO:<' . $to . '>');
- $this->_expect(array(250, 251), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_rcpt = true;
- }
-
-
- /**
- * Issues DATA command
- *
- * @param string $data
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function data($data)
- {
- // Ensure recipients have been set
- if ($this->_rcpt !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No recipient forward path has been supplied');
- }
-
- $this->_send('DATA');
- $this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2
-
- foreach (explode(Zend_Mime::LINEEND, $data) as $line) {
- if (strpos($line, '.') === 0) {
- // Escape lines prefixed with a '.'
- $line = '.' . $line;
- }
- $this->_send($line);
- }
-
- $this->_send('.');
- $this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2
- $this->_data = true;
- }
-
-
- /**
- * Issues the RSET command end validates answer
- *
- * Can be used to restore a clean smtp communication state when a transaction has been cancelled or commencing a new transaction.
- *
- * @return void
- */
- public function rset()
- {
- $this->_send('RSET');
- // MS ESMTP doesn't follow RFC, see [ZF-1377]
- $this->_expect(array(250, 220));
-
- $this->_mail = false;
- $this->_rcpt = false;
- $this->_data = false;
- }
-
-
- /**
- * Issues the NOOP command end validates answer
- *
- * Not used by Zend_Mail, could be used to keep a connection alive or check if it is still open.
- *
- * @return void
- */
- public function noop()
- {
- $this->_send('NOOP');
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- }
-
-
- /**
- * Issues the VRFY command end validates answer
- *
- * Not used by Zend_Mail.
- *
- * @param string $user User Name or eMail to verify
- * @return void
- */
- public function vrfy($user)
- {
- $this->_send('VRFY ' . $user);
- $this->_expect(array(250, 251, 252), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- }
-
-
- /**
- * Issues the QUIT command and clears the current session
- *
- * @return void
- */
- public function quit()
- {
- if ($this->_sess) {
- $this->_send('QUIT');
- $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_stopSession();
- }
- }
-
-
- /**
- * Default authentication method
- *
- * This default method is implemented by AUTH adapters to properly authenticate to a remote host.
- *
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function auth()
- {
- if ($this->_auth === true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Already authenticated for this session');
- }
- }
-
-
- /**
- * Closes connection
- *
- * @return void
- */
- public function disconnect()
- {
- $this->_disconnect();
- }
-
-
- /**
- * Start mail session
- *
- * @return void
- */
- protected function _startSession()
- {
- $this->_sess = true;
- }
-
-
- /**
- * Stop mail session
- *
- * @return void
- */
- protected function _stopSession()
- {
- $this->_sess = false;
- }
-}
+<?php + +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + + +/** + * @see Zend_Mail_Protocol_Abstract + */ +require_once 'Zend/Mail/Protocol/Abstract.php'; + + +/** + * Smtp implementation of Zend_Mail_Protocol_Abstract + * + * Minimum implementation according to RFC2821: EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp extends Zend_Mail_Protocol_Abstract +{ + /** + * The transport method for the socket + * + * @var string + */ + protected $_transport = 'tcp'; + + + /** + * Indicates that a session is requested to be secure + * + * @var string + */ + protected $_secure; + + + /** + * Indicates an smtp session has been started by the HELO command + * + * @var boolean + */ + protected $_sess = false; + + + /** + * Indicates the HELO command has been issues + * + * @var unknown_type + */ + protected $_helo = false; + + + /** + * Indicates an smtp AUTH has been issued and authenticated + * + * @var unknown_type + */ + protected $_auth = false; + + + /** + * Indicates a MAIL command has been issued + * + * @var unknown_type + */ + protected $_mail = false; + + + /** + * Indicates one or more RCTP commands have been issued + * + * @var unknown_type + */ + protected $_rcpt = false; + + + /** + * Indicates that DATA has been issued and sent + * + * @var unknown_type + */ + protected $_data = null; + + + /** + * Constructor. + * + * @param string $host + * @param integer $port + * @param array $config + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($host = '127.0.0.1', $port = null, array $config = array()) + { + if (isset($config['ssl'])) { + switch (strtolower($config['ssl'])) { + case 'tls': + $this->_secure = 'tls'; + break; + + case 'ssl': + $this->_transport = 'ssl'; + $this->_secure = 'ssl'; + if ($port == null) { + $port = 465; + } + break; + + default: + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($config['ssl'] . ' is unsupported SSL type'); + break; + } + } + + // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null. + if ($port == null) { + if (($port = ini_get('smtp_port')) == '') { + $port = 25; + } + } + + parent::__construct($host, $port); + } + + + /** + * Connect to the server with the parameters given in the constructor. + * + * @return boolean + */ + public function connect() + { + return $this->_connect($this->_transport . '://' . $this->_host . ':'. $this->_port); + } + + + /** + * Initiate HELO/EHLO sequence and set flag to indicate valid smtp session + * + * @param string $host The client hostname or IP address (default: 127.0.0.1) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function helo($host = '127.0.0.1') + { + // Respect RFC 2821 and disallow HELO attempts if session is already initiated. + if ($this->_sess === true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Cannot issue HELO to existing session'); + } + + // Validate client hostname + if (!$this->_validHost->isValid($host)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessage())); + } + + // Initiate helo sequence + $this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_ehlo($host); + + // If a TLS session is required, commence negotiation + if ($this->_secure == 'tls') { + $this->_send('STARTTLS'); + $this->_expect(220, 180); + if (!stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Unable to connect via TLS'); + } + $this->_ehlo($host); + } + + $this->_startSession(); + $this->auth(); + } + + + /** + * Send EHLO or HELO depending on capabilities of smtp host + * + * @param string $host The client hostname or IP address (default: 127.0.0.1) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + protected function _ehlo($host) + { + // Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO. + try { + $this->_send('EHLO ' . $host); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } catch (Zend_Mail_Protocol_Exception $e) { + $this->_send('HELO ' . $host); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } catch (Zend_Mail_Protocol_Exception $e) { + throw $e; + } + } + + + /** + * Issues MAIL command + * + * @param string $from Sender mailbox + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function mail($from) + { + if ($this->_sess !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('A valid session has not been started'); + } + + $this->_send('MAIL FROM:<' . $from . '>'); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + + // Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821 + $this->_mail = true; + $this->_rcpt = false; + $this->_data = false; + } + + + /** + * Issues RCPT command + * + * @param string $to Receiver(s) mailbox + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function rcpt($to) + { + if ($this->_mail !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No sender reverse path has been supplied'); + } + + // Set rcpt to true, as per 4.1.1.3 of RFC 2821 + $this->_send('RCPT TO:<' . $to . '>'); + $this->_expect(array(250, 251), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_rcpt = true; + } + + + /** + * Issues DATA command + * + * @param string $data + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function data($data) + { + // Ensure recipients have been set + if ($this->_rcpt !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No recipient forward path has been supplied'); + } + + $this->_send('DATA'); + $this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2 + + foreach (explode(Zend_Mime::LINEEND, $data) as $line) { + if (strpos($line, '.') === 0) { + // Escape lines prefixed with a '.' + $line = '.' . $line; + } + $this->_send($line); + } + + $this->_send('.'); + $this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2 + $this->_data = true; + } + + + /** + * Issues the RSET command end validates answer + * + * Can be used to restore a clean smtp communication state when a transaction has been cancelled or commencing a new transaction. + * + * @return void + */ + public function rset() + { + $this->_send('RSET'); + // MS ESMTP doesn't follow RFC, see [ZF-1377] + $this->_expect(array(250, 220)); + + $this->_mail = false; + $this->_rcpt = false; + $this->_data = false; + } + + + /** + * Issues the NOOP command end validates answer + * + * Not used by Zend_Mail, could be used to keep a connection alive or check if it is still open. + * + * @return void + */ + public function noop() + { + $this->_send('NOOP'); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } + + + /** + * Issues the VRFY command end validates answer + * + * Not used by Zend_Mail. + * + * @param string $user User Name or eMail to verify + * @return void + */ + public function vrfy($user) + { + $this->_send('VRFY ' . $user); + $this->_expect(array(250, 251, 252), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } + + + /** + * Issues the QUIT command and clears the current session + * + * @return void + */ + public function quit() + { + if ($this->_sess) { + $this->_send('QUIT'); + $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_stopSession(); + } + } + + + /** + * Default authentication method + * + * This default method is implemented by AUTH adapters to properly authenticate to a remote host. + * + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function auth() + { + if ($this->_auth === true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Already authenticated for this session'); + } + } + + + /** + * Closes connection + * + * @return void + */ + public function disconnect() + { + $this->_disconnect(); + } + + + /** + * Start mail session + * + * @return void + */ + protected function _startSession() + { + $this->_sess = true; + } + + + /** + * Stop mail session + * + * @return void + */ + protected function _stopSession() + { + $this->_sess = false; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php index d23d0e0e1f..337c7ebc98 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php @@ -1,108 +1,108 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Crammd5.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs CRAM-MD5 authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Zend_Mail_Protocol_Smtp
-{
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * @todo Perform CRAM-MD5 authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH CRAM-MD5');
- $challenge = $this->_expect(334);
- $challenge = base64_decode($challenge);
- $digest = $this->_hmacMd5($this->_password, $challenge);
- $this->_send(base64_encode($this->_username . ' ' . $digest));
- $this->_expect(235);
- $this->_auth = true;
- }
-
-
- /**
- * Prepare CRAM-MD5 response to server's ticket
- *
- * @param string $key Challenge key (usually password)
- * @param string $data Challenge data
- * @param string $block Length of blocks
- * @return string
- */
- protected function _hmacMd5($key, $data, $block = 64)
- {
- if (strlen($key) > 64) {
- $key = pack('H32', md5($key));
- } elseif (strlen($key) < 64) {
- $key = str_pad($key, $block, chr(0));
- }
-
- $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
- $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
-
- $inner = pack('H32', md5($k_ipad . $data));
- $digest = md5($k_opad . $inner);
-
- return $digest;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Crammd5.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs CRAM-MD5 authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Zend_Mail_Protocol_Smtp +{ + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * @todo Perform CRAM-MD5 authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH CRAM-MD5'); + $challenge = $this->_expect(334); + $challenge = base64_decode($challenge); + $digest = $this->_hmacMd5($this->_password, $challenge); + $this->_send(base64_encode($this->_username . ' ' . $digest)); + $this->_expect(235); + $this->_auth = true; + } + + + /** + * Prepare CRAM-MD5 response to server's ticket + * + * @param string $key Challenge key (usually password) + * @param string $data Challenge data + * @param string $block Length of blocks + * @return string + */ + protected function _hmacMd5($key, $data, $block = 64) + { + if (strlen($key) > 64) { + $key = pack('H32', md5($key)); + } elseif (strlen($key) < 64) { + $key = str_pad($key, $block, chr(0)); + } + + $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); + $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); + + $inner = pack('H32', md5($k_ipad . $data)); + $digest = md5($k_opad . $inner); + + return $digest; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php index dead2ace33..6332207199 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php @@ -1,98 +1,98 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Login.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs LOGIN authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Login extends Zend_Mail_Protocol_Smtp
-{
- /**
- * LOGIN username
- *
- * @var string
- */
- protected $_username;
-
-
- /**
- * LOGIN password
- *
- * @var string
- */
- protected $_password;
-
-
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * Perform LOGIN authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH LOGIN');
- $this->_expect(334);
- $this->_send(base64_encode($this->_username));
- $this->_expect(334);
- $this->_send(base64_encode($this->_password));
- $this->_expect(235);
- $this->_auth = true;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Login.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs LOGIN authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Login extends Zend_Mail_Protocol_Smtp +{ + /** + * LOGIN username + * + * @var string + */ + protected $_username; + + + /** + * LOGIN password + * + * @var string + */ + protected $_password; + + + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * Perform LOGIN authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH LOGIN'); + $this->_expect(334); + $this->_send(base64_encode($this->_username)); + $this->_expect(334); + $this->_send(base64_encode($this->_password)); + $this->_expect(235); + $this->_auth = true; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php index 5a85c996c8..cb8d019770 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php @@ -1,96 +1,96 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Plain.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs PLAIN authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Plain extends Zend_Mail_Protocol_Smtp
-{
- /**
- * PLAIN username
- *
- * @var string
- */
- protected $_username;
-
-
- /**
- * PLAIN password
- *
- * @var string
- */
- protected $_password;
-
-
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * Perform PLAIN authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH PLAIN');
- $this->_expect(334);
- $this->_send(base64_encode(chr(0) . $this->_username . chr(0) . $this->_password));
- $this->_expect(235);
- $this->_auth = true;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Plain.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs PLAIN authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Plain extends Zend_Mail_Protocol_Smtp +{ + /** + * PLAIN username + * + * @var string + */ + protected $_username; + + + /** + * PLAIN password + * + * @var string + */ + protected $_password; + + + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * Perform PLAIN authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH PLAIN'); + $this->_expect(334); + $this->_send(base64_encode(chr(0) . $this->_username . chr(0) . $this->_password)); + $this->_expect(235); + $this->_auth = true; + } +} diff --git a/libs/Zend/Mail/Storage.php b/libs/Zend/Mail/Storage.php index b2d0df80e0..4f6c1883b2 100644 --- a/libs/Zend/Mail/Storage.php +++ b/libs/Zend/Mail/Storage.php @@ -1,39 +1,39 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Storage.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage
-{
- // maildir and IMAP flags, using IMAP names, where possible to be able to distinguish between IMAP
- // system flags and other flags
- const FLAG_PASSED = 'Passed';
- const FLAG_SEEN = '\Seen';
- const FLAG_ANSWERED = '\Answered';
- const FLAG_FLAGGED = '\Flagged';
- const FLAG_DELETED = '\Deleted';
- const FLAG_DRAFT = '\Draft';
- const FLAG_RECENT = '\Recent';
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Storage.php 8064 2008-02-16 10:58:39Z thomas $ + */ + +/** + * @category Zend + * @package Zend_Mail + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage +{ + // maildir and IMAP flags, using IMAP names, where possible to be able to distinguish between IMAP + // system flags and other flags + const FLAG_PASSED = 'Passed'; + const FLAG_SEEN = '\Seen'; + const FLAG_ANSWERED = '\Answered'; + const FLAG_FLAGGED = '\Flagged'; + const FLAG_DELETED = '\Deleted'; + const FLAG_DRAFT = '\Draft'; + const FLAG_RECENT = '\Recent'; +} diff --git a/libs/Zend/Mail/Storage/Abstract.php b/libs/Zend/Mail/Storage/Abstract.php index 783a41386b..d25f2548cc 100644 --- a/libs/Zend/Mail/Storage/Abstract.php +++ b/libs/Zend/Mail/Storage/Abstract.php @@ -1,366 +1,366 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-abstract class Zend_Mail_Storage_Abstract implements Countable, ArrayAccess, SeekableIterator
-{
- /**
- * class capabilities with default values
- * @var array
- */
- protected $_has = array('uniqueid' => true,
- 'delete' => false,
- 'create' => false,
- 'top' => false,
- 'fetchPart' => true,
- 'flags' => false);
-
- /**
- * current iteration position
- * @var int
- */
- protected $_iterationPos = 0;
-
- /**
- * maximum iteration position (= message count)
- * @var null|int
- */
- protected $_iterationMax = null;
-
- /**
- * used message class, change it in an extened class to extend the returned message class
- * @var string
- */
- protected $_messageClass = 'Zend_Mail_Message';
-
- /**
- * Getter for has-properties. The standard has properties
- * are: hasFolder, hasUniqueid, hasDelete, hasCreate, hasTop
- *
- * The valid values for the has-properties are:
- * - true if a feature is supported
- * - false if a feature is not supported
- * - null is it's not yet known or it can't be know if a feature is supported
- *
- * @param string $var property name
- * @return bool supported or not
- * @throws Zend_Mail_Storage_Exception
- */
- public function __get($var)
- {
- if (strpos($var, 'has') === 0) {
- $var = strtolower(substr($var, 3));
- return isset($this->_has[$var]) ? $this->_has[$var] : null;
- }
-
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception($var . ' not found');
- }
-
-
- /**
- * Get a full list of features supported by the specific mail lib and the server
- *
- * @return array list of features as array(featurename => true|false[|null])
- */
- public function getCapabilities()
- {
- return $this->_has;
- }
-
-
- /**
- * Count messages messages in current box/folder
- *
- * @return int number of messages
- * @throws Zend_Mail_Storage_Exception
- */
- abstract public function countMessages();
-
-
- /**
- * Get a list of messages with number and size
- *
- * @param int $id number of message
- * @return int|array size of given message of list with all messages as array(num => size)
- */
- abstract public function getSize($id = 0);
-
-
- /**
- * Get a message with headers and body
- *
- * @param $id int number of message
- * @return Zend_Mail_Message
- */
- abstract public function getMessage($id);
-
-
- /**
- * Get raw header of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage header
- * @param int $topLines include this many lines with header (after an empty line)
- * @return string raw header
- */
- abstract public function getRawHeader($id, $part = null, $topLines = 0);
-
- /**
- * Get raw content of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage content
- * @return string raw content
- */
- abstract public function getRawContent($id, $part = null);
-
- /**
- * Create instance with parameters
- *
- * @param array $params mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- */
- abstract public function __construct($params);
-
-
- /**
- * Destructor calls close() and therefore closes the resource.
- */
- public function __destruct()
- {
- $this->close();
- }
-
-
- /**
- * Close resource for mail lib. If you need to control, when the resource
- * is closed. Otherwise the destructor would call this.
- *
- * @return null
- */
- abstract public function close();
-
-
- /**
- * Keep the resource alive.
- *
- * @return null
- */
- abstract public function noop();
-
- /**
- * delete a message from current box/folder
- *
- * @return null
- */
- abstract public function removeMessage($id);
-
- /**
- * get unique id for one or all messages
- *
- * if storage does not support unique ids it's the same as the message number
- *
- * @param int|null $id message number
- * @return array|string message number for given message or all messages as array
- * @throws Zend_Mail_Storage_Exception
- */
- abstract public function getUniqueId($id = null);
-
- /**
- * get a message number from a unique id
- *
- * I.e. if you have a webmailer that supports deleting messages you should use unique ids
- * as parameter and use this method to translate it to message number right before calling removeMessage()
- *
- * @param string $id unique id
- * @return int message number
- * @throws Zend_Mail_Storage_Exception
- */
- abstract public function getNumberByUniqueId($id);
-
- // interface implementations follows
-
- /**
- * Countable::count()
- *
- * @return int
- */
- public function count()
- {
- return $this->countMessages();
- }
-
-
- /**
- * ArrayAccess::offsetExists()
- *
- * @param int $id
- * @return boolean
- */
- public function offsetExists($id)
- {
- try {
- if ($this->getMessage($id)) {
- return true;
- }
- } catch(Zend_Mail_Storage_Exception $e) {}
-
- return false;
- }
-
-
- /**
- * ArrayAccess::offsetGet()
- *
- * @param int $id
- * @return Zend_Mail_Message message object
- */
- public function offsetGet($id)
- {
- return $this->getMessage($id);
- }
-
-
- /**
- * ArrayAccess::offsetSet()
- *
- * @param id $id
- * @param mixed $value
- * @throws Zend_Mail_Storage_Exception
- * @return void
- */
- public function offsetSet($id, $value)
- {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot write mail messages via array access');
- }
-
-
- /**
- * ArrayAccess::offsetUnset()
- *
- * @param int $id
- * @return boolean success
- */
- public function offsetUnset($id)
- {
- return $this->removeMessage($id);
- }
-
-
- /**
- * Iterator::rewind()
- *
- * Rewind always gets the new count from the storage. Thus if you use
- * the interfaces and your scripts take long you should use reset()
- * from time to time.
- *
- * @return void
- */
- public function rewind()
- {
- $this->_iterationMax = $this->countMessages();
- $this->_iterationPos = 1;
- }
-
-
- /**
- * Iterator::current()
- *
- * @return Zend_Mail_Message current message
- */
- public function current()
- {
- return $this->getMessage($this->_iterationPos);
- }
-
-
- /**
- * Iterator::key()
- *
- * @return int id of current position
- */
- public function key()
- {
- return $this->_iterationPos;
- }
-
-
- /**
- * Iterator::next()
- *
- * @return void
- */
- public function next()
- {
- ++$this->_iterationPos;
- }
-
-
- /**
- * Iterator::valid()
- *
- * @return boolean
- */
- public function valid()
- {
- if ($this->_iterationMax === null) {
- $this->_iterationMax = $this->countMessages();
- }
- return $this->_iterationPos && $this->_iterationPos <= $this->_iterationMax;
- }
-
-
- /**
- * SeekableIterator::seek()
- *
- * @param int $pos
- * @return void
- * @throws OutOfBoundsException
- */
- public function seek($pos)
- {
- if ($this->_iterationMax === null) {
- $this->_iterationMax = $this->countMessages();
- }
-
- if ($pos > $this->_iterationMax) {
- throw new OutOfBoundsException('this position does not exist');
- }
- $this->_iterationPos = $pos;
- }
-
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +abstract class Zend_Mail_Storage_Abstract implements Countable, ArrayAccess, SeekableIterator +{ + /** + * class capabilities with default values + * @var array + */ + protected $_has = array('uniqueid' => true, + 'delete' => false, + 'create' => false, + 'top' => false, + 'fetchPart' => true, + 'flags' => false); + + /** + * current iteration position + * @var int + */ + protected $_iterationPos = 0; + + /** + * maximum iteration position (= message count) + * @var null|int + */ + protected $_iterationMax = null; + + /** + * used message class, change it in an extened class to extend the returned message class + * @var string + */ + protected $_messageClass = 'Zend_Mail_Message'; + + /** + * Getter for has-properties. The standard has properties + * are: hasFolder, hasUniqueid, hasDelete, hasCreate, hasTop + * + * The valid values for the has-properties are: + * - true if a feature is supported + * - false if a feature is not supported + * - null is it's not yet known or it can't be know if a feature is supported + * + * @param string $var property name + * @return bool supported or not + * @throws Zend_Mail_Storage_Exception + */ + public function __get($var) + { + if (strpos($var, 'has') === 0) { + $var = strtolower(substr($var, 3)); + return isset($this->_has[$var]) ? $this->_has[$var] : null; + } + + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception($var . ' not found'); + } + + + /** + * Get a full list of features supported by the specific mail lib and the server + * + * @return array list of features as array(featurename => true|false[|null]) + */ + public function getCapabilities() + { + return $this->_has; + } + + + /** + * Count messages messages in current box/folder + * + * @return int number of messages + * @throws Zend_Mail_Storage_Exception + */ + abstract public function countMessages(); + + + /** + * Get a list of messages with number and size + * + * @param int $id number of message + * @return int|array size of given message of list with all messages as array(num => size) + */ + abstract public function getSize($id = 0); + + + /** + * Get a message with headers and body + * + * @param $id int number of message + * @return Zend_Mail_Message + */ + abstract public function getMessage($id); + + + /** + * Get raw header of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage header + * @param int $topLines include this many lines with header (after an empty line) + * @return string raw header + */ + abstract public function getRawHeader($id, $part = null, $topLines = 0); + + /** + * Get raw content of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage content + * @return string raw content + */ + abstract public function getRawContent($id, $part = null); + + /** + * Create instance with parameters + * + * @param array $params mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + */ + abstract public function __construct($params); + + + /** + * Destructor calls close() and therefore closes the resource. + */ + public function __destruct() + { + $this->close(); + } + + + /** + * Close resource for mail lib. If you need to control, when the resource + * is closed. Otherwise the destructor would call this. + * + * @return null + */ + abstract public function close(); + + + /** + * Keep the resource alive. + * + * @return null + */ + abstract public function noop(); + + /** + * delete a message from current box/folder + * + * @return null + */ + abstract public function removeMessage($id); + + /** + * get unique id for one or all messages + * + * if storage does not support unique ids it's the same as the message number + * + * @param int|null $id message number + * @return array|string message number for given message or all messages as array + * @throws Zend_Mail_Storage_Exception + */ + abstract public function getUniqueId($id = null); + + /** + * get a message number from a unique id + * + * I.e. if you have a webmailer that supports deleting messages you should use unique ids + * as parameter and use this method to translate it to message number right before calling removeMessage() + * + * @param string $id unique id + * @return int message number + * @throws Zend_Mail_Storage_Exception + */ + abstract public function getNumberByUniqueId($id); + + // interface implementations follows + + /** + * Countable::count() + * + * @return int + */ + public function count() + { + return $this->countMessages(); + } + + + /** + * ArrayAccess::offsetExists() + * + * @param int $id + * @return boolean + */ + public function offsetExists($id) + { + try { + if ($this->getMessage($id)) { + return true; + } + } catch(Zend_Mail_Storage_Exception $e) {} + + return false; + } + + + /** + * ArrayAccess::offsetGet() + * + * @param int $id + * @return Zend_Mail_Message message object + */ + public function offsetGet($id) + { + return $this->getMessage($id); + } + + + /** + * ArrayAccess::offsetSet() + * + * @param id $id + * @param mixed $value + * @throws Zend_Mail_Storage_Exception + * @return void + */ + public function offsetSet($id, $value) + { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot write mail messages via array access'); + } + + + /** + * ArrayAccess::offsetUnset() + * + * @param int $id + * @return boolean success + */ + public function offsetUnset($id) + { + return $this->removeMessage($id); + } + + + /** + * Iterator::rewind() + * + * Rewind always gets the new count from the storage. Thus if you use + * the interfaces and your scripts take long you should use reset() + * from time to time. + * + * @return void + */ + public function rewind() + { + $this->_iterationMax = $this->countMessages(); + $this->_iterationPos = 1; + } + + + /** + * Iterator::current() + * + * @return Zend_Mail_Message current message + */ + public function current() + { + return $this->getMessage($this->_iterationPos); + } + + + /** + * Iterator::key() + * + * @return int id of current position + */ + public function key() + { + return $this->_iterationPos; + } + + + /** + * Iterator::next() + * + * @return void + */ + public function next() + { + ++$this->_iterationPos; + } + + + /** + * Iterator::valid() + * + * @return boolean + */ + public function valid() + { + if ($this->_iterationMax === null) { + $this->_iterationMax = $this->countMessages(); + } + return $this->_iterationPos && $this->_iterationPos <= $this->_iterationMax; + } + + + /** + * SeekableIterator::seek() + * + * @param int $pos + * @return void + * @throws OutOfBoundsException + */ + public function seek($pos) + { + if ($this->_iterationMax === null) { + $this->_iterationMax = $this->countMessages(); + } + + if ($pos > $this->_iterationMax) { + throw new OutOfBoundsException('this position does not exist'); + } + $this->_iterationPos = $pos; + } + +} diff --git a/libs/Zend/Mail/Storage/Exception.php b/libs/Zend/Mail/Storage/Exception.php index 013a69f7c2..1aea4f9d0b 100644 --- a/libs/Zend/Mail/Storage/Exception.php +++ b/libs/Zend/Mail/Storage/Exception.php @@ -1,39 +1,39 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Exception
- */
-require_once 'Zend/Mail/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Exception extends Zend_Mail_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Exception + */ +require_once 'Zend/Mail/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Exception extends Zend_Mail_Exception +{} + diff --git a/libs/Zend/Mail/Storage/Folder.php b/libs/Zend/Mail/Storage/Folder.php index bde10d865d..6f7e2f3933 100644 --- a/libs/Zend/Mail/Storage/Folder.php +++ b/libs/Zend/Mail/Storage/Folder.php @@ -1,236 +1,236 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Folder.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Folder implements RecursiveIterator
-{
- /**
- * subfolders of folder array(localName => Zend_Mail_Storage_Folder folder)
- * @var array
- */
- protected $_folders;
-
- /**
- * local name (name of folder in parent folder)
- * @var string
- */
- protected $_localName;
-
- /**
- * global name (absolute name of folder)
- * @var string
- */
- protected $_globalName;
-
- /**
- * folder is selectable if folder is able to hold messages, else it's just a parent folder
- * @var bool
- */
- protected $_selectable = true;
-
- /**
- * create a new mail folder instance
- *
- * @param string $localName name of folder in current subdirectory
- * @param string $globalName absolute name of folder
- * @param bool $selectable if true folder holds messages, if false it's just a parent for subfolders
- * @param array $folders init with given instances of Zend_Mail_Storage_Folder as subfolders
- */
- public function __construct($localName, $globalName = '', $selectable = true, array $folders = array())
- {
- $this->_localName = $localName;
- $this->_globalName = $globalName ? $globalName : $localName;
- $this->_selectable = $selectable;
- $this->_folders = $folders;
- }
-
- /**
- * implements RecursiveIterator::hasChildren()
- *
- * @return bool current element has children
- */
- public function hasChildren()
- {
- $current = $this->current();
- return $current && $current instanceof Zend_Mail_Storage_Folder && !$current->isLeaf();
- }
-
- /**
- * implements RecursiveIterator::getChildren()
- *
- * @return Zend_Mail_Storage_Folder same as self::current()
- */
- public function getChildren()
- {
- return $this->current();
- }
-
- /**
- * implements Iterator::valid()
- *
- * @return bool check if there's a current element
- */
- public function valid()
- {
- return key($this->_folders) !== null;
- }
-
- /**
- * implements Iterator::next()
- *
- * @return null
- */
- public function next()
- {
- next($this->_folders);
- }
-
- /**
- * implements Iterator::key()
- *
- * @return string key/local name of current element
- */
- public function key()
- {
- return key($this->_folders);
- }
-
- /**
- * implements Iterator::current()
- *
- * @return Zend_Mail_Storage_Folder current folder
- */
- public function current()
- {
- return current($this->_folders);
- }
-
- /**
- * implements Iterator::rewind()
- *
- * @return null
- */
- public function rewind()
- {
- reset($this->_folders);
- }
-
- /**
- * get subfolder named $name
- *
- * @param string $name wanted subfolder
- * @return Zend_Mail_Storage_Folder folder named $folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function __get($name)
- {
- if (!isset($this->_folders[$name])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("no subfolder named $name");
- }
-
- return $this->_folders[$name];
- }
-
- /**
- * add or replace subfolder named $name
- *
- * @param string $name local name of subfolder
- * @param Zend_Mail_Storage_Folder $folder instance for new subfolder
- * @return null
- */
- public function __set($name, Zend_Mail_Storage_Folder $folder)
- {
- $this->_folders[$name] = $folder;
- }
-
- /**
- * remove subfolder named $name
- *
- * @param string $name local name of subfolder
- * @return null
- */
- public function __unset($name)
- {
- unset($this->_folders[$name]);
- }
-
- /**
- * magic method for easy output of global name
- *
- * @return string global name of folder
- */
- public function __toString()
- {
- return (string)$this->getGlobalName();
- }
-
- /**
- * get local name
- *
- * @return string local name
- */
- public function getLocalName()
- {
- return $this->_localName;
- }
-
- /**
- * get global name
- *
- * @return string global name
- */
- public function getGlobalName()
- {
- return $this->_globalName;
- }
-
- /**
- * is this folder selectable?
- *
- * @return bool selectable
- */
- public function isSelectable()
- {
- return $this->_selectable;
- }
-
- /**
- * check if folder has no subfolder
- *
- * @return bool true if no subfolders
- */
- public function isLeaf()
- {
- return empty($this->_folders);
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Folder.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Folder implements RecursiveIterator +{ + /** + * subfolders of folder array(localName => Zend_Mail_Storage_Folder folder) + * @var array + */ + protected $_folders; + + /** + * local name (name of folder in parent folder) + * @var string + */ + protected $_localName; + + /** + * global name (absolute name of folder) + * @var string + */ + protected $_globalName; + + /** + * folder is selectable if folder is able to hold messages, else it's just a parent folder + * @var bool + */ + protected $_selectable = true; + + /** + * create a new mail folder instance + * + * @param string $localName name of folder in current subdirectory + * @param string $globalName absolute name of folder + * @param bool $selectable if true folder holds messages, if false it's just a parent for subfolders + * @param array $folders init with given instances of Zend_Mail_Storage_Folder as subfolders + */ + public function __construct($localName, $globalName = '', $selectable = true, array $folders = array()) + { + $this->_localName = $localName; + $this->_globalName = $globalName ? $globalName : $localName; + $this->_selectable = $selectable; + $this->_folders = $folders; + } + + /** + * implements RecursiveIterator::hasChildren() + * + * @return bool current element has children + */ + public function hasChildren() + { + $current = $this->current(); + return $current && $current instanceof Zend_Mail_Storage_Folder && !$current->isLeaf(); + } + + /** + * implements RecursiveIterator::getChildren() + * + * @return Zend_Mail_Storage_Folder same as self::current() + */ + public function getChildren() + { + return $this->current(); + } + + /** + * implements Iterator::valid() + * + * @return bool check if there's a current element + */ + public function valid() + { + return key($this->_folders) !== null; + } + + /** + * implements Iterator::next() + * + * @return null + */ + public function next() + { + next($this->_folders); + } + + /** + * implements Iterator::key() + * + * @return string key/local name of current element + */ + public function key() + { + return key($this->_folders); + } + + /** + * implements Iterator::current() + * + * @return Zend_Mail_Storage_Folder current folder + */ + public function current() + { + return current($this->_folders); + } + + /** + * implements Iterator::rewind() + * + * @return null + */ + public function rewind() + { + reset($this->_folders); + } + + /** + * get subfolder named $name + * + * @param string $name wanted subfolder + * @return Zend_Mail_Storage_Folder folder named $folder + * @throws Zend_Mail_Storage_Exception + */ + public function __get($name) + { + if (!isset($this->_folders[$name])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("no subfolder named $name"); + } + + return $this->_folders[$name]; + } + + /** + * add or replace subfolder named $name + * + * @param string $name local name of subfolder + * @param Zend_Mail_Storage_Folder $folder instance for new subfolder + * @return null + */ + public function __set($name, Zend_Mail_Storage_Folder $folder) + { + $this->_folders[$name] = $folder; + } + + /** + * remove subfolder named $name + * + * @param string $name local name of subfolder + * @return null + */ + public function __unset($name) + { + unset($this->_folders[$name]); + } + + /** + * magic method for easy output of global name + * + * @return string global name of folder + */ + public function __toString() + { + return (string)$this->getGlobalName(); + } + + /** + * get local name + * + * @return string local name + */ + public function getLocalName() + { + return $this->_localName; + } + + /** + * get global name + * + * @return string global name + */ + public function getGlobalName() + { + return $this->_globalName; + } + + /** + * is this folder selectable? + * + * @return bool selectable + */ + public function isSelectable() + { + return $this->_selectable; + } + + /** + * check if folder has no subfolder + * + * @return bool true if no subfolders + */ + public function isLeaf() + { + return empty($this->_folders); + } +} diff --git a/libs/Zend/Mail/Storage/Folder/Interface.php b/libs/Zend/Mail/Storage/Folder/Interface.php index b0e6764b98..d9482b81e2 100644 --- a/libs/Zend/Mail/Storage/Folder/Interface.php +++ b/libs/Zend/Mail/Storage/Folder/Interface.php @@ -1,60 +1,60 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-interface Zend_Mail_Storage_Folder_Interface
-{
- /**
- * get root folder or given folder
- *
- * @param string $rootFolder get folder structure for given folder, else root
- * @return Zend_Mail_Storage_Folder root or wanted folder
- */
- public function getFolders($rootFolder = null);
-
- /**
- * select given folder
- *
- * folder must be selectable!
- *
- * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function selectFolder($globalName);
-
-
- /**
- * get Zend_Mail_Storage_Folder instance for current folder
- *
- * @return Zend_Mail_Storage_Folder instance of current folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getCurrentFolder();
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +interface Zend_Mail_Storage_Folder_Interface +{ + /** + * get root folder or given folder + * + * @param string $rootFolder get folder structure for given folder, else root + * @return Zend_Mail_Storage_Folder root or wanted folder + */ + public function getFolders($rootFolder = null); + + /** + * select given folder + * + * folder must be selectable! + * + * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function selectFolder($globalName); + + + /** + * get Zend_Mail_Storage_Folder instance for current folder + * + * @return Zend_Mail_Storage_Folder instance of current folder + * @throws Zend_Mail_Storage_Exception + */ + public function getCurrentFolder(); +} diff --git a/libs/Zend/Mail/Storage/Folder/Maildir.php b/libs/Zend/Mail/Storage/Folder/Maildir.php index 44826f4945..bf4e4847ca 100644 --- a/libs/Zend/Mail/Storage/Folder/Maildir.php +++ b/libs/Zend/Mail/Storage/Folder/Maildir.php @@ -1,265 +1,265 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Folder
- */
-require_once 'Zend/Mail/Storage/Folder.php';
-
-/**
- * @see Zend_Mail_Storage_Folder_Interface
- */
-require_once 'Zend/Mail/Storage/Folder/Interface.php';
-
-/**
- * @see Zend_Mail_Storage_Maildir
- */
-require_once 'Zend/Mail/Storage/Maildir.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Folder_Maildir extends Zend_Mail_Storage_Maildir implements Zend_Mail_Storage_Folder_Interface
-{
- /**
- * Zend_Mail_Storage_Folder root folder for folder structure
- * @var Zend_Mail_Storage_Folder
- */
- protected $_rootFolder;
-
- /**
- * rootdir of folder structure
- * @var string
- */
- protected $_rootdir;
-
- /**
- * name of current folder
- * @var string
- */
- protected $_currentFolder;
-
- /**
- * delim char for subfolders
- * @var string
- */
- protected $_delim;
-
- /**
- * Create instance with parameters
- * Supported parameters are:
- * - dirname rootdir of maildir structure
- * - delim delim char for folder structur, default is '.'
- * - folder intial selected folder, default is 'INBOX'
- *
- * @param $params array mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- if (!isset($params->dirname) || !is_dir($params->dirname)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
- }
-
- $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
-
- $this->_delim = isset($params->delim) ? $params->delim : '.';
-
- $this->_buildFolderTree();
- $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
- $this->_has['top'] = true;
- $this->_has['flags'] = true;
- }
-
- /**
- * find all subfolders and mbox files for folder structure
- *
- * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
- * $parentFolder and $parentGlobalName are only used internally for recursion.
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _buildFolderTree()
- {
- $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
- $this->_rootFolder->INBOX = new Zend_Mail_Storage_Folder('INBOX', 'INBOX', true);
-
- $dh = @opendir($this->_rootdir);
- if (!$dh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("can't read folders in maildir");
- }
- $dirs = array();
- while (($entry = readdir($dh)) !== false) {
- // maildir++ defines folders must start with .
- if ($entry[0] != '.' || $entry == '.' || $entry == '..') {
- continue;
- }
- if ($this->_isMaildir($this->_rootdir . $entry)) {
- $dirs[] = $entry;
- }
- }
- closedir($dh);
-
- sort($dirs);
- $stack = array(null);
- $folderStack = array(null);
- $parentFolder = $this->_rootFolder;
- $parent = '.';
-
- foreach ($dirs as $dir) {
- do {
- if (strpos($dir, $parent) === 0) {
- $local = substr($dir, strlen($parent));
- if (strpos($local, $this->_delim) !== false) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('error while reading maildir');
- }
- array_push($stack, $parent);
- $parent = $dir . $this->_delim;
- $folder = new Zend_Mail_Storage_Folder($local, substr($dir, 1), true);
- $parentFolder->$local = $folder;
- array_push($folderStack, $parentFolder);
- $parentFolder = $folder;
- break;
- } else if ($stack) {
- $parent = array_pop($stack);
- $parentFolder = array_pop($folderStack);
- }
- } while ($stack);
- if (!$stack) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('error while reading maildir');
- }
- }
- }
-
- /**
- * get root folder or given folder
- *
- * @param string $rootFolder get folder structure for given folder, else root
- * @return Zend_Mail_Storage_Folder root or wanted folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getFolders($rootFolder = null)
- {
- if (!$rootFolder || $rootFolder == 'INBOX') {
- return $this->_rootFolder;
- }
-
- // rootdir is same as INBOX in maildir
- if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) {
- $rootFolder = substr($rootFolder, 6);
- }
- $currentFolder = $this->_rootFolder;
- $subname = trim($rootFolder, $this->_delim);
- while ($currentFolder) {
- @list($entry, $subname) = @explode($this->_delim, $subname, 2);
- $currentFolder = $currentFolder->$entry;
- if (!$subname) {
- break;
- }
- }
-
- if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
- }
- return $currentFolder;
- }
-
- /**
- * select given folder
- *
- * folder must be selectable!
- *
- * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function selectFolder($globalName)
- {
- $this->_currentFolder = (string)$globalName;
-
- // getting folder from folder tree for validation
- $folder = $this->getFolders($this->_currentFolder);
-
- try {
- $this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName());
- } catch(Zend_Mail_Storage_Exception $e) {
- // check what went wrong
- if (!$folder->isSelectable()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable");
- }
- // seems like file has vanished; rebuilding folder tree - but it's still an exception
- $this->_buildFolderTree($this->_rootdir);
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' .
- 'folder tree, search for an other folder and try again');
- }
- }
-
- /**
- * get Zend_Mail_Storage_Folder instance for current folder
- *
- * @return Zend_Mail_Storage_Folder instance of current folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getCurrentFolder()
- {
- return $this->_currentFolder;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Folder + */ +require_once 'Zend/Mail/Storage/Folder.php'; + +/** + * @see Zend_Mail_Storage_Folder_Interface + */ +require_once 'Zend/Mail/Storage/Folder/Interface.php'; + +/** + * @see Zend_Mail_Storage_Maildir + */ +require_once 'Zend/Mail/Storage/Maildir.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Folder_Maildir extends Zend_Mail_Storage_Maildir implements Zend_Mail_Storage_Folder_Interface +{ + /** + * Zend_Mail_Storage_Folder root folder for folder structure + * @var Zend_Mail_Storage_Folder + */ + protected $_rootFolder; + + /** + * rootdir of folder structure + * @var string + */ + protected $_rootdir; + + /** + * name of current folder + * @var string + */ + protected $_currentFolder; + + /** + * delim char for subfolders + * @var string + */ + protected $_delim; + + /** + * Create instance with parameters + * Supported parameters are: + * - dirname rootdir of maildir structure + * - delim delim char for folder structur, default is '.' + * - folder intial selected folder, default is 'INBOX' + * + * @param $params array mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + if (!isset($params->dirname) || !is_dir($params->dirname)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('no valid dirname given in params'); + } + + $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + + $this->_delim = isset($params->delim) ? $params->delim : '.'; + + $this->_buildFolderTree(); + $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX'); + $this->_has['top'] = true; + $this->_has['flags'] = true; + } + + /** + * find all subfolders and mbox files for folder structure + * + * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder. + * $parentFolder and $parentGlobalName are only used internally for recursion. + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + protected function _buildFolderTree() + { + $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false); + $this->_rootFolder->INBOX = new Zend_Mail_Storage_Folder('INBOX', 'INBOX', true); + + $dh = @opendir($this->_rootdir); + if (!$dh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("can't read folders in maildir"); + } + $dirs = array(); + while (($entry = readdir($dh)) !== false) { + // maildir++ defines folders must start with . + if ($entry[0] != '.' || $entry == '.' || $entry == '..') { + continue; + } + if ($this->_isMaildir($this->_rootdir . $entry)) { + $dirs[] = $entry; + } + } + closedir($dh); + + sort($dirs); + $stack = array(null); + $folderStack = array(null); + $parentFolder = $this->_rootFolder; + $parent = '.'; + + foreach ($dirs as $dir) { + do { + if (strpos($dir, $parent) === 0) { + $local = substr($dir, strlen($parent)); + if (strpos($local, $this->_delim) !== false) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('error while reading maildir'); + } + array_push($stack, $parent); + $parent = $dir . $this->_delim; + $folder = new Zend_Mail_Storage_Folder($local, substr($dir, 1), true); + $parentFolder->$local = $folder; + array_push($folderStack, $parentFolder); + $parentFolder = $folder; + break; + } else if ($stack) { + $parent = array_pop($stack); + $parentFolder = array_pop($folderStack); + } + } while ($stack); + if (!$stack) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('error while reading maildir'); + } + } + } + + /** + * get root folder or given folder + * + * @param string $rootFolder get folder structure for given folder, else root + * @return Zend_Mail_Storage_Folder root or wanted folder + * @throws Zend_Mail_Storage_Exception + */ + public function getFolders($rootFolder = null) + { + if (!$rootFolder || $rootFolder == 'INBOX') { + return $this->_rootFolder; + } + + // rootdir is same as INBOX in maildir + if (strpos($rootFolder, 'INBOX' . $this->_delim) === 0) { + $rootFolder = substr($rootFolder, 6); + } + $currentFolder = $this->_rootFolder; + $subname = trim($rootFolder, $this->_delim); + while ($currentFolder) { + @list($entry, $subname) = @explode($this->_delim, $subname, 2); + $currentFolder = $currentFolder->$entry; + if (!$subname) { + break; + } + } + + if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->_delim)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("folder $rootFolder not found"); + } + return $currentFolder; + } + + /** + * select given folder + * + * folder must be selectable! + * + * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function selectFolder($globalName) + { + $this->_currentFolder = (string)$globalName; + + // getting folder from folder tree for validation + $folder = $this->getFolders($this->_currentFolder); + + try { + $this->_openMaildir($this->_rootdir . '.' . $folder->getGlobalName()); + } catch(Zend_Mail_Storage_Exception $e) { + // check what went wrong + if (!$folder->isSelectable()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable"); + } + // seems like file has vanished; rebuilding folder tree - but it's still an exception + $this->_buildFolderTree($this->_rootdir); + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('seems like the maildir has vanished, I\'ve rebuild the ' . + 'folder tree, search for an other folder and try again'); + } + } + + /** + * get Zend_Mail_Storage_Folder instance for current folder + * + * @return Zend_Mail_Storage_Folder instance of current folder + * @throws Zend_Mail_Storage_Exception + */ + public function getCurrentFolder() + { + return $this->_currentFolder; + } +} diff --git a/libs/Zend/Mail/Storage/Folder/Mbox.php b/libs/Zend/Mail/Storage/Folder/Mbox.php index 47e67dc8ab..e5b1b1002e 100644 --- a/libs/Zend/Mail/Storage/Folder/Mbox.php +++ b/libs/Zend/Mail/Storage/Folder/Mbox.php @@ -1,264 +1,264 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Mbox.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Folder
- */
-require_once 'Zend/Mail/Storage/Folder.php';
-
-/**
- * @see Zend_Mail_Storage_Folder_Interface
- */
-require_once 'Zend/Mail/Storage/Folder/Interface.php';
-
-/**
- * @see Zend_Mail_Storage_Mbox
- */
-require_once 'Zend/Mail/Storage/Mbox.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Folder_Mbox extends Zend_Mail_Storage_Mbox implements Zend_Mail_Storage_Folder_Interface
-{
- /**
- * Zend_Mail_Storage_Folder root folder for folder structure
- * @var Zend_Mail_Storage_Folder
- */
- protected $_rootFolder;
-
- /**
- * rootdir of folder structure
- * @var string
- */
- protected $_rootdir;
-
- /**
- * name of current folder
- * @var string
- */
- protected $_currentFolder;
-
- /**
- * Create instance with parameters
- *
- * Disallowed parameters are:
- * - filename use Zend_Mail_Storage_Mbox for a single file
- * Supported parameters are:
- * - dirname rootdir of mbox structure
- * - folder intial selected folder, default is 'INBOX'
- *
- * @param $params array mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- if (isset($params->filename)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('use Zend_Mail_Storage_Mbox for a single file');
- }
-
- if (!isset($params->dirname) || !is_dir($params->dirname)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
- }
-
- $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
-
- $this->_buildFolderTree($this->_rootdir);
- $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX');
- $this->_has['top'] = true;
- $this->_has['uniqueid'] = false;
- }
-
- /**
- * find all subfolders and mbox files for folder structure
- *
- * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder.
- * $parentFolder and $parentGlobalName are only used internally for recursion.
- *
- * @param string $currentDir call with root dir, also used for recursion.
- * @param Zend_Mail_Storage_Folder|null $parentFolder used for recursion
- * @param string $parentGlobalName used for rescursion
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '')
- {
- if (!$parentFolder) {
- $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false);
- $parentFolder = $this->_rootFolder;
- }
-
- $dh = @opendir($currentDir);
- if (!$dh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("can't read dir $currentDir");
- }
- while (($entry = readdir($dh)) !== false) {
- // ignore hidden files for mbox
- if ($entry[0] == '.') {
- continue;
- }
- $absoluteEntry = $currentDir . $entry;
- $globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry;
- if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) {
- $parentFolder->$entry = new Zend_Mail_Storage_Folder($entry, $globalName);
- continue;
- }
- if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) {
- continue;
- }
- $folder = new Zend_Mail_Storage_Folder($entry, $globalName, false);
- $parentFolder->$entry = $folder;
- $this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName);
- }
-
- closedir($dh);
- }
-
- /**
- * get root folder or given folder
- *
- * @param string $rootFolder get folder structure for given folder, else root
- * @return Zend_Mail_Storage_Folder root or wanted folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getFolders($rootFolder = null)
- {
- if (!$rootFolder) {
- return $this->_rootFolder;
- }
-
- $currentFolder = $this->_rootFolder;
- $subname = trim($rootFolder, DIRECTORY_SEPARATOR);
- while ($currentFolder) {
- @list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2);
- $currentFolder = $currentFolder->$entry;
- if (!$subname) {
- break;
- }
- }
-
- if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("folder $rootFolder not found");
- }
- return $currentFolder;
- }
-
- /**
- * select given folder
- *
- * folder must be selectable!
- *
- * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function selectFolder($globalName)
- {
- $this->_currentFolder = (string)$globalName;
-
- // getting folder from folder tree for validation
- $folder = $this->getFolders($this->_currentFolder);
-
- try {
- $this->_openMboxFile($this->_rootdir . $folder->getGlobalName());
- } catch(Zend_Mail_Storage_Exception $e) {
- // check what went wrong
- if (!$folder->isSelectable()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable");
- }
- // seems like file has vanished; rebuilding folder tree - but it's still an exception
- $this->_buildFolderTree($this->_rootdir);
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' .
- 'folder tree, search for an other folder and try again');
- }
- }
-
- /**
- * get Zend_Mail_Storage_Folder instance for current folder
- *
- * @return Zend_Mail_Storage_Folder instance of current folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getCurrentFolder()
- {
- return $this->_currentFolder;
- }
-
- /**
- * magic method for serialize()
- *
- * with this method you can cache the mbox class
- *
- * @return array name of variables
- */
- public function __sleep()
- {
- return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir'));
- }
-
- /**
- * magic method for unserialize()
- *
- * with this method you can cache the mbox class
- *
- * @return null
- */
- public function __wakeup()
- {
- // if cache is stall selectFolder() rebuilds the tree on error
- parent::__wakeup();
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Mbox.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Folder + */ +require_once 'Zend/Mail/Storage/Folder.php'; + +/** + * @see Zend_Mail_Storage_Folder_Interface + */ +require_once 'Zend/Mail/Storage/Folder/Interface.php'; + +/** + * @see Zend_Mail_Storage_Mbox + */ +require_once 'Zend/Mail/Storage/Mbox.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Folder_Mbox extends Zend_Mail_Storage_Mbox implements Zend_Mail_Storage_Folder_Interface +{ + /** + * Zend_Mail_Storage_Folder root folder for folder structure + * @var Zend_Mail_Storage_Folder + */ + protected $_rootFolder; + + /** + * rootdir of folder structure + * @var string + */ + protected $_rootdir; + + /** + * name of current folder + * @var string + */ + protected $_currentFolder; + + /** + * Create instance with parameters + * + * Disallowed parameters are: + * - filename use Zend_Mail_Storage_Mbox for a single file + * Supported parameters are: + * - dirname rootdir of mbox structure + * - folder intial selected folder, default is 'INBOX' + * + * @param $params array mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + if (isset($params->filename)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('use Zend_Mail_Storage_Mbox for a single file'); + } + + if (!isset($params->dirname) || !is_dir($params->dirname)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('no valid dirname given in params'); + } + + $this->_rootdir = rtrim($params->dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + + $this->_buildFolderTree($this->_rootdir); + $this->selectFolder(!empty($params->folder) ? $params->folder : 'INBOX'); + $this->_has['top'] = true; + $this->_has['uniqueid'] = false; + } + + /** + * find all subfolders and mbox files for folder structure + * + * Result is save in Zend_Mail_Storage_Folder instances with the root in $this->_rootFolder. + * $parentFolder and $parentGlobalName are only used internally for recursion. + * + * @param string $currentDir call with root dir, also used for recursion. + * @param Zend_Mail_Storage_Folder|null $parentFolder used for recursion + * @param string $parentGlobalName used for rescursion + * @return null + * @throws Zend_Mail_Storage_Exception + */ + protected function _buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '') + { + if (!$parentFolder) { + $this->_rootFolder = new Zend_Mail_Storage_Folder('/', '/', false); + $parentFolder = $this->_rootFolder; + } + + $dh = @opendir($currentDir); + if (!$dh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("can't read dir $currentDir"); + } + while (($entry = readdir($dh)) !== false) { + // ignore hidden files for mbox + if ($entry[0] == '.') { + continue; + } + $absoluteEntry = $currentDir . $entry; + $globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry; + if (is_file($absoluteEntry) && $this->_isMboxFile($absoluteEntry)) { + $parentFolder->$entry = new Zend_Mail_Storage_Folder($entry, $globalName); + continue; + } + if (!is_dir($absoluteEntry) /* || $entry == '.' || $entry == '..' */) { + continue; + } + $folder = new Zend_Mail_Storage_Folder($entry, $globalName, false); + $parentFolder->$entry = $folder; + $this->_buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName); + } + + closedir($dh); + } + + /** + * get root folder or given folder + * + * @param string $rootFolder get folder structure for given folder, else root + * @return Zend_Mail_Storage_Folder root or wanted folder + * @throws Zend_Mail_Storage_Exception + */ + public function getFolders($rootFolder = null) + { + if (!$rootFolder) { + return $this->_rootFolder; + } + + $currentFolder = $this->_rootFolder; + $subname = trim($rootFolder, DIRECTORY_SEPARATOR); + while ($currentFolder) { + @list($entry, $subname) = @explode(DIRECTORY_SEPARATOR, $subname, 2); + $currentFolder = $currentFolder->$entry; + if (!$subname) { + break; + } + } + + if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("folder $rootFolder not found"); + } + return $currentFolder; + } + + /** + * select given folder + * + * folder must be selectable! + * + * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function selectFolder($globalName) + { + $this->_currentFolder = (string)$globalName; + + // getting folder from folder tree for validation + $folder = $this->getFolders($this->_currentFolder); + + try { + $this->_openMboxFile($this->_rootdir . $folder->getGlobalName()); + } catch(Zend_Mail_Storage_Exception $e) { + // check what went wrong + if (!$folder->isSelectable()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("{$this->_currentFolder} is not selectable"); + } + // seems like file has vanished; rebuilding folder tree - but it's still an exception + $this->_buildFolderTree($this->_rootdir); + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('seems like the mbox file has vanished, I\'ve rebuild the ' . + 'folder tree, search for an other folder and try again'); + } + } + + /** + * get Zend_Mail_Storage_Folder instance for current folder + * + * @return Zend_Mail_Storage_Folder instance of current folder + * @throws Zend_Mail_Storage_Exception + */ + public function getCurrentFolder() + { + return $this->_currentFolder; + } + + /** + * magic method for serialize() + * + * with this method you can cache the mbox class + * + * @return array name of variables + */ + public function __sleep() + { + return array_merge(parent::__sleep(), array('_currentFolder', '_rootFolder', '_rootdir')); + } + + /** + * magic method for unserialize() + * + * with this method you can cache the mbox class + * + * @return null + */ + public function __wakeup() + { + // if cache is stall selectFolder() rebuilds the tree on error + parent::__wakeup(); + } +} diff --git a/libs/Zend/Mail/Storage/Imap.php b/libs/Zend/Mail/Storage/Imap.php index fdd1b980f4..47c9a6e9d7 100644 --- a/libs/Zend/Mail/Storage/Imap.php +++ b/libs/Zend/Mail/Storage/Imap.php @@ -1,608 +1,608 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Abstract
- */
-require_once 'Zend/Mail/Storage/Abstract.php';
-
-/**
- * @see Zend_Mail_Protocol_Imap
- */
-require_once 'Zend/Mail/Protocol/Imap.php';
-
-/**
- * @see Zend_Mail_Storage_Writable_Interface
- */
-require_once 'Zend/Mail/Storage/Writable/Interface.php';
-
-/**
- * @see Zend_Mail_Storage_Folder_Interface
- */
-require_once 'Zend/Mail/Storage/Folder/Interface.php';
-
-/**
- * @see Zend_Mail_Storage_Folder
- */
-require_once 'Zend/Mail/Storage/Folder.php';
-
-/**
- * @see Zend_Mail_Message
- */
-require_once 'Zend/Mail/Message.php';
-
-/**
- * @see Zend_Mail_Storage
- */
-require_once 'Zend/Mail/Storage.php';
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Imap extends Zend_Mail_Storage_Abstract
- implements Zend_Mail_Storage_Folder_Interface, Zend_Mail_Storage_Writable_Interface
-{
- // TODO: with an internal cache we could optimize this class, or create an extra class with
- // such optimizations. Especially the various fetch calls could be combined to one cache call
-
- /**
- * protocol handler
- * @var null|Zend_Mail_Protocol_Imap
- */
- protected $_protocol;
-
- /**
- * name of current folder
- * @var string
- */
- protected $_currentFolder = '';
-
- /**
- * imap flags to constants translation
- * @var array
- */
- protected static $_knownFlags = array('\Passed' => Zend_Mail_Storage::FLAG_PASSED,
- '\Answered' => Zend_Mail_Storage::FLAG_ANSWERED,
- '\Seen' => Zend_Mail_Storage::FLAG_SEEN,
- '\Deleted' => Zend_Mail_Storage::FLAG_DELETED,
- '\Draft' => Zend_Mail_Storage::FLAG_DRAFT,
- '\Flagged' => Zend_Mail_Storage::FLAG_FLAGGED);
-
- /**
- * Count messages all messages in current box
- *
- * @return int number of messages
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function countMessages()
- {
- if (!$this->_currentFolder) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('No selected folder to count');
- }
-
- // we're reselecting the current mailbox, because STATUS is slow and shouldn't be used on the current mailbox
- $result = $this->_protocol->select($this->_currentFolder);
- return $result['exists'];
- }
-
- /**
- * get a list of messages with number and size
- *
- * @param int $id number of message
- * @return int|array size of given message of list with all messages as array(num => size)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getSize($id = 0)
- {
- if ($id) {
- return $this->_protocol->fetch('RFC822.SIZE', $id);
- }
- return $this->_protocol->fetch('RFC822.SIZE', 1, INF);
- }
-
- /**
- * Fetch a message
- *
- * @param int $id number of message
- * @return Zend_Mail_Message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getMessage($id)
- {
- $data = $this->_protocol->fetch(array('FLAGS', 'RFC822.HEADER'), $id);
- $header = $data['RFC822.HEADER'];
-
- $flags = array();
- foreach ($data['FLAGS'] as $flag) {
- $flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
- }
-
- return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags));
- }
-
- /*
- * Get raw header of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage header
- * @param int $topLines include this many lines with header (after an empty line)
- * @param int $topLines include this many lines with header (after an empty line)
- * @return string raw header
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawHeader($id, $part = null, $topLines = 0)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- // TODO: toplines
- return $this->_protocol->fetch('RFC822.HEADER', $id);
- }
-
- /*
- * Get raw content of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage content
- * @return string raw content
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawContent($id, $part = null)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- return $this->_protocol->fetch('RFC822.TEXT', $id);
- }
-
- /**
- * create instance with parameters
- * Supported paramters are
- * - user username
- * - host hostname or ip address of IMAP server [optional, default = 'localhost']
- * - password password for user 'username' [optional, default = '']
- * - port port for IMAP server [optional, default = 110]
- * - ssl 'SSL' or 'TLS' for secure sockets
- * - folder select this folder [optional, default = 'INBOX']
- *
- * @param array $params mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- $this->_has['flags'] = true;
-
- if ($params instanceof Zend_Mail_Protocol_Imap) {
- $this->_protocol = $params;
- try {
- $this->selectFolder('INBOX');
- } catch(Zend_Mail_Storage_Exception $e) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot select INBOX, is this a valid transport?');
- }
- return;
- }
-
- if (!isset($params->user)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('need at least user in params');
- }
-
- $host = isset($params->host) ? $params->host : 'localhost';
- $password = isset($params->password) ? $params->password : '';
- $port = isset($params->port) ? $params->port : null;
- $ssl = isset($params->ssl) ? $params->ssl : false;
-
- $this->_protocol = new Zend_Mail_Protocol_Imap();
- $this->_protocol->connect($host, $port, $ssl);
- if (!$this->_protocol->login($params->user, $password)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot login, user or password wrong');
- }
- $this->selectFolder(isset($params->folder) ? $params->folder : 'INBOX');
- }
-
- /**
- * Close resource for mail lib. If you need to control, when the resource
- * is closed. Otherwise the destructor would call this.
- *
- * @return null
- */
- public function close()
- {
- $this->_currentFolder = '';
- $this->_protocol->logout();
- }
-
- /**
- * Keep the server busy.
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function noop()
- {
- if (!$this->_protocol->noop()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('could not do nothing');
- }
- }
-
- /**
- * Remove a message from server. If you're doing that from a web enviroment
- * you should be careful and use a uniqueid as parameter if possible to
- * identify the message.
- *
- * @param int $id number of message
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeMessage($id)
- {
- if (!$this->_protocol->store(array(Zend_Mail_Storage::FLAG_DELETED), $id, null, '+')) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot set deleted flag');
- }
- // TODO: expunge here or at close? we can handle an error here better and are more fail safe
- if (!$this->_protocol->expunge()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('message marked as deleted, but could not expunge');
- }
- }
-
- /**
- * get unique id for one or all messages
- *
- * if storage does not support unique ids it's the same as the message number
- *
- * @param int|null $id message number
- * @return array|string message number for given message or all messages as array
- * @throws Zend_Mail_Storage_Exception
- */
- public function getUniqueId($id = null)
- {
- if ($id) {
- return $this->_protocol->fetch('UID', $id);
- }
-
- return $this->_protocol->fetch('UID', 1, INF);
- }
-
- /**
- * get a message number from a unique id
- *
- * I.e. if you have a webmailer that supports deleting messages you should use unique ids
- * as parameter and use this method to translate it to message number right before calling removeMessage()
- *
- * @param string $id unique id
- * @return int message number
- * @throws Zend_Mail_Storage_Exception
- */
- public function getNumberByUniqueId($id)
- {
- // TODO: use search to find number directly
- $ids = $this->getUniqueId();
- foreach ($ids as $k => $v) {
- if ($v == $id) {
- return $k;
- }
- }
-
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('unique id not found');
- }
-
-
- /**
- * get root folder or given folder
- *
- * @param string $rootFolder get folder structure for given folder, else root
- * @return Zend_Mail_Storage_Folder root or wanted folder
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getFolders($rootFolder = null)
- {
- $folders = $this->_protocol->listMailbox((string)$rootFolder);
- if (!$folders) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('folder not found');
- }
-
- ksort($folders, SORT_STRING);
- $root = new Zend_Mail_Storage_Folder('/', '/', false);
- $stack = array(null);
- $folderStack = array(null);
- $parentFolder = $root;
- $parent = '';
-
- foreach ($folders as $globalName => $data) {
- do {
- if (!$parent || strpos($globalName, $parent) === 0) {
- $pos = strrpos($globalName, $data['delim']);
- if ($pos === false) {
- $localName = $globalName;
- } else {
- $localName = substr($globalName, $pos + 1);
- }
- $selectable = !$data['flags'] || !in_array('\\Noselect', $data['flags']);
-
- array_push($stack, $parent);
- $parent = $globalName . $data['delim'];
- $folder = new Zend_Mail_Storage_Folder($localName, $globalName, $selectable);
- $parentFolder->$localName = $folder;
- array_push($folderStack, $parentFolder);
- $parentFolder = $folder;
- break;
- } else if ($stack) {
- $parent = array_pop($stack);
- $parentFolder = array_pop($folderStack);
- }
- } while ($stack);
- if (!$stack) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('error while constructing folder tree');
- }
- }
-
- return $root;
- }
-
- /**
- * select given folder
- *
- * folder must be selectable!
- *
- * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function selectFolder($globalName)
- {
- $this->_currentFolder = $globalName;
- if (!$this->_protocol->select($this->_currentFolder)) {
- $this->_currentFolder = '';
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot change folder, maybe it does not exist');
- }
- }
-
-
- /**
- * get Zend_Mail_Storage_Folder instance for current folder
- *
- * @return Zend_Mail_Storage_Folder instance of current folder
- * @throws Zend_Mail_Storage_Exception
- */
- public function getCurrentFolder()
- {
- return $this->_currentFolder;
- }
-
- /**
- * create a new folder
- *
- * This method also creates parent folders if necessary. Some mail storages may restrict, which folder
- * may be used as parent or which chars may be used in the folder name
- *
- * @param string $name global name of folder, local name if $parentFolder is set
- * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function createFolder($name, $parentFolder = null)
- {
- // TODO: we assume / as the hierarchy delim - need to get that from the folder class!
- if ($parentFolder instanceof Zend_Mail_Storage_Folder) {
- $folder = $parentFolder->getGlobalName() . '/' . $name;
- } else if ($parentFolder != null) {
- $folder = $parentFolder . '/' . $name;
- } else {
- $folder = $name;
- }
-
- if (!$this->_protocol->create($folder)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot create folder');
- }
- }
-
- /**
- * remove a folder
- *
- * @param string|Zend_Mail_Storage_Folder $name name or instance of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeFolder($name)
- {
- if ($name instanceof Zend_Mail_Storage_Folder) {
- $name = $name->getGlobalName();
- }
-
- if (!$this->_protocol->delete($name)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot delete folder');
- }
- }
-
- /**
- * rename and/or move folder
- *
- * The new name has the same restrictions as in createFolder()
- *
- * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
- * @param string $newName new global name of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function renameFolder($oldName, $newName)
- {
- if ($oldName instanceof Zend_Mail_Storage_Folder) {
- $oldName = $oldName->getGlobalName();
- }
-
- if (!$this->_protocol->rename($oldName, $newName)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot rename folder');
- }
- }
-
- /**
- * append a new message to mail storage
- *
- * @param string $message message as string or instance of message class
- * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
- * @param null|array $flags set flags for new message, else a default set is used
- * @throws Zend_Mail_Storage_Exception
- */
- // not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
- public function appendMessage($message, $folder = null, $flags = null)
- {
- if ($folder === null) {
- $folder = $this->_currentFolder;
- }
-
- if ($flags === null) {
- $flags = array(Zend_Mail_Storage::FLAG_SEEN);
- }
-
- // TODO: handle class instances for $message
- if (!$this->_protocol->append($folder, $message, $flags)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot create message, please check if the folder exists and your flags');
- }
- }
-
- /**
- * copy an existing message
- *
- * @param int $id number of message
- * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function copyMessage($id, $folder)
- {
- if (!$this->_protocol->copy($folder, $id)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot copy message, does the folder exist?');
- }
- }
-
-
- /**
- * set flags for message
- *
- * NOTE: this method can't set the recent flag.
- *
- * @param int $id number of message
- * @param array $flags new flags for message
- * @throws Zend_Mail_Storage_Exception
- */
- public function setFlags($id, $flags)
- {
- if (!$this->_protocol->store($flags, $id)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot set flags, have you tried to set the recent flag or special chars?');
- }
- }
-}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Abstract + */ +require_once 'Zend/Mail/Storage/Abstract.php'; + +/** + * @see Zend_Mail_Protocol_Imap + */ +require_once 'Zend/Mail/Protocol/Imap.php'; + +/** + * @see Zend_Mail_Storage_Writable_Interface + */ +require_once 'Zend/Mail/Storage/Writable/Interface.php'; + +/** + * @see Zend_Mail_Storage_Folder_Interface + */ +require_once 'Zend/Mail/Storage/Folder/Interface.php'; + +/** + * @see Zend_Mail_Storage_Folder + */ +require_once 'Zend/Mail/Storage/Folder.php'; + +/** + * @see Zend_Mail_Message + */ +require_once 'Zend/Mail/Message.php'; + +/** + * @see Zend_Mail_Storage + */ +require_once 'Zend/Mail/Storage.php'; + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Imap extends Zend_Mail_Storage_Abstract + implements Zend_Mail_Storage_Folder_Interface, Zend_Mail_Storage_Writable_Interface +{ + // TODO: with an internal cache we could optimize this class, or create an extra class with + // such optimizations. Especially the various fetch calls could be combined to one cache call + + /** + * protocol handler + * @var null|Zend_Mail_Protocol_Imap + */ + protected $_protocol; + + /** + * name of current folder + * @var string + */ + protected $_currentFolder = ''; + + /** + * imap flags to constants translation + * @var array + */ + protected static $_knownFlags = array('\Passed' => Zend_Mail_Storage::FLAG_PASSED, + '\Answered' => Zend_Mail_Storage::FLAG_ANSWERED, + '\Seen' => Zend_Mail_Storage::FLAG_SEEN, + '\Deleted' => Zend_Mail_Storage::FLAG_DELETED, + '\Draft' => Zend_Mail_Storage::FLAG_DRAFT, + '\Flagged' => Zend_Mail_Storage::FLAG_FLAGGED); + + /** + * Count messages all messages in current box + * + * @return int number of messages + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function countMessages() + { + if (!$this->_currentFolder) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('No selected folder to count'); + } + + // we're reselecting the current mailbox, because STATUS is slow and shouldn't be used on the current mailbox + $result = $this->_protocol->select($this->_currentFolder); + return $result['exists']; + } + + /** + * get a list of messages with number and size + * + * @param int $id number of message + * @return int|array size of given message of list with all messages as array(num => size) + * @throws Zend_Mail_Protocol_Exception + */ + public function getSize($id = 0) + { + if ($id) { + return $this->_protocol->fetch('RFC822.SIZE', $id); + } + return $this->_protocol->fetch('RFC822.SIZE', 1, INF); + } + + /** + * Fetch a message + * + * @param int $id number of message + * @return Zend_Mail_Message + * @throws Zend_Mail_Protocol_Exception + */ + public function getMessage($id) + { + $data = $this->_protocol->fetch(array('FLAGS', 'RFC822.HEADER'), $id); + $header = $data['RFC822.HEADER']; + + $flags = array(); + foreach ($data['FLAGS'] as $flag) { + $flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag; + } + + return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags)); + } + + /* + * Get raw header of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage header + * @param int $topLines include this many lines with header (after an empty line) + * @param int $topLines include this many lines with header (after an empty line) + * @return string raw header + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawHeader($id, $part = null, $topLines = 0) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + // TODO: toplines + return $this->_protocol->fetch('RFC822.HEADER', $id); + } + + /* + * Get raw content of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage content + * @return string raw content + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawContent($id, $part = null) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + return $this->_protocol->fetch('RFC822.TEXT', $id); + } + + /** + * create instance with parameters + * Supported paramters are + * - user username + * - host hostname or ip address of IMAP server [optional, default = 'localhost'] + * - password password for user 'username' [optional, default = ''] + * - port port for IMAP server [optional, default = 110] + * - ssl 'SSL' or 'TLS' for secure sockets + * - folder select this folder [optional, default = 'INBOX'] + * + * @param array $params mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + $this->_has['flags'] = true; + + if ($params instanceof Zend_Mail_Protocol_Imap) { + $this->_protocol = $params; + try { + $this->selectFolder('INBOX'); + } catch(Zend_Mail_Storage_Exception $e) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot select INBOX, is this a valid transport?'); + } + return; + } + + if (!isset($params->user)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('need at least user in params'); + } + + $host = isset($params->host) ? $params->host : 'localhost'; + $password = isset($params->password) ? $params->password : ''; + $port = isset($params->port) ? $params->port : null; + $ssl = isset($params->ssl) ? $params->ssl : false; + + $this->_protocol = new Zend_Mail_Protocol_Imap(); + $this->_protocol->connect($host, $port, $ssl); + if (!$this->_protocol->login($params->user, $password)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot login, user or password wrong'); + } + $this->selectFolder(isset($params->folder) ? $params->folder : 'INBOX'); + } + + /** + * Close resource for mail lib. If you need to control, when the resource + * is closed. Otherwise the destructor would call this. + * + * @return null + */ + public function close() + { + $this->_currentFolder = ''; + $this->_protocol->logout(); + } + + /** + * Keep the server busy. + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function noop() + { + if (!$this->_protocol->noop()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('could not do nothing'); + } + } + + /** + * Remove a message from server. If you're doing that from a web enviroment + * you should be careful and use a uniqueid as parameter if possible to + * identify the message. + * + * @param int $id number of message + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeMessage($id) + { + if (!$this->_protocol->store(array(Zend_Mail_Storage::FLAG_DELETED), $id, null, '+')) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot set deleted flag'); + } + // TODO: expunge here or at close? we can handle an error here better and are more fail safe + if (!$this->_protocol->expunge()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('message marked as deleted, but could not expunge'); + } + } + + /** + * get unique id for one or all messages + * + * if storage does not support unique ids it's the same as the message number + * + * @param int|null $id message number + * @return array|string message number for given message or all messages as array + * @throws Zend_Mail_Storage_Exception + */ + public function getUniqueId($id = null) + { + if ($id) { + return $this->_protocol->fetch('UID', $id); + } + + return $this->_protocol->fetch('UID', 1, INF); + } + + /** + * get a message number from a unique id + * + * I.e. if you have a webmailer that supports deleting messages you should use unique ids + * as parameter and use this method to translate it to message number right before calling removeMessage() + * + * @param string $id unique id + * @return int message number + * @throws Zend_Mail_Storage_Exception + */ + public function getNumberByUniqueId($id) + { + // TODO: use search to find number directly + $ids = $this->getUniqueId(); + foreach ($ids as $k => $v) { + if ($v == $id) { + return $k; + } + } + + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('unique id not found'); + } + + + /** + * get root folder or given folder + * + * @param string $rootFolder get folder structure for given folder, else root + * @return Zend_Mail_Storage_Folder root or wanted folder + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function getFolders($rootFolder = null) + { + $folders = $this->_protocol->listMailbox((string)$rootFolder); + if (!$folders) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('folder not found'); + } + + ksort($folders, SORT_STRING); + $root = new Zend_Mail_Storage_Folder('/', '/', false); + $stack = array(null); + $folderStack = array(null); + $parentFolder = $root; + $parent = ''; + + foreach ($folders as $globalName => $data) { + do { + if (!$parent || strpos($globalName, $parent) === 0) { + $pos = strrpos($globalName, $data['delim']); + if ($pos === false) { + $localName = $globalName; + } else { + $localName = substr($globalName, $pos + 1); + } + $selectable = !$data['flags'] || !in_array('\\Noselect', $data['flags']); + + array_push($stack, $parent); + $parent = $globalName . $data['delim']; + $folder = new Zend_Mail_Storage_Folder($localName, $globalName, $selectable); + $parentFolder->$localName = $folder; + array_push($folderStack, $parentFolder); + $parentFolder = $folder; + break; + } else if ($stack) { + $parent = array_pop($stack); + $parentFolder = array_pop($folderStack); + } + } while ($stack); + if (!$stack) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('error while constructing folder tree'); + } + } + + return $root; + } + + /** + * select given folder + * + * folder must be selectable! + * + * @param Zend_Mail_Storage_Folder|string $globalName global name of folder or instance for subfolder + * @return null + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function selectFolder($globalName) + { + $this->_currentFolder = $globalName; + if (!$this->_protocol->select($this->_currentFolder)) { + $this->_currentFolder = ''; + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot change folder, maybe it does not exist'); + } + } + + + /** + * get Zend_Mail_Storage_Folder instance for current folder + * + * @return Zend_Mail_Storage_Folder instance of current folder + * @throws Zend_Mail_Storage_Exception + */ + public function getCurrentFolder() + { + return $this->_currentFolder; + } + + /** + * create a new folder + * + * This method also creates parent folders if necessary. Some mail storages may restrict, which folder + * may be used as parent or which chars may be used in the folder name + * + * @param string $name global name of folder, local name if $parentFolder is set + * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function createFolder($name, $parentFolder = null) + { + // TODO: we assume / as the hierarchy delim - need to get that from the folder class! + if ($parentFolder instanceof Zend_Mail_Storage_Folder) { + $folder = $parentFolder->getGlobalName() . '/' . $name; + } else if ($parentFolder != null) { + $folder = $parentFolder . '/' . $name; + } else { + $folder = $name; + } + + if (!$this->_protocol->create($folder)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot create folder'); + } + } + + /** + * remove a folder + * + * @param string|Zend_Mail_Storage_Folder $name name or instance of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeFolder($name) + { + if ($name instanceof Zend_Mail_Storage_Folder) { + $name = $name->getGlobalName(); + } + + if (!$this->_protocol->delete($name)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot delete folder'); + } + } + + /** + * rename and/or move folder + * + * The new name has the same restrictions as in createFolder() + * + * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder + * @param string $newName new global name of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function renameFolder($oldName, $newName) + { + if ($oldName instanceof Zend_Mail_Storage_Folder) { + $oldName = $oldName->getGlobalName(); + } + + if (!$this->_protocol->rename($oldName, $newName)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot rename folder'); + } + } + + /** + * append a new message to mail storage + * + * @param string $message message as string or instance of message class + * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken + * @param null|array $flags set flags for new message, else a default set is used + * @throws Zend_Mail_Storage_Exception + */ + // not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class + public function appendMessage($message, $folder = null, $flags = null) + { + if ($folder === null) { + $folder = $this->_currentFolder; + } + + if ($flags === null) { + $flags = array(Zend_Mail_Storage::FLAG_SEEN); + } + + // TODO: handle class instances for $message + if (!$this->_protocol->append($folder, $message, $flags)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot create message, please check if the folder exists and your flags'); + } + } + + /** + * copy an existing message + * + * @param int $id number of message + * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function copyMessage($id, $folder) + { + if (!$this->_protocol->copy($folder, $id)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot copy message, does the folder exist?'); + } + } + + + /** + * set flags for message + * + * NOTE: this method can't set the recent flag. + * + * @param int $id number of message + * @param array $flags new flags for message + * @throws Zend_Mail_Storage_Exception + */ + public function setFlags($id, $flags) + { + if (!$this->_protocol->store($flags, $id)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot set flags, have you tried to set the recent flag or special chars?'); + } + } +} + diff --git a/libs/Zend/Mail/Storage/Maildir.php b/libs/Zend/Mail/Storage/Maildir.php index df9886a5d0..653f36bcb2 100644 --- a/libs/Zend/Mail/Storage/Maildir.php +++ b/libs/Zend/Mail/Storage/Maildir.php @@ -1,425 +1,425 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Abstract
- */
-require_once 'Zend/Mail/Storage/Abstract.php';
-
-/**
- * @see Zend_Mail_Message
- */
-require_once 'Zend/Mail/Message.php';
-
-/**
- * @see Zend_Mail_Storage
- */
-require_once 'Zend/Mail/Storage.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Maildir extends Zend_Mail_Storage_Abstract
-{
- /**
- * data of found message files in maildir dir
- * @var array
- */
- protected $_files = array();
-
- /**
- * known flag chars in filenames
- *
- * This list has to be in alphabetical order for setFlags()
- *
- * @var array
- */
- protected static $_knownFlags = array('D' => Zend_Mail_Storage::FLAG_DRAFT,
- 'F' => Zend_Mail_Storage::FLAG_FLAGGED,
- 'P' => Zend_Mail_Storage::FLAG_PASSED,
- 'R' => Zend_Mail_Storage::FLAG_ANSWERED,
- 'S' => Zend_Mail_Storage::FLAG_SEEN,
- 'T' => Zend_Mail_Storage::FLAG_DELETED);
-
- /**
- * Count messages all messages in current box
- *
- * @return int number of messages
- * @throws Zend_Mail_Storage_Exception
- */
- public function countMessages()
- {
- return count($this->_files);
- }
-
- /**
- * Get one or all fields from file structure. Also checks if message is valid
- *
- * @param int $id message number
- * @param string|null $field wanted field
- * @return string|array wanted field or all fields as array
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _getFileData($id, $field = null)
- {
- if (!isset($this->_files[$id - 1])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('id does not exist');
- }
-
- if (!$field) {
- return $this->_files[$id - 1];
- }
-
- if (!isset($this->_files[$id - 1][$field])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('field does not exist');
- }
-
- return $this->_files[$id - 1][$field];
- }
-
- /**
- * Get a list of messages with number and size
- *
- * @param int|null $id number of message or null for all messages
- * @return int|array size of given message of list with all messages as array(num => size)
- * @throws Zend_Mail_Storage_Exception
- */
- public function getSize($id = null)
- {
- if ($id !== null) {
- return filesize($this->_getFileData($id, 'filename'));
- }
-
- $result = array();
- foreach ($this->_files as $num => $pos) {
- $result[$num + 1] = filesize($this->_files[$num]['filename']);
- }
-
- return $result;
- }
-
-
-
- /**
- * Fetch a message
- *
- * @param int $id number of message
- * @return Zend_Mail_Message
- * @throws Zend_Mail_Storage_Exception
- */
- public function getMessage($id)
- {
- return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $this->getRawHeader($id),
- 'flags' => $this->_getFileData($id, 'flags')));
- }
-
- /*
- * Get raw header of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage header
- * @param int $topLines include this many lines with header (after an empty line)
- * @return string raw header
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawHeader($id, $part = null, $topLines = 0)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- $fh = fopen($this->_getFileData($id, 'filename'), 'r');
-
- $content = '';
- while (!feof($fh)) {
- $line = fgets($fh);
- if (!trim($line)) {
- break;
- }
- $content .= $line;
- }
-
- fclose($fh);
- return $content;
- }
-
- /*
- * Get raw content of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage content
- * @return string raw content
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawContent($id, $part = null)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- $fh = fopen($this->_getFileData($id, 'filename'), 'r');
-
- while (!feof($fh)) {
- $line = fgets($fh);
- if (!trim($line)) {
- break;
- }
- }
-
- $content = stream_get_contents($fh);
- fclose($fh);
- return $content;
- }
-
- /**
- * Create instance with parameters
- * Supported parameters are:
- * - dirname dirname of mbox file
- *
- * @param $params array mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- if (!isset($params->dirname) || !is_dir($params->dirname)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('no valid dirname given in params');
- }
-
- if (!$this->_isMaildir($params->dirname)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('invalid maildir given');
- }
-
- $this->_has['top'] = true;
- $this->_has['flags'] = true;
- $this->_openMaildir($params->dirname);
- }
-
- /**
- * check if a given dir is a valid maildir
- *
- * @param string $dirname name of dir
- * @return bool dir is valid maildir
- */
- protected function _isMaildir($dirname)
- {
- if (file_exists($dirname . '/new') && !is_dir($dirname . '/new')) {
- return false;
- }
- if (file_exists($dirname . '/tmp') && !is_dir($dirname . '/tmp')) {
- return false;
- }
- return is_dir($dirname . '/cur');
- }
-
- /**
- * open given dir as current maildir
- *
- * @param string $dirname name of maildir
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _openMaildir($dirname)
- {
- if ($this->_files) {
- $this->close();
- }
-
- $dh = @opendir($dirname . '/cur/');
- if (!$dh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot open maildir');
- }
- $this->_getMaildirFiles($dh, $dirname . '/cur/');
- closedir($dh);
-
- $dh = @opendir($dirname . '/new/');
- if ($dh) {
- $this->_getMaildirFiles($dh, $dirname . '/new/', array(Zend_Mail_Storage::FLAG_RECENT));
- closedir($dh);
- } else if (file_exists($dirname . '/new/')) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot read recent mails in maildir');
- }
- }
-
- /**
- * find all files in opened dir handle and add to maildir files
- *
- * @param resource $dh dir handle used for search
- * @param string $dirname dirname of dir in $dh
- * @param array $default_flags default flags for given dir
- * @return null
- */
- protected function _getMaildirFiles($dh, $dirname, $default_flags = array())
- {
- while (($entry = readdir($dh)) !== false) {
- if ($entry[0] == '.' || !is_file($dirname . $entry)) {
- continue;
- }
-
- @list($uniq, $info) = explode(':', $entry, 2);
- @list($version, $flags) = explode(',', $info, 2);
- if ($version != 2) {
- $flags = '';
- }
-
- $named_flags = $default_flags;
- $length = strlen($flags);
- for ($i = 0; $i < $length; ++$i) {
- $flag = $flags[$i];
- $named_flags[$flag] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag;
- }
-
- $this->_files[] = array('uniq' => $uniq,
- 'flags' => $named_flags,
- 'filename' => $dirname . $entry);
- }
- }
-
-
- /**
- * Close resource for mail lib. If you need to control, when the resource
- * is closed. Otherwise the destructor would call this.
- *
- * @return void
- */
- public function close()
- {
- $this->_files = array();
- }
-
-
- /**
- * Waste some CPU cycles doing nothing.
- *
- * @return void
- */
- public function noop()
- {
- return true;
- }
-
-
- /**
- * stub for not supported message deletion
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeMessage($id)
- {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('maildir is (currently) read-only');
- }
-
- /**
- * get unique id for one or all messages
- *
- * if storage does not support unique ids it's the same as the message number
- *
- * @param int|null $id message number
- * @return array|string message number for given message or all messages as array
- * @throws Zend_Mail_Storage_Exception
- */
- public function getUniqueId($id = null)
- {
- if ($id) {
- return $this->_getFileData($id, 'uniq');
- }
-
- $ids = array();
- foreach ($this->_files as $num => $file) {
- $ids[$num + 1] = $file['uniq'];
- }
- return $ids;
- }
-
- /**
- * get a message number from a unique id
- *
- * I.e. if you have a webmailer that supports deleting messages you should use unique ids
- * as parameter and use this method to translate it to message number right before calling removeMessage()
- *
- * @param string $id unique id
- * @return int message number
- * @throws Zend_Mail_Storage_Exception
- */
- public function getNumberByUniqueId($id)
- {
- foreach ($this->_files as $num => $file) {
- if ($file['uniq'] == $id) {
- return $num + 1;
- }
- }
-
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('unique id not found');
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Abstract + */ +require_once 'Zend/Mail/Storage/Abstract.php'; + +/** + * @see Zend_Mail_Message + */ +require_once 'Zend/Mail/Message.php'; + +/** + * @see Zend_Mail_Storage + */ +require_once 'Zend/Mail/Storage.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Maildir extends Zend_Mail_Storage_Abstract +{ + /** + * data of found message files in maildir dir + * @var array + */ + protected $_files = array(); + + /** + * known flag chars in filenames + * + * This list has to be in alphabetical order for setFlags() + * + * @var array + */ + protected static $_knownFlags = array('D' => Zend_Mail_Storage::FLAG_DRAFT, + 'F' => Zend_Mail_Storage::FLAG_FLAGGED, + 'P' => Zend_Mail_Storage::FLAG_PASSED, + 'R' => Zend_Mail_Storage::FLAG_ANSWERED, + 'S' => Zend_Mail_Storage::FLAG_SEEN, + 'T' => Zend_Mail_Storage::FLAG_DELETED); + + /** + * Count messages all messages in current box + * + * @return int number of messages + * @throws Zend_Mail_Storage_Exception + */ + public function countMessages() + { + return count($this->_files); + } + + /** + * Get one or all fields from file structure. Also checks if message is valid + * + * @param int $id message number + * @param string|null $field wanted field + * @return string|array wanted field or all fields as array + * @throws Zend_Mail_Storage_Exception + */ + protected function _getFileData($id, $field = null) + { + if (!isset($this->_files[$id - 1])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('id does not exist'); + } + + if (!$field) { + return $this->_files[$id - 1]; + } + + if (!isset($this->_files[$id - 1][$field])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('field does not exist'); + } + + return $this->_files[$id - 1][$field]; + } + + /** + * Get a list of messages with number and size + * + * @param int|null $id number of message or null for all messages + * @return int|array size of given message of list with all messages as array(num => size) + * @throws Zend_Mail_Storage_Exception + */ + public function getSize($id = null) + { + if ($id !== null) { + return filesize($this->_getFileData($id, 'filename')); + } + + $result = array(); + foreach ($this->_files as $num => $pos) { + $result[$num + 1] = filesize($this->_files[$num]['filename']); + } + + return $result; + } + + + + /** + * Fetch a message + * + * @param int $id number of message + * @return Zend_Mail_Message + * @throws Zend_Mail_Storage_Exception + */ + public function getMessage($id) + { + return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $this->getRawHeader($id), + 'flags' => $this->_getFileData($id, 'flags'))); + } + + /* + * Get raw header of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage header + * @param int $topLines include this many lines with header (after an empty line) + * @return string raw header + * @throws Zend_Mail_Storage_Exception + */ + public function getRawHeader($id, $part = null, $topLines = 0) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + $fh = fopen($this->_getFileData($id, 'filename'), 'r'); + + $content = ''; + while (!feof($fh)) { + $line = fgets($fh); + if (!trim($line)) { + break; + } + $content .= $line; + } + + fclose($fh); + return $content; + } + + /* + * Get raw content of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage content + * @return string raw content + * @throws Zend_Mail_Storage_Exception + */ + public function getRawContent($id, $part = null) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + $fh = fopen($this->_getFileData($id, 'filename'), 'r'); + + while (!feof($fh)) { + $line = fgets($fh); + if (!trim($line)) { + break; + } + } + + $content = stream_get_contents($fh); + fclose($fh); + return $content; + } + + /** + * Create instance with parameters + * Supported parameters are: + * - dirname dirname of mbox file + * + * @param $params array mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + if (!isset($params->dirname) || !is_dir($params->dirname)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('no valid dirname given in params'); + } + + if (!$this->_isMaildir($params->dirname)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('invalid maildir given'); + } + + $this->_has['top'] = true; + $this->_has['flags'] = true; + $this->_openMaildir($params->dirname); + } + + /** + * check if a given dir is a valid maildir + * + * @param string $dirname name of dir + * @return bool dir is valid maildir + */ + protected function _isMaildir($dirname) + { + if (file_exists($dirname . '/new') && !is_dir($dirname . '/new')) { + return false; + } + if (file_exists($dirname . '/tmp') && !is_dir($dirname . '/tmp')) { + return false; + } + return is_dir($dirname . '/cur'); + } + + /** + * open given dir as current maildir + * + * @param string $dirname name of maildir + * @return null + * @throws Zend_Mail_Storage_Exception + */ + protected function _openMaildir($dirname) + { + if ($this->_files) { + $this->close(); + } + + $dh = @opendir($dirname . '/cur/'); + if (!$dh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot open maildir'); + } + $this->_getMaildirFiles($dh, $dirname . '/cur/'); + closedir($dh); + + $dh = @opendir($dirname . '/new/'); + if ($dh) { + $this->_getMaildirFiles($dh, $dirname . '/new/', array(Zend_Mail_Storage::FLAG_RECENT)); + closedir($dh); + } else if (file_exists($dirname . '/new/')) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot read recent mails in maildir'); + } + } + + /** + * find all files in opened dir handle and add to maildir files + * + * @param resource $dh dir handle used for search + * @param string $dirname dirname of dir in $dh + * @param array $default_flags default flags for given dir + * @return null + */ + protected function _getMaildirFiles($dh, $dirname, $default_flags = array()) + { + while (($entry = readdir($dh)) !== false) { + if ($entry[0] == '.' || !is_file($dirname . $entry)) { + continue; + } + + @list($uniq, $info) = explode(':', $entry, 2); + @list($version, $flags) = explode(',', $info, 2); + if ($version != 2) { + $flags = ''; + } + + $named_flags = $default_flags; + $length = strlen($flags); + for ($i = 0; $i < $length; ++$i) { + $flag = $flags[$i]; + $named_flags[$flag] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag; + } + + $this->_files[] = array('uniq' => $uniq, + 'flags' => $named_flags, + 'filename' => $dirname . $entry); + } + } + + + /** + * Close resource for mail lib. If you need to control, when the resource + * is closed. Otherwise the destructor would call this. + * + * @return void + */ + public function close() + { + $this->_files = array(); + } + + + /** + * Waste some CPU cycles doing nothing. + * + * @return void + */ + public function noop() + { + return true; + } + + + /** + * stub for not supported message deletion + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeMessage($id) + { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('maildir is (currently) read-only'); + } + + /** + * get unique id for one or all messages + * + * if storage does not support unique ids it's the same as the message number + * + * @param int|null $id message number + * @return array|string message number for given message or all messages as array + * @throws Zend_Mail_Storage_Exception + */ + public function getUniqueId($id = null) + { + if ($id) { + return $this->_getFileData($id, 'uniq'); + } + + $ids = array(); + foreach ($this->_files as $num => $file) { + $ids[$num + 1] = $file['uniq']; + } + return $ids; + } + + /** + * get a message number from a unique id + * + * I.e. if you have a webmailer that supports deleting messages you should use unique ids + * as parameter and use this method to translate it to message number right before calling removeMessage() + * + * @param string $id unique id + * @return int message number + * @throws Zend_Mail_Storage_Exception + */ + public function getNumberByUniqueId($id) + { + foreach ($this->_files as $num => $file) { + if ($file['uniq'] == $id) { + return $num + 1; + } + } + + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('unique id not found'); + } +} diff --git a/libs/Zend/Mail/Storage/Mbox.php b/libs/Zend/Mail/Storage/Mbox.php index 100a5a83d9..6f48fa2ddc 100644 --- a/libs/Zend/Mail/Storage/Mbox.php +++ b/libs/Zend/Mail/Storage/Mbox.php @@ -1,434 +1,434 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Mbox.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Loader
- * May be used in constructor, but commented out for now
- */
-// require_once 'Zend/Loader.php';
-
-/**
- * @see Zend_Mail_Storage_Abstract
- */
-require_once 'Zend/Mail/Storage/Abstract.php';
-
-/**
- * @see Zend_Mail_Message
- */
-require_once 'Zend/Mail/Message.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Mbox extends Zend_Mail_Storage_Abstract
-{
- /**
- * file handle to mbox file
- * @var null|resource
- */
- protected $_fh;
-
- /**
- * filename of mbox file for __wakeup
- * @var string
- */
- protected $_filename;
-
- /**
- * modification date of mbox file for __wakeup
- * @var int
- */
- protected $_filemtime;
-
- /**
- * start and end position of messages as array('start' => start, 'seperator' => headersep, 'end' => end)
- * @var array
- */
- protected $_positions;
-
-
- /**
- * Count messages all messages in current box
- *
- * @return int number of messages
- * @throws Zend_Mail_Storage_Exception
- */
- public function countMessages()
- {
- return count($this->_positions);
- }
-
-
- /**
- * Get a list of messages with number and size
- *
- * @param int|null $id number of message or null for all messages
- * @return int|array size of given message of list with all messages as array(num => size)
- */
- public function getSize($id = 0)
- {
- if ($id) {
- $pos = $this->_positions[$id - 1];
- return $pos['end'] - $pos['start'];
- }
-
- $result = array();
- foreach ($this->_positions as $num => $pos) {
- $result[$num + 1] = $pos['end'] - $pos['start'];
- }
-
- return $result;
- }
-
-
- /**
- * Get positions for mail message or throw exeption if id is invalid
- *
- * @param int $id number of message
- * @return array positions as in _positions
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _getPos($id)
- {
- if (!isset($this->_positions[$id - 1])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('id does not exist');
- }
-
- return $this->_positions[$id - 1];
- }
-
-
- /**
- * Fetch a message
- *
- * @param int $id number of message
- * @return Zend_Mail_Message
- * @throws Zend_Mail_Storage_Exception
- */
- public function getMessage($id)
- {
- $bodyLines = 0; // TODO: need a way to change that
-
- $message = $this->getRawHeader($id);
- // file pointer is after headers now
- if ($bodyLines) {
- $message .= "\n";
- while ($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1]['end']) {
- $message .= fgets($this->_fh);
- }
- }
-
- return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message));
- }
-
- /*
- * Get raw header of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage header
- * @param int $topLines include this many lines with header (after an empty line)
- * @return string raw header
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawHeader($id, $part = null, $topLines = 0)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
- $messagePos = $this->_getPos($id);
- // TODO: toplines
- return stream_get_contents($this->_fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']);
- }
-
- /*
- * Get raw content of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage content
- * @return string raw content
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawContent($id, $part = null)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
- $messagePos = $this->_getPos($id);
- return stream_get_contents($this->_fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']);
- }
-
- /**
- * Create instance with parameters
- * Supported parameters are:
- * - filename filename of mbox file
- *
- * @param $params array mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- if (!isset($params->filename) /* || Zend_Loader::isReadable($params['filename']) */) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('no valid filename given in params');
- }
-
- $this->_openMboxFile($params->filename);
- $this->_has['top'] = true;
- $this->_has['uniqueid'] = false;
- }
-
- /**
- * check if given file is a mbox file
- *
- * if $file is a resource its file pointer is moved after the first line
- *
- * @param resource|string $file stream resource of name of file
- * @param bool $fileIsString file is string or resource
- * @return bool file is mbox file
- */
- protected function _isMboxFile($file, $fileIsString = true)
- {
- if ($fileIsString) {
- $file = @fopen($file, 'r');
- if (!$file) {
- return false;
- }
- } else {
- fseek($file, 0);
- }
-
- $result = false;
-
- $line = fgets($file);
- if (strpos($line, 'From ') === 0) {
- $result = true;
- }
-
- if ($fileIsString) {
- @fclose($file);
- }
-
- return $result;
- }
-
- /**
- * open given file as current mbox file
- *
- * @param string $filename filename of mbox file
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _openMboxFile($filename)
- {
- if ($this->_fh) {
- $this->close();
- }
-
- $this->_fh = @fopen($filename, 'r');
- if (!$this->_fh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot open mbox file');
- }
- $this->_filename = $filename;
- $this->_filemtime = filemtime($this->_filename);
-
- if (!$this->_isMboxFile($this->_fh, false)) {
- @fclose($this->_fh);
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('file is not a valid mbox format');
- }
-
- $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
- while (($line = fgets($this->_fh)) !== false) {
- if (strpos($line, 'From ') === 0) {
- $messagePos['end'] = ftell($this->_fh) - strlen($line) - 2; // + newline
- if (!$messagePos['separator']) {
- $messagePos['separator'] = $messagePos['end'];
- }
- $this->_positions[] = $messagePos;
- $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
- }
- if (!$messagePos['separator'] && !trim($line)) {
- $messagePos['separator'] = ftell($this->_fh);
- }
- }
-
- $messagePos['end'] = ftell($this->_fh);
- if (!$messagePos['separator']) {
- $messagePos['separator'] = $messagePos['end'];
- }
- $this->_positions[] = $messagePos;
- }
-
- /**
- * Close resource for mail lib. If you need to control, when the resource
- * is closed. Otherwise the destructor would call this.
- *
- * @return void
- */
- public function close()
- {
- @fclose($this->_fh);
- $this->_positions = array();
- }
-
-
- /**
- * Waste some CPU cycles doing nothing.
- *
- * @return void
- */
- public function noop()
- {
- return true;
- }
-
-
- /**
- * stub for not supported message deletion
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeMessage($id)
- {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('mbox is read-only');
- }
-
- /**
- * get unique id for one or all messages
- *
- * Mbox does not support unique ids (yet) - it's always the same as the message number.
- * That shouldn't be a problem, because we can't change mbox files. Therefor the message
- * number is save enough.
- *
- * @param int|null $id message number
- * @return array|string message number for given message or all messages as array
- * @throws Zend_Mail_Storage_Exception
- */
- public function getUniqueId($id = null)
- {
- if ($id) {
- // check if id exists
- $this->_getPos($id);
- return $id;
- }
-
- $range = range(1, $this->countMessages());
- return array_combine($range, $range);
- }
-
- /**
- * get a message number from a unique id
- *
- * I.e. if you have a webmailer that supports deleting messages you should use unique ids
- * as parameter and use this method to translate it to message number right before calling removeMessage()
- *
- * @param string $id unique id
- * @return int message number
- * @throws Zend_Mail_Storage_Exception
- */
- public function getNumberByUniqueId($id)
- {
- // check if id exists
- $this->_getPos($id);
- return $id;
- }
-
- /**
- * magic method for serialize()
- *
- * with this method you can cache the mbox class
- *
- * @return array name of variables
- */
- public function __sleep()
- {
- return array('_filename', '_positions', '_filemtime');
- }
-
- /**
- * magic method for unserialize()
- *
- * with this method you can cache the mbox class
- * for cache validation the mtime of the mbox file is used
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function __wakeup()
- {
- if ($this->_filemtime != @filemtime($this->_filename)) {
- $this->close();
- $this->_openMboxFile($this->_filename);
- } else {
- $this->_fh = @fopen($this->_filename, 'r');
- if (!$this->_fh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot open mbox file');
- }
- }
- }
-
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Mbox.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Loader + * May be used in constructor, but commented out for now + */ +// require_once 'Zend/Loader.php'; + +/** + * @see Zend_Mail_Storage_Abstract + */ +require_once 'Zend/Mail/Storage/Abstract.php'; + +/** + * @see Zend_Mail_Message + */ +require_once 'Zend/Mail/Message.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Mbox extends Zend_Mail_Storage_Abstract +{ + /** + * file handle to mbox file + * @var null|resource + */ + protected $_fh; + + /** + * filename of mbox file for __wakeup + * @var string + */ + protected $_filename; + + /** + * modification date of mbox file for __wakeup + * @var int + */ + protected $_filemtime; + + /** + * start and end position of messages as array('start' => start, 'seperator' => headersep, 'end' => end) + * @var array + */ + protected $_positions; + + + /** + * Count messages all messages in current box + * + * @return int number of messages + * @throws Zend_Mail_Storage_Exception + */ + public function countMessages() + { + return count($this->_positions); + } + + + /** + * Get a list of messages with number and size + * + * @param int|null $id number of message or null for all messages + * @return int|array size of given message of list with all messages as array(num => size) + */ + public function getSize($id = 0) + { + if ($id) { + $pos = $this->_positions[$id - 1]; + return $pos['end'] - $pos['start']; + } + + $result = array(); + foreach ($this->_positions as $num => $pos) { + $result[$num + 1] = $pos['end'] - $pos['start']; + } + + return $result; + } + + + /** + * Get positions for mail message or throw exeption if id is invalid + * + * @param int $id number of message + * @return array positions as in _positions + * @throws Zend_Mail_Storage_Exception + */ + protected function _getPos($id) + { + if (!isset($this->_positions[$id - 1])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('id does not exist'); + } + + return $this->_positions[$id - 1]; + } + + + /** + * Fetch a message + * + * @param int $id number of message + * @return Zend_Mail_Message + * @throws Zend_Mail_Storage_Exception + */ + public function getMessage($id) + { + $bodyLines = 0; // TODO: need a way to change that + + $message = $this->getRawHeader($id); + // file pointer is after headers now + if ($bodyLines) { + $message .= "\n"; + while ($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1]['end']) { + $message .= fgets($this->_fh); + } + } + + return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message)); + } + + /* + * Get raw header of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage header + * @param int $topLines include this many lines with header (after an empty line) + * @return string raw header + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawHeader($id, $part = null, $topLines = 0) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + $messagePos = $this->_getPos($id); + // TODO: toplines + return stream_get_contents($this->_fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']); + } + + /* + * Get raw content of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage content + * @return string raw content + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawContent($id, $part = null) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + $messagePos = $this->_getPos($id); + return stream_get_contents($this->_fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']); + } + + /** + * Create instance with parameters + * Supported parameters are: + * - filename filename of mbox file + * + * @param $params array mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + if (!isset($params->filename) /* || Zend_Loader::isReadable($params['filename']) */) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('no valid filename given in params'); + } + + $this->_openMboxFile($params->filename); + $this->_has['top'] = true; + $this->_has['uniqueid'] = false; + } + + /** + * check if given file is a mbox file + * + * if $file is a resource its file pointer is moved after the first line + * + * @param resource|string $file stream resource of name of file + * @param bool $fileIsString file is string or resource + * @return bool file is mbox file + */ + protected function _isMboxFile($file, $fileIsString = true) + { + if ($fileIsString) { + $file = @fopen($file, 'r'); + if (!$file) { + return false; + } + } else { + fseek($file, 0); + } + + $result = false; + + $line = fgets($file); + if (strpos($line, 'From ') === 0) { + $result = true; + } + + if ($fileIsString) { + @fclose($file); + } + + return $result; + } + + /** + * open given file as current mbox file + * + * @param string $filename filename of mbox file + * @return null + * @throws Zend_Mail_Storage_Exception + */ + protected function _openMboxFile($filename) + { + if ($this->_fh) { + $this->close(); + } + + $this->_fh = @fopen($filename, 'r'); + if (!$this->_fh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot open mbox file'); + } + $this->_filename = $filename; + $this->_filemtime = filemtime($this->_filename); + + if (!$this->_isMboxFile($this->_fh, false)) { + @fclose($this->_fh); + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('file is not a valid mbox format'); + } + + $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0); + while (($line = fgets($this->_fh)) !== false) { + if (strpos($line, 'From ') === 0) { + $messagePos['end'] = ftell($this->_fh) - strlen($line) - 2; // + newline + if (!$messagePos['separator']) { + $messagePos['separator'] = $messagePos['end']; + } + $this->_positions[] = $messagePos; + $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0); + } + if (!$messagePos['separator'] && !trim($line)) { + $messagePos['separator'] = ftell($this->_fh); + } + } + + $messagePos['end'] = ftell($this->_fh); + if (!$messagePos['separator']) { + $messagePos['separator'] = $messagePos['end']; + } + $this->_positions[] = $messagePos; + } + + /** + * Close resource for mail lib. If you need to control, when the resource + * is closed. Otherwise the destructor would call this. + * + * @return void + */ + public function close() + { + @fclose($this->_fh); + $this->_positions = array(); + } + + + /** + * Waste some CPU cycles doing nothing. + * + * @return void + */ + public function noop() + { + return true; + } + + + /** + * stub for not supported message deletion + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeMessage($id) + { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('mbox is read-only'); + } + + /** + * get unique id for one or all messages + * + * Mbox does not support unique ids (yet) - it's always the same as the message number. + * That shouldn't be a problem, because we can't change mbox files. Therefor the message + * number is save enough. + * + * @param int|null $id message number + * @return array|string message number for given message or all messages as array + * @throws Zend_Mail_Storage_Exception + */ + public function getUniqueId($id = null) + { + if ($id) { + // check if id exists + $this->_getPos($id); + return $id; + } + + $range = range(1, $this->countMessages()); + return array_combine($range, $range); + } + + /** + * get a message number from a unique id + * + * I.e. if you have a webmailer that supports deleting messages you should use unique ids + * as parameter and use this method to translate it to message number right before calling removeMessage() + * + * @param string $id unique id + * @return int message number + * @throws Zend_Mail_Storage_Exception + */ + public function getNumberByUniqueId($id) + { + // check if id exists + $this->_getPos($id); + return $id; + } + + /** + * magic method for serialize() + * + * with this method you can cache the mbox class + * + * @return array name of variables + */ + public function __sleep() + { + return array('_filename', '_positions', '_filemtime'); + } + + /** + * magic method for unserialize() + * + * with this method you can cache the mbox class + * for cache validation the mtime of the mbox file is used + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function __wakeup() + { + if ($this->_filemtime != @filemtime($this->_filename)) { + $this->close(); + $this->_openMboxFile($this->_filename); + } else { + $this->_fh = @fopen($this->_filename, 'r'); + if (!$this->_fh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot open mbox file'); + } + } + } + +} diff --git a/libs/Zend/Mail/Storage/Pop3.php b/libs/Zend/Mail/Storage/Pop3.php index edb19026a0..707cb3f89b 100644 --- a/libs/Zend/Mail/Storage/Pop3.php +++ b/libs/Zend/Mail/Storage/Pop3.php @@ -1,328 +1,328 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Abstract
- */
-require_once 'Zend/Mail/Storage/Abstract.php';
-
-/**
- * @see Zend_Mail_Protocol_Pop3
- */
-require_once 'Zend/Mail/Protocol/Pop3.php';
-
-/**
- * @see Zend_Mail_Message
- */
-require_once 'Zend/Mail/Message.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Pop3 extends Zend_Mail_Storage_Abstract
-{
- /**
- * protocol handler
- * @var null|Zend_Mail_Protocol_Pop3
- */
- protected $_protocol;
-
-
- /**
- * Count messages all messages in current box
- *
- * @return int number of messages
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function countMessages()
- {
- $this->_protocol->status($count, $null);
- return (int)$count;
- }
-
- /**
- * get a list of messages with number and size
- *
- * @param int $id number of message
- * @return int|array size of given message of list with all messages as array(num => size)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getSize($id = 0)
- {
- $id = $id ? $id : null;
- return $this->_protocol->getList($id);
- }
-
- /**
- * Fetch a message
- *
- * @param int $id number of message
- * @return Zend_Mail_Message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getMessage($id)
- {
- $bodyLines = 0;
- $message = $this->_protocol->top($id, $bodyLines, true);
-
- return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message,
- 'noToplines' => $bodyLines < 1));
- }
-
- /*
- * Get raw header of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage header
- * @param int $topLines include this many lines with header (after an empty line)
- * @return string raw header
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawHeader($id, $part = null, $topLines = 0)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- return $this->_protocol->top($id, 0, true);
- }
-
- /*
- * Get raw content of message or part
- *
- * @param int $id number of message
- * @param null|array|string $part path to part or null for messsage content
- * @return string raw content
- * @throws Zend_Mail_Protocol_Exception
- * @throws Zend_Mail_Storage_Exception
- */
- public function getRawContent($id, $part = null)
- {
- if ($part !== null) {
- // TODO: implement
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('not implemented');
- }
-
- $content = $this->_protocol->retrieve($id);
- // TODO: find a way to avoid decoding the headers
- Zend_Mime_Decode::splitMessage($content, $null, $body);
- return $body;
- }
-
- /**
- * create instance with parameters
- * Supported paramters are
- * - host hostname or ip address of POP3 server
- * - user username
- * - password password for user 'username' [optional, default = '']
- * - port port for POP3 server [optional, default = 110]
- * - ssl 'SSL' or 'TLS' for secure sockets
- *
- * @param $params array mail reader specific parameters
- * @throws Zend_Mail_Storage_Exception
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($params)
- {
- if (is_array($params)) {
- $params = (object)$params;
- }
-
- $this->_has['fetchPart'] = false;
- $this->_has['top'] = null;
- $this->_has['uniqueid'] = null;
-
- if ($params instanceof Zend_Mail_Protocol_Pop3) {
- $this->_protocol = $params;
- return;
- }
-
- if (!isset($params->user)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('need at least user in params');
- }
-
- $host = isset($params->host) ? $params->host : 'localhost';
- $password = isset($params->password) ? $params->password : '';
- $port = isset($params->port) ? $params->port : null;
- $ssl = isset($params->ssl) ? $params->ssl : false;
-
- $this->_protocol = new Zend_Mail_Protocol_Pop3();
- $this->_protocol->connect($host, $port, $ssl);
- $this->_protocol->login($params->user, $password);
- }
-
- /**
- * Close resource for mail lib. If you need to control, when the resource
- * is closed. Otherwise the destructor would call this.
- *
- * @return null
- */
- public function close()
- {
- $this->_protocol->logout();
- }
-
- /**
- * Keep the server busy.
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function noop()
- {
- return $this->_protocol->noop();
- }
-
- /**
- * Remove a message from server. If you're doing that from a web enviroment
- * you should be careful and use a uniqueid as parameter if possible to
- * identify the message.
- *
- * @param int $id number of message
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function removeMessage($id)
- {
- $this->_protocol->delete($id);
- }
-
- /**
- * get unique id for one or all messages
- *
- * if storage does not support unique ids it's the same as the message number
- *
- * @param int|null $id message number
- * @return array|string message number for given message or all messages as array
- * @throws Zend_Mail_Storage_Exception
- */
- public function getUniqueId($id = null)
- {
- if (!$this->hasUniqueid) {
- if ($id) {
- return $id;
- }
- $count = $this->countMessages();
- if ($count < 1) {
- return array();
- }
- $range = range(1, $count);
- return array_combine($range, $range);
- }
-
- return $this->_protocol->uniqueid($id);
- }
-
- /**
- * get a message number from a unique id
- *
- * I.e. if you have a webmailer that supports deleting messages you should use unique ids
- * as parameter and use this method to translate it to message number right before calling removeMessage()
- *
- * @param string $id unique id
- * @return int message number
- * @throws Zend_Mail_Storage_Exception
- */
- public function getNumberByUniqueId($id)
- {
- if (!$this->hasUniqueid) {
- return $id;
- }
-
- $ids = $this->getUniqueId();
- foreach ($ids as $k => $v) {
- if ($v == $id) {
- return $k;
- }
- }
-
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('unique id not found');
- }
-
- /**
- * Special handling for hasTop and hasUniqueid. The headers of the first message is
- * retrieved if Top wasn't needed/tried yet.
- *
- * @see Zend_Mail_Storage_Abstract:__get()
- * @param string $var
- * @return string
- * @throws Zend_Mail_Storage_Exception
- */
- public function __get($var)
- {
- $result = parent::__get($var);
- if ($result !== null) {
- return $result;
- }
-
- if (strtolower($var) == 'hastop') {
- if ($this->_protocol->hasTop === null) {
- // need to make a real call, because not all server are honest in their capas
- try {
- $this->_protocol->top(1, 0, false);
- } catch(Zend_Mail_Exception $e) {
- // ignoring error
- }
- }
- $this->_has['top'] = $this->_protocol->hasTop;
- return $this->_protocol->hasTop;
- }
-
- if (strtolower($var) == 'hasuniqueid') {
- $id = null;
- try {
- $id = $this->_protocol->uniqueid(1);
- } catch(Zend_Mail_Exception $e) {
- // ignoring error
- }
- $this->_has['uniqueid'] = $id ? true : false;
- return $this->_has['uniqueid'];
- }
-
- return $result;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Abstract + */ +require_once 'Zend/Mail/Storage/Abstract.php'; + +/** + * @see Zend_Mail_Protocol_Pop3 + */ +require_once 'Zend/Mail/Protocol/Pop3.php'; + +/** + * @see Zend_Mail_Message + */ +require_once 'Zend/Mail/Message.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Pop3 extends Zend_Mail_Storage_Abstract +{ + /** + * protocol handler + * @var null|Zend_Mail_Protocol_Pop3 + */ + protected $_protocol; + + + /** + * Count messages all messages in current box + * + * @return int number of messages + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function countMessages() + { + $this->_protocol->status($count, $null); + return (int)$count; + } + + /** + * get a list of messages with number and size + * + * @param int $id number of message + * @return int|array size of given message of list with all messages as array(num => size) + * @throws Zend_Mail_Protocol_Exception + */ + public function getSize($id = 0) + { + $id = $id ? $id : null; + return $this->_protocol->getList($id); + } + + /** + * Fetch a message + * + * @param int $id number of message + * @return Zend_Mail_Message + * @throws Zend_Mail_Protocol_Exception + */ + public function getMessage($id) + { + $bodyLines = 0; + $message = $this->_protocol->top($id, $bodyLines, true); + + return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message, + 'noToplines' => $bodyLines < 1)); + } + + /* + * Get raw header of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage header + * @param int $topLines include this many lines with header (after an empty line) + * @return string raw header + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawHeader($id, $part = null, $topLines = 0) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + return $this->_protocol->top($id, 0, true); + } + + /* + * Get raw content of message or part + * + * @param int $id number of message + * @param null|array|string $part path to part or null for messsage content + * @return string raw content + * @throws Zend_Mail_Protocol_Exception + * @throws Zend_Mail_Storage_Exception + */ + public function getRawContent($id, $part = null) + { + if ($part !== null) { + // TODO: implement + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('not implemented'); + } + + $content = $this->_protocol->retrieve($id); + // TODO: find a way to avoid decoding the headers + Zend_Mime_Decode::splitMessage($content, $null, $body); + return $body; + } + + /** + * create instance with parameters + * Supported paramters are + * - host hostname or ip address of POP3 server + * - user username + * - password password for user 'username' [optional, default = ''] + * - port port for POP3 server [optional, default = 110] + * - ssl 'SSL' or 'TLS' for secure sockets + * + * @param $params array mail reader specific parameters + * @throws Zend_Mail_Storage_Exception + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($params) + { + if (is_array($params)) { + $params = (object)$params; + } + + $this->_has['fetchPart'] = false; + $this->_has['top'] = null; + $this->_has['uniqueid'] = null; + + if ($params instanceof Zend_Mail_Protocol_Pop3) { + $this->_protocol = $params; + return; + } + + if (!isset($params->user)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('need at least user in params'); + } + + $host = isset($params->host) ? $params->host : 'localhost'; + $password = isset($params->password) ? $params->password : ''; + $port = isset($params->port) ? $params->port : null; + $ssl = isset($params->ssl) ? $params->ssl : false; + + $this->_protocol = new Zend_Mail_Protocol_Pop3(); + $this->_protocol->connect($host, $port, $ssl); + $this->_protocol->login($params->user, $password); + } + + /** + * Close resource for mail lib. If you need to control, when the resource + * is closed. Otherwise the destructor would call this. + * + * @return null + */ + public function close() + { + $this->_protocol->logout(); + } + + /** + * Keep the server busy. + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function noop() + { + return $this->_protocol->noop(); + } + + /** + * Remove a message from server. If you're doing that from a web enviroment + * you should be careful and use a uniqueid as parameter if possible to + * identify the message. + * + * @param int $id number of message + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function removeMessage($id) + { + $this->_protocol->delete($id); + } + + /** + * get unique id for one or all messages + * + * if storage does not support unique ids it's the same as the message number + * + * @param int|null $id message number + * @return array|string message number for given message or all messages as array + * @throws Zend_Mail_Storage_Exception + */ + public function getUniqueId($id = null) + { + if (!$this->hasUniqueid) { + if ($id) { + return $id; + } + $count = $this->countMessages(); + if ($count < 1) { + return array(); + } + $range = range(1, $count); + return array_combine($range, $range); + } + + return $this->_protocol->uniqueid($id); + } + + /** + * get a message number from a unique id + * + * I.e. if you have a webmailer that supports deleting messages you should use unique ids + * as parameter and use this method to translate it to message number right before calling removeMessage() + * + * @param string $id unique id + * @return int message number + * @throws Zend_Mail_Storage_Exception + */ + public function getNumberByUniqueId($id) + { + if (!$this->hasUniqueid) { + return $id; + } + + $ids = $this->getUniqueId(); + foreach ($ids as $k => $v) { + if ($v == $id) { + return $k; + } + } + + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('unique id not found'); + } + + /** + * Special handling for hasTop and hasUniqueid. The headers of the first message is + * retrieved if Top wasn't needed/tried yet. + * + * @see Zend_Mail_Storage_Abstract:__get() + * @param string $var + * @return string + * @throws Zend_Mail_Storage_Exception + */ + public function __get($var) + { + $result = parent::__get($var); + if ($result !== null) { + return $result; + } + + if (strtolower($var) == 'hastop') { + if ($this->_protocol->hasTop === null) { + // need to make a real call, because not all server are honest in their capas + try { + $this->_protocol->top(1, 0, false); + } catch(Zend_Mail_Exception $e) { + // ignoring error + } + } + $this->_has['top'] = $this->_protocol->hasTop; + return $this->_protocol->hasTop; + } + + if (strtolower($var) == 'hasuniqueid') { + $id = null; + try { + $id = $this->_protocol->uniqueid(1); + } catch(Zend_Mail_Exception $e) { + // ignoring error + } + $this->_has['uniqueid'] = $id ? true : false; + return $this->_has['uniqueid']; + } + + return $result; + } +} diff --git a/libs/Zend/Mail/Storage/Writable/Interface.php b/libs/Zend/Mail/Storage/Writable/Interface.php index 8454f9c54c..7eb4aba106 100644 --- a/libs/Zend/Mail/Storage/Writable/Interface.php +++ b/libs/Zend/Mail/Storage/Writable/Interface.php @@ -1,98 +1,98 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Interface.php 8928 2008-03-20 19:41:41Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-interface Zend_Mail_Storage_Writable_Interface
-{
- /**
- * create a new folder
- *
- * This method also creates parent folders if necessary. Some mail storages may restrict, which folder
- * may be used as parent or which chars may be used in the folder name
- *
- * @param string $name global name of folder, local name if $parentFolder is set
- * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function createFolder($name, $parentFolder = null);
-
- /**
- * remove a folder
- *
- * @param string|Zend_Mail_Storage_Folder $name name or instance of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeFolder($name);
-
- /**
- * rename and/or move folder
- *
- * The new name has the same restrictions as in createFolder()
- *
- * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
- * @param string $newName new global name of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function renameFolder($oldName, $newName);
-
- /**
- * append a new message to mail storage
- *
- * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
- * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
- * @param null|array $flags set flags for new message, else a default set is used
- * @throws Zend_Mail_Storage_Exception
- */
- public function appendMessage($message, $folder = null, $flags = null);
-
- /**
- * copy an existing message
- *
- * @param int $id number of message
- * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function copyMessage($id, $folder);
-
- /**
- * set flags for message
- *
- * NOTE: this method can't set the recent flag.
- *
- * @param int $id number of message
- * @param array $flags new flags for message
- * @throws Zend_Mail_Storage_Exception
- */
- public function setFlags($id, $flags);
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Interface.php 8928 2008-03-20 19:41:41Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +interface Zend_Mail_Storage_Writable_Interface +{ + /** + * create a new folder + * + * This method also creates parent folders if necessary. Some mail storages may restrict, which folder + * may be used as parent or which chars may be used in the folder name + * + * @param string $name global name of folder, local name if $parentFolder is set + * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function createFolder($name, $parentFolder = null); + + /** + * remove a folder + * + * @param string|Zend_Mail_Storage_Folder $name name or instance of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeFolder($name); + + /** + * rename and/or move folder + * + * The new name has the same restrictions as in createFolder() + * + * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder + * @param string $newName new global name of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function renameFolder($oldName, $newName); + + /** + * append a new message to mail storage + * + * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class + * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken + * @param null|array $flags set flags for new message, else a default set is used + * @throws Zend_Mail_Storage_Exception + */ + public function appendMessage($message, $folder = null, $flags = null); + + /** + * copy an existing message + * + * @param int $id number of message + * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function copyMessage($id, $folder); + + /** + * set flags for message + * + * NOTE: this method can't set the recent flag. + * + * @param int $id number of message + * @param array $flags new flags for message + * @throws Zend_Mail_Storage_Exception + */ + public function setFlags($id, $flags); +} diff --git a/libs/Zend/Mail/Storage/Writable/Maildir.php b/libs/Zend/Mail/Storage/Writable/Maildir.php index b43ad4c2df..506b1c66e5 100644 --- a/libs/Zend/Mail/Storage/Writable/Maildir.php +++ b/libs/Zend/Mail/Storage/Writable/Maildir.php @@ -1,912 +1,912 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Storage_Folder_Maildir
- */
-require_once 'Zend/Mail/Storage/Folder/Maildir.php';
-
-/**
- * @see Zend_Mail_Storage_Writable_Interface
- */
-require_once 'Zend/Mail/Storage/Writable/Interface.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Storage
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Storage_Writable_Maildir extends Zend_Mail_Storage_Folder_Maildir
- implements Zend_Mail_Storage_Writable_Interface
-{
- /**
- * use quota and size of quota if given
- * @var bool|int
- */
- protected $_quota;
-
- /**
- * create a new folder
- *
- * This method also creates parent folders if necessary. Some mail storages may restrict, which folder
- * may be used as parent or which chars may be used in the folder name
- *
- * @param string $name global name of folder, local name if $parentFolder is set
- * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent
- * @return string only used internally (new created maildir)
- * @throws Zend_Mail_Storage_Exception
- */
- public function createFolder($name, $parentFolder = null)
- {
- if ($parentFolder instanceof Zend_Mail_Storage_Folder) {
- $folder = $parentFolder->getGlobalName() . $this->_delim . $name;
- } else if ($parentFolder != null) {
- $folder = rtrim($parentFolder, $this->_delim) . $this->_delim . $name;
- } else {
- $folder = $name;
- }
-
- $folder = trim($folder, $this->_delim);
-
- // first we check if we try to create a folder that does exist
- $exists = null;
- try {
- $exists = $this->getFolders($folder);
- } catch (Zend_Mail_Exception $e) {
- // ok
- }
- if ($exists) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('folder already exists');
- }
-
- if (strpos($folder, $this->_delim . $this->_delim) !== false) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('invalid name - folder parts may not be empty');
- }
-
- if (strpos($folder, 'INBOX' . $this->_delim) === 0) {
- $folder = substr($folder, 6);
- }
-
- $fulldir = $this->_rootdir . '.' . $folder;
-
- // check if we got tricked and would create a dir outside of the rootdir or not as direct child
- if (strpos($folder, DIRECTORY_SEPARATOR) !== false || strpos($folder, '/') !== false
- || dirname($fulldir) . DIRECTORY_SEPARATOR != $this->_rootdir) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('invalid name - no directory seprator allowed in folder name');
- }
-
- // has a parent folder?
- $parent = null;
- if (strpos($folder, $this->_delim)) {
- // let's see if the parent folder exists
- $parent = substr($folder, 0, strrpos($folder, $this->_delim));
- try {
- $this->getFolders($parent);
- } catch (Zend_Mail_Exception $e) {
- // does not - create parent folder
- $this->createFolder($parent);
- }
- }
-
- if (!@mkdir($fulldir) || !@mkdir($fulldir . DIRECTORY_SEPARATOR . 'cur')) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('error while creating new folder, may be created incompletly');
- }
-
- mkdir($fulldir . DIRECTORY_SEPARATOR . 'new');
- mkdir($fulldir . DIRECTORY_SEPARATOR . 'tmp');
-
- $localName = $parent ? substr($folder, strlen($parent) + 1) : $folder;
- $this->getFolders($parent)->$localName = new Zend_Mail_Storage_Folder($localName, $folder, true);
-
- return $fulldir;
- }
-
- /**
- * remove a folder
- *
- * @param string|Zend_Mail_Storage_Folder $name name or instance of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeFolder($name)
- {
- // TODO: This could fail in the middle of the task, which is not optimal.
- // But there is no defined standard way to mark a folder as removed and there is no atomar fs-op
- // to remove a directory. Also moving the folder to a/the trash folder is not possible, as
- // all parent folders must be created. What we could do is add a dash to the front of the
- // directory name and it should be ignored as long as other processes obey the standard.
-
- if ($name instanceof Zend_Mail_Storage_Folder) {
- $name = $name->getGlobalName();
- }
-
- $name = trim($name, $this->_delim);
- if (strpos($name, 'INBOX' . $this->_delim) === 0) {
- $name = substr($name, 6);
- }
-
- // check if folder exists and has no children
- if (!$this->getFolders($name)->isLeaf()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('delete children first');
- }
-
- if ($name == 'INBOX' || $name == DIRECTORY_SEPARATOR || $name == '/') {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('wont delete INBOX');
- }
-
- if ($name == $this->getCurrentFolder()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('wont delete selected folder');
- }
-
- foreach (array('tmp', 'new', 'cur', '.') as $subdir) {
- $dir = $this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . $subdir;
- if (!file_exists($dir)) {
- continue;
- }
- $dh = opendir($dir);
- if (!$dh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("error opening $subdir");
- }
- while (($entry = readdir($dh)) !== false) {
- if ($entry == '.' || $entry == '..') {
- continue;
- }
- if (!unlink($dir . DIRECTORY_SEPARATOR . $entry)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("error cleaning $subdir");
- }
- }
- closedir($dh);
- if ($subdir !== '.') {
- if (!rmdir($dir)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("error removing $subdir");
- }
- }
- }
-
- if (!rmdir($this->_rootdir . '.' . $name)) {
- // at least we should try to make it a valid maildir again
- mkdir($this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . 'cur');
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("error removing maindir");
- }
-
- $parent = strpos($name, $this->_delim) ? substr($name, 0, strrpos($name, $this->_delim)) : null;
- $localName = $parent ? substr($name, strlen($parent) + 1) : $name;
- unset($this->getFolders($parent)->$localName);
- }
-
- /**
- * rename and/or move folder
- *
- * The new name has the same restrictions as in createFolder()
- *
- * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder
- * @param string $newName new global name of folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function renameFolder($oldName, $newName)
- {
- // TODO: This is also not atomar and has similar problems as removeFolder()
-
- if ($oldName instanceof Zend_Mail_Storage_Folder) {
- $oldName = $oldName->getGlobalName();
- }
-
- $oldName = trim($oldName, $this->_delim);
- if (strpos($oldName, 'INBOX' . $this->_delim) === 0) {
- $oldName = substr($oldName, 6);
- }
-
- $newName = trim($newName, $this->_delim);
- if (strpos($newName, 'INBOX' . $this->_delim) === 0) {
- $newName = substr($newName, 6);
- }
-
- if (strpos($newName, $oldName . $this->_delim) === 0) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('new folder cannot be a child of old folder');
- }
-
- // check if folder exists and has no children
- $folder = $this->getFolders($oldName);
-
- if ($oldName == 'INBOX' || $oldName == DIRECTORY_SEPARATOR || $oldName == '/') {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('wont rename INBOX');
- }
-
- if ($oldName == $this->getCurrentFolder()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('wont rename selected folder');
- }
-
- $newdir = $this->createFolder($newName);
-
- if (!$folder->isLeaf()) {
- foreach ($folder as $k => $v) {
- $this->renameFolder($v->getGlobalName(), $newName . $this->_delim . $k);
- }
- }
-
- $olddir = $this->_rootdir . '.' . $folder;
- foreach (array('tmp', 'new', 'cur') as $subdir) {
- $subdir = DIRECTORY_SEPARATOR . $subdir;
- if (!file_exists($olddir . $subdir)) {
- continue;
- }
- // using copy or moving files would be even better - but also much slower
- if (!rename($olddir . $subdir, $newdir . $subdir)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('error while moving ' . $subdir);
- }
- }
- // create a dummy if removing fails - otherwise we can't read it next time
- mkdir($olddir . DIRECTORY_SEPARATOR . 'cur');
- $this->removeFolder($oldName);
- }
-
- /**
- * create a uniqueid for maildir filename
- *
- * This is nearly the format defined in the maildir standard. The microtime() call should already
- * create a uniqueid, the pid is for multicore/-cpu machine that manage to call this function at the
- * exact same time, and uname() gives us the hostname for multiple machines accessing the same storage.
- *
- * If someone disables posix we create a random number of the same size, so this method should also
- * work on Windows - if you manage to get maildir working on Windows.
- * Microtime could also be disabled, altough I've never seen it.
- *
- * @return string new uniqueid
- */
- protected function _createUniqueId()
- {
- $id = '';
- $id .= function_exists('microtime') ? microtime(true) : (time() . ' ' . rand(0, 100000));
- $id .= '.' . (function_exists('posix_getpid') ? posix_getpid() : rand(50, 65535));
- $id .= '.' . php_uname('n');
-
- return $id;
- }
-
- /**
- * open a temporary maildir file
- *
- * makes sure tmp/ exists and create a file with a unique name
- * you should close the returned filehandle!
- *
- * @param string $folder name of current folder without leading .
- * @return array array('dirname' => dir of maildir folder, 'uniq' => unique id, 'filename' => name of create file
- * 'handle' => file opened for writing)
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _createTmpFile($folder = 'INBOX')
- {
- if ($folder == 'INBOX') {
- $tmpdir = $this->_rootdir . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
- } else {
- $tmpdir = $this->_rootdir . '.' . $folder . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
- }
- if (!file_exists($tmpdir)) {
- if (!mkdir($tmpdir)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('problems creating tmp dir');
- }
- }
-
- // we should retry to create a unique id if a file with the same name exists
- // to avoid a script timeout we only wait 1 second (instead of 2) and stop
- // after a defined retry count
- // if you change this variable take into account that it can take up to $max_tries seconds
- // normally we should have a valid unique name after the first try, we're just following the "standard" here
- $max_tries = 5;
- for ($i = 0; $i < $max_tries; ++$i) {
- $uniq = $this->_createUniqueId();
- if (!file_exists($tmpdir . $uniq)) {
- // here is the race condition! - as defined in the standard
- // to avoid having a long time between stat()ing the file and creating it we're opening it here
- // to mark the filename as taken
- $fh = fopen($tmpdir . $uniq, 'w');
- if (!$fh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('could not open temp file');
- }
- break;
- }
- sleep(1);
- }
-
- if (!$fh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception("tried $max_tries unique ids for a temp file, but all were taken"
- . ' - giving up');
- }
-
- return array('dirname' => $this->_rootdir . '.' . $folder, 'uniq' => $uniq, 'filename' => $tmpdir . $uniq,
- 'handle' => $fh);
- }
-
- /**
- * create an info string for filenames with given flags
- *
- * @param array $flags wanted flags, with the reference you'll get the set flags with correct key (= char for flag)
- * @return string info string for version 2 filenames including the leading colon
- * @throws Zend_Mail_Storage_Exception
- */
- protected function _getInfoString(&$flags)
- {
- // accessing keys is easier, faster and it removes duplicated flags
- $wanted_flags = array_flip($flags);
- if (isset($wanted_flags[Zend_Mail_Storage::FLAG_RECENT])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('recent flag may not be set');
- }
-
- $info = ':2,';
- $flags = array();
- foreach (Zend_Mail_Storage_Maildir::$_knownFlags as $char => $flag) {
- if (!isset($wanted_flags[$flag])) {
- continue;
- }
- $info .= $char;
- $flags[$char] = $flag;
- unset($wanted_flags[$flag]);
- }
-
- if (!empty($wanted_flags)) {
- $wanted_flags = implode(', ', array_keys($wanted_flags));
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('unknown flag(s): ' . $wanted_flags);
- }
-
- return $info;
- }
-
- /**
- * append a new message to mail storage
- *
- * @param string|stream $message message as string or stream resource
- * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken
- * @param null|array $flags set flags for new message, else a default set is used
- * @param bool $recent handle this mail as if recent flag has been set,
- * should only be used in delivery
- * @throws Zend_Mail_Storage_Exception
- */
- // not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class
-
- public function appendMessage($message, $folder = null, $flags = null, $recent = false)
- {
- if ($this->_quota && $this->checkQuota()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('storage is over quota!');
- }
-
- if ($folder === null) {
- $folder = $this->_currentFolder;
- }
-
- if (!($folder instanceof Zend_Mail_Storage_Folder)) {
- $folder = $this->getFolders($folder);
- }
-
- if ($flags === null) {
- $flags = array(Zend_Mail_Storage::FLAG_SEEN);
- }
- $info = $this->_getInfoString($flags);
- $temp_file = $this->_createTmpFile($folder->getGlobalName());
-
- // TODO: handle class instances for $message
- if (is_resource($message) && get_resource_type($message) == 'stream') {
- stream_copy_to_stream($message, $temp_file['handle']);
- } else {
- fputs($temp_file['handle'], $message);
- }
- fclose($temp_file['handle']);
-
- // we're adding the size to the filename for maildir++
- $size = filesize($temp_file['filename']);
- if ($size) {
- $info = ',S=' . $size . $info;
- }
- $new_filename = $temp_file['dirname'] . DIRECTORY_SEPARATOR;
- $new_filename .= $recent ? 'new' : 'cur';
- $new_filename .= DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info;
-
- // we're throwing any exception after removing our temp file and saving it to this variable instead
- $exception = null;
-
- if (!link($temp_file['filename'], $new_filename)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- $exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir');
- }
- @unlink($temp_file['filename']);
-
- if ($exception) {
- throw $exception;
- }
-
- $this->_files[] = array('uniq' => $temp_file['uniq'],
- 'flags' => $flags,
- 'filename' => $new_filename);
- if ($this->_quota) {
- $this->_addQuotaEntry((int)$size, 1);
- }
- }
-
- /**
- * copy an existing message
- *
- * @param int $id number of message
- * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function copyMessage($id, $folder)
- {
- if ($this->_quota && $this->checkQuota()) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('storage is over quota!');
- }
-
- if (!($folder instanceof Zend_Mail_Storage_Folder)) {
- $folder = $this->getFolders($folder);
- }
-
- $filedata = $this->_getFileData($id);
- $old_file = $filedata['filename'];
- $flags = $filedata['flags'];
-
- // copied message can't be recent
- while (($key = array_search(Zend_Mail_Storage::FLAG_RECENT, $flags)) !== false) {
- unset($flags[$key]);
- }
- $info = $this->_getInfoString($flags);
-
- // we're creating the copy as temp file before moving to cur/
- $temp_file = $this->_createTmpFile($folder->getGlobalName());
- // we don't write directly to the file
- fclose($temp_file['handle']);
-
- // we're adding the size to the filename for maildir++
- // TODO: maybe we should support maildirsize or we just let the MDA do the work
- $size = filesize($old_file);
- if ($size) {
- $info = ',S=' . $size . $info;
- }
- $new_file = $temp_file['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info;
-
- // we're throwing any exception after removing our temp file and saving it to this variable instead
- $exception = null;
-
- if (!copy($old_file, $temp_file['filename'])) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- $exception = new Zend_Mail_Storage_Exception('cannot copy message file');
- } else if (!link($temp_file['filename'], $new_file)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- $exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir');
- }
- @unlink($temp_file['filename']);
-
- if ($exception) {
- throw $exception;
- }
-
- if ($folder->getGlobalName() == $this->_currentFolder
- || ($this->_currentFolder == 'INBOX' && $folder->getGlobalName() == '/')) {
- $this->_files[] = array('uniq' => $temp_file['uniq'],
- 'flags' => $flags,
- 'filename' => $new_file);
- }
-
- if ($this->_quota) {
- $this->_addQuotaEntry((int)$size, 1);
- }
- }
-
- /**
- * set flags for message
- *
- * NOTE: this method can't set the recent flag.
- *
- * @param int $id number of message
- * @param array $flags new flags for message
- * @throws Zend_Mail_Storage_Exception
- */
- public function setFlags($id, $flags)
- {
- $info = $this->_getInfoString($flags);
- $filedata = $this->_getFileData($id);
-
- // TODO: move file from new to cur
- $new_filename = dirname($filedata['filename']) . DIRECTORY_SEPARATOR . "$filedata[uniq]$info";
-
- if (!@rename($filedata['filename'], $new_filename)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot rename file');
- }
-
- $filedata['flags'] = $flags;
- $filedata['filename'] = $new_filename;
-
- $this->_files[$id - 1] = $filedata;
- }
-
-
- /**
- * stub for not supported message deletion
- *
- * @return null
- * @throws Zend_Mail_Storage_Exception
- */
- public function removeMessage($id)
- {
- $filename = $this->_getFileData($id, 'filename');
-
- if ($this->_quota) {
- $size = filesize($filename);
- }
-
- if (!@unlink($filename)) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot remove message');
- }
- unset($this->_files[$id - 1]);
- // remove the gap
- $this->_files = array_values($this->_files);
- if ($this->_quota) {
- $this->_addQuotaEntry(0 - (int)$size, -1);
- }
- }
-
- /**
- * enable/disable quota and set a quota value if wanted or needed
- *
- * You can enable/disable quota with true/false. If you don't have
- * a MDA or want to enforce a quota value you can also set this value
- * here. Use array('size' => SIZE_QUOTA, 'count' => MAX_MESSAGE) do
- * define your quota. Order of these fields does matter!
- *
- * @param bool|array $value new quota value
- * @return null
- */
- public function setQuota($value) {
- $this->_quota = $value;
- }
-
- /**
- * get currently set quota
- *
- * @see Zend_Mail_Storage_Writable_Maildir::setQuota()
- *
- * @return bool|array
- */
- public function getQuota($fromStorage = false) {
- if ($fromStorage) {
- $fh = @fopen($this->_rootdir . 'maildirsize', 'r');
- if (!$fh) {
- /**
- * @see Zend_Mail_Storage_Exception
- */
- require_once 'Zend/Mail/Storage/Exception.php';
- throw new Zend_Mail_Storage_Exception('cannot open maildirsize');
- }
- $definition = fgets($fh);
- fclose($fh);
- $definition = explode(',', trim($definition));
- $quota = array();
- foreach ($definition as $member) {
- $key = $member[strlen($member) - 1];
- if ($key == 'S' || $key == 'C') {
- $key = $key == 'C' ? 'count' : 'size';
- }
- $quota[$key] = substr($member, 0, -1);
- }
- return $quota;
- }
-
- return $this->_quota;
- }
-
- /**
- * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating maildirsize"
- */
- protected function _calculateMaildirsize() {
- $timestamps = array();
- $messages = 0;
- $total_size = 0;
-
- if (is_array($this->_quota)) {
- $quota = $this->_quota;
- } else {
- try {
- $quota = $this->getQuota(true);
- } catch (Zend_Mail_Storage_Exception $e) {
- throw new Zend_Mail_Storage_Exception('no quota defintion found');
- }
- }
-
- $folders = new RecursiveIteratorIterator($this->getFolders(), RecursiveIteratorIterator::SELF_FIRST);
- foreach ($folders as $folder) {
- $subdir = $folder->getGlobalName();
- if ($subdir == 'INBOX') {
- $subdir = '';
- } else {
- $subdir = '.' . $subdir;
- }
- if ($subdir == 'Trash') {
- continue;
- }
-
- foreach (array('cur', 'new') as $subsubdir) {
- $dirname = $this->_rootdir . $subdir . DIRECTORY_SEPARATOR . $subsubdir . DIRECTORY_SEPARATOR;
- if (!file_exists($dirname)) {
- continue;
- }
- // NOTE: we are using mtime instead of "the latest timestamp". The latest would be atime
- // and as we are accessing the directory it would make the whole calculation useless.
- $timestamps[$dirname] = filemtime($dirname);
-
- $dh = opendir($dirname);
- // NOTE: Should have been checked in constructor. Not throwing an exception here, quotas will
- // therefore not be fully enforeced, but next request will fail anyway, if problem persists.
- if (!$dh) {
- continue;
- }
-
-
- while (($entry = readdir()) !== false) {
- if ($entry[0] == '.' || !is_file($dirname . $entry)) {
- continue;
- }
-
- if (strpos($entry, ',S=')) {
- strtok($entry, '=');
- $filesize = strtok(':');
- if (is_numeric($filesize)) {
- $total_size += $filesize;
- ++$messages;
- continue;
- }
- }
- $size = filesize($dirname . $entry);
- if ($size === false) {
- // ignore, as we assume file got removed
- continue;
- }
- $total_size += $size;
- ++$messages;
- }
- }
- }
-
- $tmp = $this->_createTmpFile();
- $fh = $tmp['handle'];
- $definition = array();
- foreach ($quota as $type => $value) {
- if ($type == 'size' || $type == 'count') {
- $type = $type == 'count' ? 'C' : 'S';
- }
- $definition[] = $value . $type;
- }
- $definition = implode(',', $definition);
- fputs($fh, "$definition\n");
- fputs($fh, "$total_size $messages\n");
- fclose($fh);
- rename($tmp['filename'], $this->_rootdir . 'maildirsize');
- foreach ($timestamps as $dir => $timestamp) {
- if ($timestamp < filemtime($dir)) {
- unlink($this->_rootdir . 'maildirsize');
- break;
- }
- }
-
- return array('size' => $total_size, 'count' => $messages, 'quota' => $quota);
- }
-
- /**
- * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating the quota for a Maildir++"
- */
- protected function _calculateQuota($forceRecalc = false) {
- $fh = null;
- $total_size = 0;
- $messages = 0;
- $maildirsize = '';
- if (!$forceRecalc && file_exists($this->_rootdir . 'maildirsize') && filesize($this->_rootdir . 'maildirsize') < 5120) {
- $fh = fopen($this->_rootdir . 'maildirsize', 'r');
- }
- if ($fh) {
- $maildirsize = fread($fh, 5120);
- if (strlen($maildirsize) >= 5120) {
- fclose($fh);
- $fh = null;
- $maildirsize = '';
- }
- }
-
- if (!$fh) {
- $result = $this->_calculateMaildirsize();
- $total_size = $result['size'];
- $messages = $result['count'];
- $quota = $result['quota'];
- } else {
- $maildirsize = explode("\n", $maildirsize);
- if (is_array($this->_quota)) {
- $quota = $this->_quota;
- } else {
- $definition = explode(',', $maildirsize[0]);
- $quota = array();
- foreach ($definition as $member) {
- $key = $member[strlen($member) - 1];
- if ($key == 'S' || $key == 'C') {
- $key = $key == 'C' ? 'count' : 'size';
- }
- $quota[$key] = substr($member, 0, -1);
- }
- }
- unset($maildirsize[0]);
- foreach ($maildirsize as $line) {
- list($size, $count) = explode(' ', trim($line));
- $total_size += $size;
- $messages += $count;
- }
- }
-
- $over_quota = false;
- $over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']);
- $over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']);
- // NOTE: $maildirsize equals false if it wasn't set (AKA we recalculated) or it's only
- // one line, because $maildirsize[0] gets unsetted.
- // Also we're using local time to calculate the 15 minute offset. Touching a file just for known the
- // local time of the file storage isn't worth the hassle.
- if ($over_quota && ($maildirsize || filemtime($this->_rootdir . 'maildirsize') > time() - 900)) {
- $result = $this->_calculateMaildirsize();
- $total_size = $result['size'];
- $messages = $result['count'];
- $quota = $result['quota'];
- $over_quota = false;
- $over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']);
- $over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']);
- }
-
- if ($fh) {
- // TODO is there a safe way to keep the handle open for writing?
- fclose($fh);
- }
-
- return array('size' => $total_size, 'count' => $messages, 'quota' => $quota, 'over_quota' => $over_quota);
- }
-
- protected function _addQuotaEntry($size, $count = 1) {
- if (!file_exists($this->_rootdir . 'maildirsize')) {
- // TODO: should get file handler from _calculateQuota
- }
- $size = (int)$size;
- $count = (int)$count;
- file_put_contents($this->_rootdir . 'maildirsize', "$size $count\n", FILE_APPEND);
- }
-
- /**
- * check if storage is currently over quota
- *
- * @param bool $detailedResponse return known data of quota and current size and message count @see _calculateQuota()
- * @return bool|array over quota state or detailed response
- */
- public function checkQuota($detailedResponse = false, $forceRecalc = false) {
- $result = $this->_calculateQuota($forceRecalc);
- return $detailedResponse ? $result : $result['over_quota'];
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Maildir.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Storage_Folder_Maildir + */ +require_once 'Zend/Mail/Storage/Folder/Maildir.php'; + +/** + * @see Zend_Mail_Storage_Writable_Interface + */ +require_once 'Zend/Mail/Storage/Writable/Interface.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Storage + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Storage_Writable_Maildir extends Zend_Mail_Storage_Folder_Maildir + implements Zend_Mail_Storage_Writable_Interface +{ + /** + * use quota and size of quota if given + * @var bool|int + */ + protected $_quota; + + /** + * create a new folder + * + * This method also creates parent folders if necessary. Some mail storages may restrict, which folder + * may be used as parent or which chars may be used in the folder name + * + * @param string $name global name of folder, local name if $parentFolder is set + * @param string|Zend_Mail_Storage_Folder $parentFolder parent folder for new folder, else root folder is parent + * @return string only used internally (new created maildir) + * @throws Zend_Mail_Storage_Exception + */ + public function createFolder($name, $parentFolder = null) + { + if ($parentFolder instanceof Zend_Mail_Storage_Folder) { + $folder = $parentFolder->getGlobalName() . $this->_delim . $name; + } else if ($parentFolder != null) { + $folder = rtrim($parentFolder, $this->_delim) . $this->_delim . $name; + } else { + $folder = $name; + } + + $folder = trim($folder, $this->_delim); + + // first we check if we try to create a folder that does exist + $exists = null; + try { + $exists = $this->getFolders($folder); + } catch (Zend_Mail_Exception $e) { + // ok + } + if ($exists) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('folder already exists'); + } + + if (strpos($folder, $this->_delim . $this->_delim) !== false) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('invalid name - folder parts may not be empty'); + } + + if (strpos($folder, 'INBOX' . $this->_delim) === 0) { + $folder = substr($folder, 6); + } + + $fulldir = $this->_rootdir . '.' . $folder; + + // check if we got tricked and would create a dir outside of the rootdir or not as direct child + if (strpos($folder, DIRECTORY_SEPARATOR) !== false || strpos($folder, '/') !== false + || dirname($fulldir) . DIRECTORY_SEPARATOR != $this->_rootdir) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('invalid name - no directory seprator allowed in folder name'); + } + + // has a parent folder? + $parent = null; + if (strpos($folder, $this->_delim)) { + // let's see if the parent folder exists + $parent = substr($folder, 0, strrpos($folder, $this->_delim)); + try { + $this->getFolders($parent); + } catch (Zend_Mail_Exception $e) { + // does not - create parent folder + $this->createFolder($parent); + } + } + + if (!@mkdir($fulldir) || !@mkdir($fulldir . DIRECTORY_SEPARATOR . 'cur')) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('error while creating new folder, may be created incompletly'); + } + + mkdir($fulldir . DIRECTORY_SEPARATOR . 'new'); + mkdir($fulldir . DIRECTORY_SEPARATOR . 'tmp'); + + $localName = $parent ? substr($folder, strlen($parent) + 1) : $folder; + $this->getFolders($parent)->$localName = new Zend_Mail_Storage_Folder($localName, $folder, true); + + return $fulldir; + } + + /** + * remove a folder + * + * @param string|Zend_Mail_Storage_Folder $name name or instance of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeFolder($name) + { + // TODO: This could fail in the middle of the task, which is not optimal. + // But there is no defined standard way to mark a folder as removed and there is no atomar fs-op + // to remove a directory. Also moving the folder to a/the trash folder is not possible, as + // all parent folders must be created. What we could do is add a dash to the front of the + // directory name and it should be ignored as long as other processes obey the standard. + + if ($name instanceof Zend_Mail_Storage_Folder) { + $name = $name->getGlobalName(); + } + + $name = trim($name, $this->_delim); + if (strpos($name, 'INBOX' . $this->_delim) === 0) { + $name = substr($name, 6); + } + + // check if folder exists and has no children + if (!$this->getFolders($name)->isLeaf()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('delete children first'); + } + + if ($name == 'INBOX' || $name == DIRECTORY_SEPARATOR || $name == '/') { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('wont delete INBOX'); + } + + if ($name == $this->getCurrentFolder()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('wont delete selected folder'); + } + + foreach (array('tmp', 'new', 'cur', '.') as $subdir) { + $dir = $this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . $subdir; + if (!file_exists($dir)) { + continue; + } + $dh = opendir($dir); + if (!$dh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("error opening $subdir"); + } + while (($entry = readdir($dh)) !== false) { + if ($entry == '.' || $entry == '..') { + continue; + } + if (!unlink($dir . DIRECTORY_SEPARATOR . $entry)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("error cleaning $subdir"); + } + } + closedir($dh); + if ($subdir !== '.') { + if (!rmdir($dir)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("error removing $subdir"); + } + } + } + + if (!rmdir($this->_rootdir . '.' . $name)) { + // at least we should try to make it a valid maildir again + mkdir($this->_rootdir . '.' . $name . DIRECTORY_SEPARATOR . 'cur'); + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("error removing maindir"); + } + + $parent = strpos($name, $this->_delim) ? substr($name, 0, strrpos($name, $this->_delim)) : null; + $localName = $parent ? substr($name, strlen($parent) + 1) : $name; + unset($this->getFolders($parent)->$localName); + } + + /** + * rename and/or move folder + * + * The new name has the same restrictions as in createFolder() + * + * @param string|Zend_Mail_Storage_Folder $oldName name or instance of folder + * @param string $newName new global name of folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function renameFolder($oldName, $newName) + { + // TODO: This is also not atomar and has similar problems as removeFolder() + + if ($oldName instanceof Zend_Mail_Storage_Folder) { + $oldName = $oldName->getGlobalName(); + } + + $oldName = trim($oldName, $this->_delim); + if (strpos($oldName, 'INBOX' . $this->_delim) === 0) { + $oldName = substr($oldName, 6); + } + + $newName = trim($newName, $this->_delim); + if (strpos($newName, 'INBOX' . $this->_delim) === 0) { + $newName = substr($newName, 6); + } + + if (strpos($newName, $oldName . $this->_delim) === 0) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('new folder cannot be a child of old folder'); + } + + // check if folder exists and has no children + $folder = $this->getFolders($oldName); + + if ($oldName == 'INBOX' || $oldName == DIRECTORY_SEPARATOR || $oldName == '/') { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('wont rename INBOX'); + } + + if ($oldName == $this->getCurrentFolder()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('wont rename selected folder'); + } + + $newdir = $this->createFolder($newName); + + if (!$folder->isLeaf()) { + foreach ($folder as $k => $v) { + $this->renameFolder($v->getGlobalName(), $newName . $this->_delim . $k); + } + } + + $olddir = $this->_rootdir . '.' . $folder; + foreach (array('tmp', 'new', 'cur') as $subdir) { + $subdir = DIRECTORY_SEPARATOR . $subdir; + if (!file_exists($olddir . $subdir)) { + continue; + } + // using copy or moving files would be even better - but also much slower + if (!rename($olddir . $subdir, $newdir . $subdir)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('error while moving ' . $subdir); + } + } + // create a dummy if removing fails - otherwise we can't read it next time + mkdir($olddir . DIRECTORY_SEPARATOR . 'cur'); + $this->removeFolder($oldName); + } + + /** + * create a uniqueid for maildir filename + * + * This is nearly the format defined in the maildir standard. The microtime() call should already + * create a uniqueid, the pid is for multicore/-cpu machine that manage to call this function at the + * exact same time, and uname() gives us the hostname for multiple machines accessing the same storage. + * + * If someone disables posix we create a random number of the same size, so this method should also + * work on Windows - if you manage to get maildir working on Windows. + * Microtime could also be disabled, altough I've never seen it. + * + * @return string new uniqueid + */ + protected function _createUniqueId() + { + $id = ''; + $id .= function_exists('microtime') ? microtime(true) : (time() . ' ' . rand(0, 100000)); + $id .= '.' . (function_exists('posix_getpid') ? posix_getpid() : rand(50, 65535)); + $id .= '.' . php_uname('n'); + + return $id; + } + + /** + * open a temporary maildir file + * + * makes sure tmp/ exists and create a file with a unique name + * you should close the returned filehandle! + * + * @param string $folder name of current folder without leading . + * @return array array('dirname' => dir of maildir folder, 'uniq' => unique id, 'filename' => name of create file + * 'handle' => file opened for writing) + * @throws Zend_Mail_Storage_Exception + */ + protected function _createTmpFile($folder = 'INBOX') + { + if ($folder == 'INBOX') { + $tmpdir = $this->_rootdir . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR; + } else { + $tmpdir = $this->_rootdir . '.' . $folder . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR; + } + if (!file_exists($tmpdir)) { + if (!mkdir($tmpdir)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('problems creating tmp dir'); + } + } + + // we should retry to create a unique id if a file with the same name exists + // to avoid a script timeout we only wait 1 second (instead of 2) and stop + // after a defined retry count + // if you change this variable take into account that it can take up to $max_tries seconds + // normally we should have a valid unique name after the first try, we're just following the "standard" here + $max_tries = 5; + for ($i = 0; $i < $max_tries; ++$i) { + $uniq = $this->_createUniqueId(); + if (!file_exists($tmpdir . $uniq)) { + // here is the race condition! - as defined in the standard + // to avoid having a long time between stat()ing the file and creating it we're opening it here + // to mark the filename as taken + $fh = fopen($tmpdir . $uniq, 'w'); + if (!$fh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('could not open temp file'); + } + break; + } + sleep(1); + } + + if (!$fh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception("tried $max_tries unique ids for a temp file, but all were taken" + . ' - giving up'); + } + + return array('dirname' => $this->_rootdir . '.' . $folder, 'uniq' => $uniq, 'filename' => $tmpdir . $uniq, + 'handle' => $fh); + } + + /** + * create an info string for filenames with given flags + * + * @param array $flags wanted flags, with the reference you'll get the set flags with correct key (= char for flag) + * @return string info string for version 2 filenames including the leading colon + * @throws Zend_Mail_Storage_Exception + */ + protected function _getInfoString(&$flags) + { + // accessing keys is easier, faster and it removes duplicated flags + $wanted_flags = array_flip($flags); + if (isset($wanted_flags[Zend_Mail_Storage::FLAG_RECENT])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('recent flag may not be set'); + } + + $info = ':2,'; + $flags = array(); + foreach (Zend_Mail_Storage_Maildir::$_knownFlags as $char => $flag) { + if (!isset($wanted_flags[$flag])) { + continue; + } + $info .= $char; + $flags[$char] = $flag; + unset($wanted_flags[$flag]); + } + + if (!empty($wanted_flags)) { + $wanted_flags = implode(', ', array_keys($wanted_flags)); + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('unknown flag(s): ' . $wanted_flags); + } + + return $info; + } + + /** + * append a new message to mail storage + * + * @param string|stream $message message as string or stream resource + * @param null|string|Zend_Mail_Storage_Folder $folder folder for new message, else current folder is taken + * @param null|array $flags set flags for new message, else a default set is used + * @param bool $recent handle this mail as if recent flag has been set, + * should only be used in delivery + * @throws Zend_Mail_Storage_Exception + */ + // not yet * @param string|Zend_Mail_Message|Zend_Mime_Message $message message as string or instance of message class + + public function appendMessage($message, $folder = null, $flags = null, $recent = false) + { + if ($this->_quota && $this->checkQuota()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('storage is over quota!'); + } + + if ($folder === null) { + $folder = $this->_currentFolder; + } + + if (!($folder instanceof Zend_Mail_Storage_Folder)) { + $folder = $this->getFolders($folder); + } + + if ($flags === null) { + $flags = array(Zend_Mail_Storage::FLAG_SEEN); + } + $info = $this->_getInfoString($flags); + $temp_file = $this->_createTmpFile($folder->getGlobalName()); + + // TODO: handle class instances for $message + if (is_resource($message) && get_resource_type($message) == 'stream') { + stream_copy_to_stream($message, $temp_file['handle']); + } else { + fputs($temp_file['handle'], $message); + } + fclose($temp_file['handle']); + + // we're adding the size to the filename for maildir++ + $size = filesize($temp_file['filename']); + if ($size) { + $info = ',S=' . $size . $info; + } + $new_filename = $temp_file['dirname'] . DIRECTORY_SEPARATOR; + $new_filename .= $recent ? 'new' : 'cur'; + $new_filename .= DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info; + + // we're throwing any exception after removing our temp file and saving it to this variable instead + $exception = null; + + if (!link($temp_file['filename'], $new_filename)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + $exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir'); + } + @unlink($temp_file['filename']); + + if ($exception) { + throw $exception; + } + + $this->_files[] = array('uniq' => $temp_file['uniq'], + 'flags' => $flags, + 'filename' => $new_filename); + if ($this->_quota) { + $this->_addQuotaEntry((int)$size, 1); + } + } + + /** + * copy an existing message + * + * @param int $id number of message + * @param string|Zend_Mail_Storage_Folder $folder name or instance of targer folder + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function copyMessage($id, $folder) + { + if ($this->_quota && $this->checkQuota()) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('storage is over quota!'); + } + + if (!($folder instanceof Zend_Mail_Storage_Folder)) { + $folder = $this->getFolders($folder); + } + + $filedata = $this->_getFileData($id); + $old_file = $filedata['filename']; + $flags = $filedata['flags']; + + // copied message can't be recent + while (($key = array_search(Zend_Mail_Storage::FLAG_RECENT, $flags)) !== false) { + unset($flags[$key]); + } + $info = $this->_getInfoString($flags); + + // we're creating the copy as temp file before moving to cur/ + $temp_file = $this->_createTmpFile($folder->getGlobalName()); + // we don't write directly to the file + fclose($temp_file['handle']); + + // we're adding the size to the filename for maildir++ + // TODO: maybe we should support maildirsize or we just let the MDA do the work + $size = filesize($old_file); + if ($size) { + $info = ',S=' . $size . $info; + } + $new_file = $temp_file['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $temp_file['uniq'] . $info; + + // we're throwing any exception after removing our temp file and saving it to this variable instead + $exception = null; + + if (!copy($old_file, $temp_file['filename'])) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + $exception = new Zend_Mail_Storage_Exception('cannot copy message file'); + } else if (!link($temp_file['filename'], $new_file)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + $exception = new Zend_Mail_Storage_Exception('cannot link message file to final dir'); + } + @unlink($temp_file['filename']); + + if ($exception) { + throw $exception; + } + + if ($folder->getGlobalName() == $this->_currentFolder + || ($this->_currentFolder == 'INBOX' && $folder->getGlobalName() == '/')) { + $this->_files[] = array('uniq' => $temp_file['uniq'], + 'flags' => $flags, + 'filename' => $new_file); + } + + if ($this->_quota) { + $this->_addQuotaEntry((int)$size, 1); + } + } + + /** + * set flags for message + * + * NOTE: this method can't set the recent flag. + * + * @param int $id number of message + * @param array $flags new flags for message + * @throws Zend_Mail_Storage_Exception + */ + public function setFlags($id, $flags) + { + $info = $this->_getInfoString($flags); + $filedata = $this->_getFileData($id); + + // TODO: move file from new to cur + $new_filename = dirname($filedata['filename']) . DIRECTORY_SEPARATOR . "$filedata[uniq]$info"; + + if (!@rename($filedata['filename'], $new_filename)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot rename file'); + } + + $filedata['flags'] = $flags; + $filedata['filename'] = $new_filename; + + $this->_files[$id - 1] = $filedata; + } + + + /** + * stub for not supported message deletion + * + * @return null + * @throws Zend_Mail_Storage_Exception + */ + public function removeMessage($id) + { + $filename = $this->_getFileData($id, 'filename'); + + if ($this->_quota) { + $size = filesize($filename); + } + + if (!@unlink($filename)) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot remove message'); + } + unset($this->_files[$id - 1]); + // remove the gap + $this->_files = array_values($this->_files); + if ($this->_quota) { + $this->_addQuotaEntry(0 - (int)$size, -1); + } + } + + /** + * enable/disable quota and set a quota value if wanted or needed + * + * You can enable/disable quota with true/false. If you don't have + * a MDA or want to enforce a quota value you can also set this value + * here. Use array('size' => SIZE_QUOTA, 'count' => MAX_MESSAGE) do + * define your quota. Order of these fields does matter! + * + * @param bool|array $value new quota value + * @return null + */ + public function setQuota($value) { + $this->_quota = $value; + } + + /** + * get currently set quota + * + * @see Zend_Mail_Storage_Writable_Maildir::setQuota() + * + * @return bool|array + */ + public function getQuota($fromStorage = false) { + if ($fromStorage) { + $fh = @fopen($this->_rootdir . 'maildirsize', 'r'); + if (!$fh) { + /** + * @see Zend_Mail_Storage_Exception + */ + require_once 'Zend/Mail/Storage/Exception.php'; + throw new Zend_Mail_Storage_Exception('cannot open maildirsize'); + } + $definition = fgets($fh); + fclose($fh); + $definition = explode(',', trim($definition)); + $quota = array(); + foreach ($definition as $member) { + $key = $member[strlen($member) - 1]; + if ($key == 'S' || $key == 'C') { + $key = $key == 'C' ? 'count' : 'size'; + } + $quota[$key] = substr($member, 0, -1); + } + return $quota; + } + + return $this->_quota; + } + + /** + * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating maildirsize" + */ + protected function _calculateMaildirsize() { + $timestamps = array(); + $messages = 0; + $total_size = 0; + + if (is_array($this->_quota)) { + $quota = $this->_quota; + } else { + try { + $quota = $this->getQuota(true); + } catch (Zend_Mail_Storage_Exception $e) { + throw new Zend_Mail_Storage_Exception('no quota defintion found'); + } + } + + $folders = new RecursiveIteratorIterator($this->getFolders(), RecursiveIteratorIterator::SELF_FIRST); + foreach ($folders as $folder) { + $subdir = $folder->getGlobalName(); + if ($subdir == 'INBOX') { + $subdir = ''; + } else { + $subdir = '.' . $subdir; + } + if ($subdir == 'Trash') { + continue; + } + + foreach (array('cur', 'new') as $subsubdir) { + $dirname = $this->_rootdir . $subdir . DIRECTORY_SEPARATOR . $subsubdir . DIRECTORY_SEPARATOR; + if (!file_exists($dirname)) { + continue; + } + // NOTE: we are using mtime instead of "the latest timestamp". The latest would be atime + // and as we are accessing the directory it would make the whole calculation useless. + $timestamps[$dirname] = filemtime($dirname); + + $dh = opendir($dirname); + // NOTE: Should have been checked in constructor. Not throwing an exception here, quotas will + // therefore not be fully enforeced, but next request will fail anyway, if problem persists. + if (!$dh) { + continue; + } + + + while (($entry = readdir()) !== false) { + if ($entry[0] == '.' || !is_file($dirname . $entry)) { + continue; + } + + if (strpos($entry, ',S=')) { + strtok($entry, '='); + $filesize = strtok(':'); + if (is_numeric($filesize)) { + $total_size += $filesize; + ++$messages; + continue; + } + } + $size = filesize($dirname . $entry); + if ($size === false) { + // ignore, as we assume file got removed + continue; + } + $total_size += $size; + ++$messages; + } + } + } + + $tmp = $this->_createTmpFile(); + $fh = $tmp['handle']; + $definition = array(); + foreach ($quota as $type => $value) { + if ($type == 'size' || $type == 'count') { + $type = $type == 'count' ? 'C' : 'S'; + } + $definition[] = $value . $type; + } + $definition = implode(',', $definition); + fputs($fh, "$definition\n"); + fputs($fh, "$total_size $messages\n"); + fclose($fh); + rename($tmp['filename'], $this->_rootdir . 'maildirsize'); + foreach ($timestamps as $dir => $timestamp) { + if ($timestamp < filemtime($dir)) { + unlink($this->_rootdir . 'maildirsize'); + break; + } + } + + return array('size' => $total_size, 'count' => $messages, 'quota' => $quota); + } + + /** + * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating the quota for a Maildir++" + */ + protected function _calculateQuota($forceRecalc = false) { + $fh = null; + $total_size = 0; + $messages = 0; + $maildirsize = ''; + if (!$forceRecalc && file_exists($this->_rootdir . 'maildirsize') && filesize($this->_rootdir . 'maildirsize') < 5120) { + $fh = fopen($this->_rootdir . 'maildirsize', 'r'); + } + if ($fh) { + $maildirsize = fread($fh, 5120); + if (strlen($maildirsize) >= 5120) { + fclose($fh); + $fh = null; + $maildirsize = ''; + } + } + + if (!$fh) { + $result = $this->_calculateMaildirsize(); + $total_size = $result['size']; + $messages = $result['count']; + $quota = $result['quota']; + } else { + $maildirsize = explode("\n", $maildirsize); + if (is_array($this->_quota)) { + $quota = $this->_quota; + } else { + $definition = explode(',', $maildirsize[0]); + $quota = array(); + foreach ($definition as $member) { + $key = $member[strlen($member) - 1]; + if ($key == 'S' || $key == 'C') { + $key = $key == 'C' ? 'count' : 'size'; + } + $quota[$key] = substr($member, 0, -1); + } + } + unset($maildirsize[0]); + foreach ($maildirsize as $line) { + list($size, $count) = explode(' ', trim($line)); + $total_size += $size; + $messages += $count; + } + } + + $over_quota = false; + $over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']); + $over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']); + // NOTE: $maildirsize equals false if it wasn't set (AKA we recalculated) or it's only + // one line, because $maildirsize[0] gets unsetted. + // Also we're using local time to calculate the 15 minute offset. Touching a file just for known the + // local time of the file storage isn't worth the hassle. + if ($over_quota && ($maildirsize || filemtime($this->_rootdir . 'maildirsize') > time() - 900)) { + $result = $this->_calculateMaildirsize(); + $total_size = $result['size']; + $messages = $result['count']; + $quota = $result['quota']; + $over_quota = false; + $over_quota = $over_quota || (isset($quota['size']) && $total_size > $quota['size']); + $over_quota = $over_quota || (isset($quota['count']) && $messages > $quota['count']); + } + + if ($fh) { + // TODO is there a safe way to keep the handle open for writing? + fclose($fh); + } + + return array('size' => $total_size, 'count' => $messages, 'quota' => $quota, 'over_quota' => $over_quota); + } + + protected function _addQuotaEntry($size, $count = 1) { + if (!file_exists($this->_rootdir . 'maildirsize')) { + // TODO: should get file handler from _calculateQuota + } + $size = (int)$size; + $count = (int)$count; + file_put_contents($this->_rootdir . 'maildirsize', "$size $count\n", FILE_APPEND); + } + + /** + * check if storage is currently over quota + * + * @param bool $detailedResponse return known data of quota and current size and message count @see _calculateQuota() + * @return bool|array over quota state or detailed response + */ + public function checkQuota($detailedResponse = false, $forceRecalc = false) { + $result = $this->_calculateQuota($forceRecalc); + return $detailedResponse ? $result : $result['over_quota']; + } +} diff --git a/libs/Zend/Mail/Transport/Abstract.php b/libs/Zend/Mail/Transport/Abstract.php index 188fb13ac2..603411a596 100644 --- a/libs/Zend/Mail/Transport/Abstract.php +++ b/libs/Zend/Mail/Transport/Abstract.php @@ -1,350 +1,350 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-
-/**
- * Abstract for sending eMails through different
- * ways of transport
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-abstract class Zend_Mail_Transport_Abstract
-{
- /**
- * Mail body
- * @var string
- * @access public
- */
- public $body = '';
-
- /**
- * MIME boundary
- * @var string
- * @access public
- */
- public $boundary = '';
-
- /**
- * Mail header string
- * @var string
- * @access public
- */
- public $header = '';
-
- /**
- * Array of message headers
- * @var array
- * @access protected
- */
- protected $_headers = array();
-
- /**
- * Message is a multipart message
- * @var boolean
- * @access protected
- */
- protected $_isMultipart = false;
-
- /**
- * Zend_Mail object
- * @var false|Zend_Mail
- * @access protected
- */
- protected $_mail = false;
-
- /**
- * Array of message parts
- * @var array
- * @access protected
- */
- protected $_parts = array();
-
- /**
- * Recipients string
- * @var string
- * @access public
- */
- public $recipients = '';
-
- /**
- * EOL character string used by transport
- * @var string
- * @access public
- */
- public $EOL = "\r\n";
-
- /**
- * Send an email independent from the used transport
- *
- * The requisite information for the email will be found in the following
- * properties:
- *
- * - {@link $recipients} - list of recipients (string)
- * - {@link $header} - message header
- * - {@link $body} - message body
- */
- abstract protected function _sendMail();
-
- /**
- * Return all mail headers as an array
- *
- * If a boundary is given, a multipart header is generated with a
- * Content-Type of either multipart/alternative or multipart/mixed depending
- * on the mail parts present in the {@link $_mail Zend_Mail object} present.
- *
- * @param string $boundary
- * @return array
- */
- protected function _getHeaders($boundary)
- {
- if (null !== $boundary) {
- // Build multipart mail
- $type = $this->_mail->getType();
- if (!$type) {
- if ($this->_mail->hasAttachments) {
- $type = Zend_Mime::MULTIPART_MIXED;
- } elseif ($this->_mail->getBodyText() && $this->_mail->getBodyHtml()) {
- $type = Zend_Mime::MULTIPART_ALTERNATIVE;
- } else {
- $type = Zend_Mime::MULTIPART_MIXED;
- }
- }
-
- $this->_headers['Content-Type'] = array(
- $type . '; charset="' . $this->_mail->getCharset() . '";'
- . $this->EOL
- . " " . 'boundary="' . $boundary . '"'
- );
- $this->_headers['MIME-Version'] = array('1.0');
-
- $this->boundary = $boundary;
- }
-
- return $this->_headers;
- }
-
- /**
- * Prepend header name to header value
- *
- * @param string $item
- * @param string $key
- * @param string $prefix
- * @static
- * @access protected
- * @return void
- */
- protected static function _formatHeader(&$item, $key, $prefix)
- {
- $item = $prefix . ': ' . $item;
- }
-
- /**
- * Prepare header string for use in transport
- *
- * Prepares and generates {@link $header} based on the headers provided.
- *
- * @param mixed $headers
- * @access protected
- * @return void
- * @throws Zend_Mail_Transport_Exception if any header lines exceed 998
- * characters
- */
- protected function _prepareHeaders($headers)
- {
- if (!$this->_mail) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('Missing Zend_Mail object in _mail property');
- }
-
- $this->header = '';
-
- foreach ($headers as $header => $content) {
- if (isset($content['append'])) {
- unset($content['append']);
- $value = implode(',' . $this->EOL . ' ', $content);
- $this->header .= $header . ': ' . $value . $this->EOL;
- } else {
- array_walk($content, array(get_class($this), '_formatHeader'), $header);
- $this->header .= implode($this->EOL, $content) . $this->EOL;
- }
- }
-
- // Sanity check on headers -- should not be > 998 characters
- $sane = true;
- foreach (explode($this->EOL, $this->header) as $line) {
- if (strlen(trim($line)) > 998) {
- $sane = false;
- break;
- }
- }
- if (!$sane) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Exception('At least one mail header line is too long');
- }
- }
-
- /**
- * Generate MIME compliant message from the current configuration
- *
- * If both a text and HTML body are present, generates a
- * multipart/alternative Zend_Mime_Part containing the headers and contents
- * of each. Otherwise, uses whichever of the text or HTML parts present.
- *
- * The content part is then prepended to the list of Zend_Mime_Parts for
- * this message.
- *
- * @return void
- */
- protected function _buildBody()
- {
- if (($text = $this->_mail->getBodyText())
- && ($html = $this->_mail->getBodyHtml()))
- {
- // Generate unique boundary for multipart/alternative
- $mime = new Zend_Mime(null);
- $boundaryLine = $mime->boundaryLine($this->EOL);
- $boundaryEnd = $mime->mimeEnd($this->EOL);
-
- $text->disposition = false;
- $html->disposition = false;
-
- $body = $boundaryLine
- . $text->getHeaders($this->EOL)
- . $this->EOL
- . $text->getContent($this->EOL)
- . $this->EOL
- . $boundaryLine
- . $html->getHeaders($this->EOL)
- . $this->EOL
- . $html->getContent($this->EOL)
- . $this->EOL
- . $boundaryEnd;
-
- $mp = new Zend_Mime_Part($body);
- $mp->type = Zend_Mime::MULTIPART_ALTERNATIVE;
- $mp->boundary = $mime->boundary();
-
- $this->_isMultipart = true;
-
- // Ensure first part contains text alternatives
- array_unshift($this->_parts, $mp);
-
- // Get headers
- $this->_headers = $this->_mail->getHeaders();
- return;
- }
-
- // If not multipart, then get the body
- if (false !== ($body = $this->_mail->getBodyHtml())) {
- array_unshift($this->_parts, $body);
- } elseif (false !== ($body = $this->_mail->getBodyText())) {
- array_unshift($this->_parts, $body);
- }
-
- if (!$body) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('No body specified');
- }
-
- // Get headers
- $this->_headers = $this->_mail->getHeaders();
- $headers = $body->getHeadersArray($this->EOL);
- foreach ($headers as $header) {
- // Headers in Zend_Mime_Part are kept as arrays with two elements, a
- // key and a value
- $this->_headers[$header[0]] = array($header[1]);
- }
- }
-
- /**
- * Send a mail using this transport
- *
- * @param Zend_Mail $mail
- * @access public
- * @return void
- * @throws Zend_Mail_Transport_Exception if mail is empty
- */
- public function send(Zend_Mail $mail)
- {
- $this->_isMultipart = false;
- $this->_mail = $mail;
- $this->_parts = $mail->getParts();
- $mime = $mail->getMime();
-
- // Build body content
- $this->_buildBody();
-
- // Determine number of parts and boundary
- $count = count($this->_parts);
- $boundary = null;
- if ($count < 1) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('Empty mail cannot be sent');
- }
-
- if ($count > 1) {
- // Multipart message; create new MIME object and boundary
- $mime = new Zend_Mime($this->_mail->getMimeBoundary());
- $boundary = $mime->boundary();
- } elseif ($this->_isMultipart) {
- // multipart/alternative -- grab boundary
- $boundary = $this->_parts[0]->boundary;
- }
-
- // Determine recipients, and prepare headers
- $this->recipients = implode(',', $mail->getRecipients());
- $this->_prepareHeaders($this->_getHeaders($boundary));
-
- // Create message body
- // This is done so that the same Zend_Mail object can be used in
- // multiple transports
- $message = new Zend_Mime_Message();
- $message->setParts($this->_parts);
- $message->setMime($mime);
- $this->body = $message->generateMessage($this->EOL);
-
- // Send to transport!
- $this->_sendMail();
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + + +/** + * Abstract for sending eMails through different + * ways of transport + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +abstract class Zend_Mail_Transport_Abstract +{ + /** + * Mail body + * @var string + * @access public + */ + public $body = ''; + + /** + * MIME boundary + * @var string + * @access public + */ + public $boundary = ''; + + /** + * Mail header string + * @var string + * @access public + */ + public $header = ''; + + /** + * Array of message headers + * @var array + * @access protected + */ + protected $_headers = array(); + + /** + * Message is a multipart message + * @var boolean + * @access protected + */ + protected $_isMultipart = false; + + /** + * Zend_Mail object + * @var false|Zend_Mail + * @access protected + */ + protected $_mail = false; + + /** + * Array of message parts + * @var array + * @access protected + */ + protected $_parts = array(); + + /** + * Recipients string + * @var string + * @access public + */ + public $recipients = ''; + + /** + * EOL character string used by transport + * @var string + * @access public + */ + public $EOL = "\r\n"; + + /** + * Send an email independent from the used transport + * + * The requisite information for the email will be found in the following + * properties: + * + * - {@link $recipients} - list of recipients (string) + * - {@link $header} - message header + * - {@link $body} - message body + */ + abstract protected function _sendMail(); + + /** + * Return all mail headers as an array + * + * If a boundary is given, a multipart header is generated with a + * Content-Type of either multipart/alternative or multipart/mixed depending + * on the mail parts present in the {@link $_mail Zend_Mail object} present. + * + * @param string $boundary + * @return array + */ + protected function _getHeaders($boundary) + { + if (null !== $boundary) { + // Build multipart mail + $type = $this->_mail->getType(); + if (!$type) { + if ($this->_mail->hasAttachments) { + $type = Zend_Mime::MULTIPART_MIXED; + } elseif ($this->_mail->getBodyText() && $this->_mail->getBodyHtml()) { + $type = Zend_Mime::MULTIPART_ALTERNATIVE; + } else { + $type = Zend_Mime::MULTIPART_MIXED; + } + } + + $this->_headers['Content-Type'] = array( + $type . '; charset="' . $this->_mail->getCharset() . '";' + . $this->EOL + . " " . 'boundary="' . $boundary . '"' + ); + $this->_headers['MIME-Version'] = array('1.0'); + + $this->boundary = $boundary; + } + + return $this->_headers; + } + + /** + * Prepend header name to header value + * + * @param string $item + * @param string $key + * @param string $prefix + * @static + * @access protected + * @return void + */ + protected static function _formatHeader(&$item, $key, $prefix) + { + $item = $prefix . ': ' . $item; + } + + /** + * Prepare header string for use in transport + * + * Prepares and generates {@link $header} based on the headers provided. + * + * @param mixed $headers + * @access protected + * @return void + * @throws Zend_Mail_Transport_Exception if any header lines exceed 998 + * characters + */ + protected function _prepareHeaders($headers) + { + if (!$this->_mail) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('Missing Zend_Mail object in _mail property'); + } + + $this->header = ''; + + foreach ($headers as $header => $content) { + if (isset($content['append'])) { + unset($content['append']); + $value = implode(',' . $this->EOL . ' ', $content); + $this->header .= $header . ': ' . $value . $this->EOL; + } else { + array_walk($content, array(get_class($this), '_formatHeader'), $header); + $this->header .= implode($this->EOL, $content) . $this->EOL; + } + } + + // Sanity check on headers -- should not be > 998 characters + $sane = true; + foreach (explode($this->EOL, $this->header) as $line) { + if (strlen(trim($line)) > 998) { + $sane = false; + break; + } + } + if (!$sane) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Exception('At least one mail header line is too long'); + } + } + + /** + * Generate MIME compliant message from the current configuration + * + * If both a text and HTML body are present, generates a + * multipart/alternative Zend_Mime_Part containing the headers and contents + * of each. Otherwise, uses whichever of the text or HTML parts present. + * + * The content part is then prepended to the list of Zend_Mime_Parts for + * this message. + * + * @return void + */ + protected function _buildBody() + { + if (($text = $this->_mail->getBodyText()) + && ($html = $this->_mail->getBodyHtml())) + { + // Generate unique boundary for multipart/alternative + $mime = new Zend_Mime(null); + $boundaryLine = $mime->boundaryLine($this->EOL); + $boundaryEnd = $mime->mimeEnd($this->EOL); + + $text->disposition = false; + $html->disposition = false; + + $body = $boundaryLine + . $text->getHeaders($this->EOL) + . $this->EOL + . $text->getContent($this->EOL) + . $this->EOL + . $boundaryLine + . $html->getHeaders($this->EOL) + . $this->EOL + . $html->getContent($this->EOL) + . $this->EOL + . $boundaryEnd; + + $mp = new Zend_Mime_Part($body); + $mp->type = Zend_Mime::MULTIPART_ALTERNATIVE; + $mp->boundary = $mime->boundary(); + + $this->_isMultipart = true; + + // Ensure first part contains text alternatives + array_unshift($this->_parts, $mp); + + // Get headers + $this->_headers = $this->_mail->getHeaders(); + return; + } + + // If not multipart, then get the body + if (false !== ($body = $this->_mail->getBodyHtml())) { + array_unshift($this->_parts, $body); + } elseif (false !== ($body = $this->_mail->getBodyText())) { + array_unshift($this->_parts, $body); + } + + if (!$body) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('No body specified'); + } + + // Get headers + $this->_headers = $this->_mail->getHeaders(); + $headers = $body->getHeadersArray($this->EOL); + foreach ($headers as $header) { + // Headers in Zend_Mime_Part are kept as arrays with two elements, a + // key and a value + $this->_headers[$header[0]] = array($header[1]); + } + } + + /** + * Send a mail using this transport + * + * @param Zend_Mail $mail + * @access public + * @return void + * @throws Zend_Mail_Transport_Exception if mail is empty + */ + public function send(Zend_Mail $mail) + { + $this->_isMultipart = false; + $this->_mail = $mail; + $this->_parts = $mail->getParts(); + $mime = $mail->getMime(); + + // Build body content + $this->_buildBody(); + + // Determine number of parts and boundary + $count = count($this->_parts); + $boundary = null; + if ($count < 1) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('Empty mail cannot be sent'); + } + + if ($count > 1) { + // Multipart message; create new MIME object and boundary + $mime = new Zend_Mime($this->_mail->getMimeBoundary()); + $boundary = $mime->boundary(); + } elseif ($this->_isMultipart) { + // multipart/alternative -- grab boundary + $boundary = $this->_parts[0]->boundary; + } + + // Determine recipients, and prepare headers + $this->recipients = implode(',', $mail->getRecipients()); + $this->_prepareHeaders($this->_getHeaders($boundary)); + + // Create message body + // This is done so that the same Zend_Mail object can be used in + // multiple transports + $message = new Zend_Mime_Message(); + $message->setParts($this->_parts); + $message->setMime($mime); + $this->body = $message->generateMessage($this->EOL); + + // Send to transport! + $this->_sendMail(); + } +} diff --git a/libs/Zend/Mail/Transport/Exception.php b/libs/Zend/Mail/Transport/Exception.php index a49f74c165..16ef2401cd 100644 --- a/libs/Zend/Mail/Transport/Exception.php +++ b/libs/Zend/Mail/Transport/Exception.php @@ -1,39 +1,39 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Exception
- */
-require_once 'Zend/Mail/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Transport_Exception extends Zend_Mail_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Exception + */ +require_once 'Zend/Mail/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Transport_Exception extends Zend_Mail_Exception +{} + diff --git a/libs/Zend/Mail/Transport/Sendmail.php b/libs/Zend/Mail/Transport/Sendmail.php index 08099f82b8..651df3c14c 100644 --- a/libs/Zend/Mail/Transport/Sendmail.php +++ b/libs/Zend/Mail/Transport/Sendmail.php @@ -1,170 +1,170 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Sendmail.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Transport_Abstract
- */
-require_once 'Zend/Mail/Transport/Abstract.php';
-
-
-/**
- * Class for sending eMails via the PHP internal mail() function
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Transport_Sendmail extends Zend_Mail_Transport_Abstract
-{
- /**
- * Subject
- * @var string
- * @access public
- */
- public $subject = null;
-
-
- /**
- * Config options for sendmail parameters
- *
- * @var string
- */
- public $parameters;
-
-
- /**
- * EOL character string
- * @var string
- * @access public
- */
- public $EOL = PHP_EOL;
-
-
- /**
- * Constructor.
- *
- * @param string $parameters OPTIONAL (Default: null)
- * @return void
- */
- public function __construct($parameters = null)
- {
- $this->parameters = $parameters;
- }
-
-
- /**
- * Send mail using PHP native mail()
- *
- * @access public
- * @return void
- * @throws Zend_Mail_Transport_Exception on mail() failure
- */
- public function _sendMail()
- {
- if ($this->parameters === null) {
- $result = mail(
- $this->recipients,
- $this->_mail->getSubject(),
- $this->body,
- $this->header);
- } else {
- $result = mail(
- $this->recipients,
- $this->_mail->getSubject(),
- $this->body,
- $this->header,
- $this->parameters);
- }
- if (!$result) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('Unable to send mail');
- }
- }
-
-
- /**
- * Format and fix headers
- *
- * mail() uses its $to and $subject arguments to set the To: and Subject:
- * headers, respectively. This method strips those out as a sanity check to
- * prevent duplicate header entries.
- *
- * @access protected
- * @param array $headers
- * @return void
- * @throws Zend_Mail_Transport_Exception
- */
- protected function _prepareHeaders($headers)
- {
- if (!$this->_mail) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object');
- }
-
- // mail() uses its $to parameter to set the To: header, and the $subject
- // parameter to set the Subject: header. We need to strip them out.
- if (0 === strpos(PHP_OS, 'WIN')) {
- // If the current recipients list is empty, throw an error
- if (empty($this->recipients)) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('Missing To addresses');
- }
- } else {
- // All others, simply grab the recipients and unset the To: header
- if (!isset($headers['To'])) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('Missing To header');
- }
-
- unset($headers['To']['append']);
- $this->recipients = implode(',', $headers['To']);
- }
-
- // Remove recipient header
- unset($headers['To']);
-
- // Remove subject header, if present
- if (isset($headers['Subject'])) {
- unset($headers['Subject']);
- }
-
- // Prepare headers
- parent::_prepareHeaders($headers);
- }
-
-}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Sendmail.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Transport_Abstract + */ +require_once 'Zend/Mail/Transport/Abstract.php'; + + +/** + * Class for sending eMails via the PHP internal mail() function + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Transport_Sendmail extends Zend_Mail_Transport_Abstract +{ + /** + * Subject + * @var string + * @access public + */ + public $subject = null; + + + /** + * Config options for sendmail parameters + * + * @var string + */ + public $parameters; + + + /** + * EOL character string + * @var string + * @access public + */ + public $EOL = PHP_EOL; + + + /** + * Constructor. + * + * @param string $parameters OPTIONAL (Default: null) + * @return void + */ + public function __construct($parameters = null) + { + $this->parameters = $parameters; + } + + + /** + * Send mail using PHP native mail() + * + * @access public + * @return void + * @throws Zend_Mail_Transport_Exception on mail() failure + */ + public function _sendMail() + { + if ($this->parameters === null) { + $result = mail( + $this->recipients, + $this->_mail->getSubject(), + $this->body, + $this->header); + } else { + $result = mail( + $this->recipients, + $this->_mail->getSubject(), + $this->body, + $this->header, + $this->parameters); + } + if (!$result) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('Unable to send mail'); + } + } + + + /** + * Format and fix headers + * + * mail() uses its $to and $subject arguments to set the To: and Subject: + * headers, respectively. This method strips those out as a sanity check to + * prevent duplicate header entries. + * + * @access protected + * @param array $headers + * @return void + * @throws Zend_Mail_Transport_Exception + */ + protected function _prepareHeaders($headers) + { + if (!$this->_mail) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object'); + } + + // mail() uses its $to parameter to set the To: header, and the $subject + // parameter to set the Subject: header. We need to strip them out. + if (0 === strpos(PHP_OS, 'WIN')) { + // If the current recipients list is empty, throw an error + if (empty($this->recipients)) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('Missing To addresses'); + } + } else { + // All others, simply grab the recipients and unset the To: header + if (!isset($headers['To'])) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('Missing To header'); + } + + unset($headers['To']['append']); + $this->recipients = implode(',', $headers['To']); + } + + // Remove recipient header + unset($headers['To']); + + // Remove subject header, if present + if (isset($headers['Subject'])) { + unset($headers['Subject']); + } + + // Prepare headers + parent::_prepareHeaders($headers); + } + +} + diff --git a/libs/Zend/Mail/Transport/Smtp.php b/libs/Zend/Mail/Transport/Smtp.php index 31b67486f2..16510edb6a 100644 --- a/libs/Zend/Mail/Transport/Smtp.php +++ b/libs/Zend/Mail/Transport/Smtp.php @@ -1,241 +1,241 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Loader
- */
-require_once 'Zend/Loader.php';
-
-/**
- * @see Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-/**
- * @see Zend_Mail_Transport_Abstract
- */
-require_once 'Zend/Mail/Transport/Abstract.php';
-
-
-/**
- * SMTP connection object
- *
- * Loads an instance of Zend_Mail_Protocol_Smtp and forwards smtp transactions
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Transport
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Transport_Smtp extends Zend_Mail_Transport_Abstract
-{
- /**
- * EOL character string used by transport
- * @var string
- * @access public
- */
- public $EOL = "\n";
-
- /**
- * Remote smtp hostname or i.p.
- *
- * @var string
- */
- protected $_host;
-
-
- /**
- * Port number
- *
- * @var integer|null
- */
- protected $_port;
-
-
- /**
- * Local client hostname or i.p.
- *
- * @var string
- */
- protected $_name = 'localhost';
-
-
- /**
- * Authentication type OPTIONAL
- *
- * @var string
- */
- protected $_auth;
-
-
- /**
- * Config options for authentication
- *
- * @var array
- */
- protected $_config;
-
-
- /**
- * Instance of Zend_Mail_Protocol_Smtp
- *
- * @var Zend_Mail_Protocol_Smtp
- */
- protected $_connection;
-
-
- /**
- * Constructor.
- *
- * @param string $host OPTIONAL (Default: 127.0.0.1)
- * @param array|null $config OPTIONAL (Default: null)
- * @return void
- */
- public function __construct($host = '127.0.0.1', Array $config = array())
- {
- if (isset($config['name'])) {
- $this->_name = $config['name'];
- }
- if (isset($config['port'])) {
- $this->_port = $config['port'];
- }
- if (isset($config['auth'])) {
- $this->_auth = $config['auth'];
- }
-
- $this->_host = $host;
- $this->_config = $config;
- }
-
-
- /**
- * Class destructor to ensure all open connections are closed
- *
- * @return void
- */
- public function __destruct()
- {
- if ($this->_connection instanceof Zend_Mail_Protocol_Smtp) {
- try {
- $this->_connection->quit();
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignore
- }
- $this->_connection->disconnect();
- }
- }
-
-
- /**
- * Sets the connection protocol instance
- *
- * @param Zend_Mail_Protocol_Abstract $client
- *
- * @return void
- */
- public function setConnection(Zend_Mail_Protocol_Abstract $connection)
- {
- $this->_connection = $connection;
- }
-
-
- /**
- * Gets the connection protocol instance
- *
- * @return Zend_Mail_Protocol|null
- */
- public function getConnection()
- {
- return $this->_connection;
- }
-
- /**
- * Send an email via the SMTP connection protocol
- *
- * The connection via the protocol adapter is made just-in-time to allow a
- * developer to add a custom adapter if required before mail is sent.
- *
- * @return void
- */
- public function _sendMail()
- {
- // If sending multiple messages per session use existing adapter
- if (!($this->_connection instanceof Zend_Mail_Protocol_Smtp)) {
- // Check if authentication is required and determine required class
- $connectionClass = 'Zend_Mail_Protocol_Smtp';
- if ($this->_auth) {
- $connectionClass .= '_Auth_' . ucwords($this->_auth);
- }
- Zend_Loader::loadClass($connectionClass);
- $this->setConnection(new $connectionClass($this->_host, $this->_port, $this->_config));
- $this->_connection->connect();
- $this->_connection->helo($this->_name);
- } else {
- // Reset connection to ensure reliable transaction
- $this->_connection->rset();
- }
-
- // Set mail return path from sender email address
- $this->_connection->mail($this->_mail->getReturnPath());
-
- // Set recipient forward paths
- foreach ($this->_mail->getRecipients() as $recipient) {
- $this->_connection->rcpt($recipient);
- }
-
- // Issue DATA command to client
- $this->_connection->data($this->header . Zend_Mime::LINEEND . $this->body);
- }
-
- /**
- * Format and fix headers
- *
- * Some SMTP servers do not strip BCC headers. Most clients do it themselves as do we.
- *
- * @access protected
- * @param array $headers
- * @return void
- * @throws Zend_Transport_Exception
- */
- protected function _prepareHeaders($headers)
- {
- if (!$this->_mail) {
- /**
- * @see Zend_Mail_Transport_Exception
- */
- require_once 'Zend/Mail/Transport/Exception.php';
- throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object');
- }
-
- unset($headers['Bcc']);
-
- // Prepare headers
- parent::_prepareHeaders($headers);
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Loader + */ +require_once 'Zend/Loader.php'; + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + +/** + * @see Zend_Mail_Transport_Abstract + */ +require_once 'Zend/Mail/Transport/Abstract.php'; + + +/** + * SMTP connection object + * + * Loads an instance of Zend_Mail_Protocol_Smtp and forwards smtp transactions + * + * @category Zend + * @package Zend_Mail + * @subpackage Transport + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Transport_Smtp extends Zend_Mail_Transport_Abstract +{ + /** + * EOL character string used by transport + * @var string + * @access public + */ + public $EOL = "\n"; + + /** + * Remote smtp hostname or i.p. + * + * @var string + */ + protected $_host; + + + /** + * Port number + * + * @var integer|null + */ + protected $_port; + + + /** + * Local client hostname or i.p. + * + * @var string + */ + protected $_name = 'localhost'; + + + /** + * Authentication type OPTIONAL + * + * @var string + */ + protected $_auth; + + + /** + * Config options for authentication + * + * @var array + */ + protected $_config; + + + /** + * Instance of Zend_Mail_Protocol_Smtp + * + * @var Zend_Mail_Protocol_Smtp + */ + protected $_connection; + + + /** + * Constructor. + * + * @param string $host OPTIONAL (Default: 127.0.0.1) + * @param array|null $config OPTIONAL (Default: null) + * @return void + */ + public function __construct($host = '127.0.0.1', Array $config = array()) + { + if (isset($config['name'])) { + $this->_name = $config['name']; + } + if (isset($config['port'])) { + $this->_port = $config['port']; + } + if (isset($config['auth'])) { + $this->_auth = $config['auth']; + } + + $this->_host = $host; + $this->_config = $config; + } + + + /** + * Class destructor to ensure all open connections are closed + * + * @return void + */ + public function __destruct() + { + if ($this->_connection instanceof Zend_Mail_Protocol_Smtp) { + try { + $this->_connection->quit(); + } catch (Zend_Mail_Protocol_Exception $e) { + // ignore + } + $this->_connection->disconnect(); + } + } + + + /** + * Sets the connection protocol instance + * + * @param Zend_Mail_Protocol_Abstract $client + * + * @return void + */ + public function setConnection(Zend_Mail_Protocol_Abstract $connection) + { + $this->_connection = $connection; + } + + + /** + * Gets the connection protocol instance + * + * @return Zend_Mail_Protocol|null + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * Send an email via the SMTP connection protocol + * + * The connection via the protocol adapter is made just-in-time to allow a + * developer to add a custom adapter if required before mail is sent. + * + * @return void + */ + public function _sendMail() + { + // If sending multiple messages per session use existing adapter + if (!($this->_connection instanceof Zend_Mail_Protocol_Smtp)) { + // Check if authentication is required and determine required class + $connectionClass = 'Zend_Mail_Protocol_Smtp'; + if ($this->_auth) { + $connectionClass .= '_Auth_' . ucwords($this->_auth); + } + Zend_Loader::loadClass($connectionClass); + $this->setConnection(new $connectionClass($this->_host, $this->_port, $this->_config)); + $this->_connection->connect(); + $this->_connection->helo($this->_name); + } else { + // Reset connection to ensure reliable transaction + $this->_connection->rset(); + } + + // Set mail return path from sender email address + $this->_connection->mail($this->_mail->getReturnPath()); + + // Set recipient forward paths + foreach ($this->_mail->getRecipients() as $recipient) { + $this->_connection->rcpt($recipient); + } + + // Issue DATA command to client + $this->_connection->data($this->header . Zend_Mime::LINEEND . $this->body); + } + + /** + * Format and fix headers + * + * Some SMTP servers do not strip BCC headers. Most clients do it themselves as do we. + * + * @access protected + * @param array $headers + * @return void + * @throws Zend_Transport_Exception + */ + protected function _prepareHeaders($headers) + { + if (!$this->_mail) { + /** + * @see Zend_Mail_Transport_Exception + */ + require_once 'Zend/Mail/Transport/Exception.php'; + throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object'); + } + + unset($headers['Bcc']); + + // Prepare headers + parent::_prepareHeaders($headers); + } +} diff --git a/libs/Zend/Mime.php b/libs/Zend/Mime.php index a2b4f9accc..499ff21b6a 100644 --- a/libs/Zend/Mime.php +++ b/libs/Zend/Mime.php @@ -1,252 +1,252 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-
-/**
- * Support class for MultiPart Mime Messages
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mime
-{
- const TYPE_OCTETSTREAM = 'application/octet-stream';
- const TYPE_TEXT = 'text/plain';
- const TYPE_HTML = 'text/html';
- const ENCODING_7BIT = '7bit';
- const ENCODING_8BIT = '8bit';
- const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
- const ENCODING_BASE64 = 'base64';
- const DISPOSITION_ATTACHMENT = 'attachment';
- const DISPOSITION_INLINE = 'inline';
- const LINELENGTH = 74;
- const LINEEND = "\n";
- const MULTIPART_ALTERNATIVE = 'multipart/alternative';
- const MULTIPART_MIXED = 'multipart/mixed';
- const MULTIPART_RELATED = 'multipart/related';
-
- protected $_boundary;
- protected static $makeUnique = 0;
-
- // lookup-Tables for QuotedPrintable
- public static $qpKeys = array(
- "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07",
- "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F",
- "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17",
- "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
- "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86",
- "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E",
- "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96",
- "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E",
- "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6",
- "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE",
- "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6",
- "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE",
- "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6",
- "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE",
- "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6",
- "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE",
- "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6",
- "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE",
- "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6",
- "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE",
- "\xFF"
- );
-
- public static $qpReplaceValues = array(
- "=00","=01","=02","=03","=04","=05","=06","=07",
- "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F",
- "=10","=11","=12","=13","=14","=15","=16","=17",
- "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F",
- "=7F","=80","=81","=82","=83","=84","=85","=86",
- "=87","=88","=89","=8A","=8B","=8C","=8D","=8E",
- "=8F","=90","=91","=92","=93","=94","=95","=96",
- "=97","=98","=99","=9A","=9B","=9C","=9D","=9E",
- "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6",
- "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE",
- "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6",
- "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE",
- "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6",
- "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE",
- "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6",
- "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE",
- "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6",
- "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE",
- "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6",
- "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE",
- "=FF"
- );
-
- public static $qpKeysString =
- "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
-
- /**
- * Check if the given string is "printable"
- *
- * Checks that a string contains no unprintable characters. If this returns
- * false, encode the string for secure delivery.
- *
- * @param string $str
- * @return boolean
- */
- public static function isPrintable($str)
- {
- return (strcspn($str, self::$qpKeysString) == strlen($str));
- }
-
- /**
- * Encode a given string with the QUOTED_PRINTABLE mechanism
- *
- * @param string $str
- * @param int $lineLength Defaults to {@link LINELENGTH}
- * @param int $lineEnd Defaults to {@link LINEEND}
- * @return string
- */
- public static function encodeQuotedPrintable($str,
- $lineLength = self::LINELENGTH,
- $lineEnd = self::LINEEND)
- {
- $out = '';
- $str = str_replace('=', '=3D', $str);
- $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
- $str = rtrim($str);
-
- // Split encoded text into separate lines
- while ($str) {
- $ptr = strlen($str);
- if ($ptr > $lineLength) {
- $ptr = $lineLength;
- }
-
- // Ensure we are not splitting across an encoded character
- $pos = strrpos(substr($str, 0, $ptr), '=');
- if ($pos !== false && $pos >= $ptr - 2) {
- $ptr = $pos;
- }
-
- // Check if there is a space at the end of the line and rewind
- if ($ptr > 0 && $str[$ptr - 1] == ' ') {
- --$ptr;
- }
-
- // Add string and continue
- $out .= substr($str, 0, $ptr) . '=' . $lineEnd;
- $str = substr($str, $ptr);
- }
-
- $out = rtrim($out, $lineEnd);
- $out = rtrim($out, '=');
- return $out;
- }
-
- /**
- * Encode a given string in base64 encoding and break lines
- * according to the maximum linelength.
- *
- * @param string $str
- * @param int $lineLength Defaults to {@link LINELENGTH}
- * @param int $lineEnd Defaults to {@link LINEEND}
- * @return string
- */
- public static function encodeBase64($str,
- $lineLength = self::LINELENGTH,
- $lineEnd = self::LINEEND)
- {
- return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
- }
-
- /**
- * Constructor
- *
- * @param null|string $boundary
- * @access public
- * @return void
- */
- public function __construct($boundary = null)
- {
- // This string needs to be somewhat unique
- if ($boundary === null) {
- $this->_boundary = '=_' . md5(microtime(1) . self::$makeUnique++);
- } else {
- $this->_boundary = $boundary;
- }
- }
-
- /**
- * Encode the given string with the given encoding.
- *
- * @param string $str
- * @param string $encoding
- * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
- * @return string
- */
- public static function encode($str, $encoding, $EOL = self::LINEEND)
- {
- switch ($encoding) {
- case self::ENCODING_BASE64:
- return self::encodeBase64($str, self::LINELENGTH, $EOL);
-
- case self::ENCODING_QUOTEDPRINTABLE:
- return self::encodeQuotedPrintable($str, self::LINELENGTH, $EOL);
-
- default:
- /**
- * @todo 7Bit and 8Bit is currently handled the same way.
- */
- return $str;
- }
- }
-
- /**
- * Return a MIME boundary
- *
- * @access public
- * @return string
- */
- public function boundary()
- {
- return $this->_boundary;
- }
-
- /**
- * Return a MIME boundary line
- *
- * @param mixed $EOL Defaults to {@link LINEEND}
- * @access public
- * @return string
- */
- public function boundaryLine($EOL = self::LINEEND)
- {
- return $EOL . '--' . $this->_boundary . $EOL;
- }
-
- /**
- * Return MIME ending
- *
- * @access public
- * @return string
- */
- public function mimeEnd($EOL = self::LINEEND)
- {
- return $EOL . '--' . $this->_boundary . '--' . $EOL;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + + +/** + * Support class for MultiPart Mime Messages + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mime +{ + const TYPE_OCTETSTREAM = 'application/octet-stream'; + const TYPE_TEXT = 'text/plain'; + const TYPE_HTML = 'text/html'; + const ENCODING_7BIT = '7bit'; + const ENCODING_8BIT = '8bit'; + const ENCODING_QUOTEDPRINTABLE = 'quoted-printable'; + const ENCODING_BASE64 = 'base64'; + const DISPOSITION_ATTACHMENT = 'attachment'; + const DISPOSITION_INLINE = 'inline'; + const LINELENGTH = 74; + const LINEEND = "\n"; + const MULTIPART_ALTERNATIVE = 'multipart/alternative'; + const MULTIPART_MIXED = 'multipart/mixed'; + const MULTIPART_RELATED = 'multipart/related'; + + protected $_boundary; + protected static $makeUnique = 0; + + // lookup-Tables for QuotedPrintable + public static $qpKeys = array( + "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07", + "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F", + "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17", + "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F", + "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86", + "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E", + "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96", + "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E", + "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6", + "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE", + "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6", + "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE", + "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6", + "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE", + "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6", + "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE", + "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6", + "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE", + "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6", + "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE", + "\xFF" + ); + + public static $qpReplaceValues = array( + "=00","=01","=02","=03","=04","=05","=06","=07", + "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F", + "=10","=11","=12","=13","=14","=15","=16","=17", + "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F", + "=7F","=80","=81","=82","=83","=84","=85","=86", + "=87","=88","=89","=8A","=8B","=8C","=8D","=8E", + "=8F","=90","=91","=92","=93","=94","=95","=96", + "=97","=98","=99","=9A","=9B","=9C","=9D","=9E", + "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6", + "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE", + "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6", + "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE", + "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6", + "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE", + "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6", + "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE", + "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6", + "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE", + "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6", + "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE", + "=FF" + ); + + public static $qpKeysString = + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"; + + /** + * Check if the given string is "printable" + * + * Checks that a string contains no unprintable characters. If this returns + * false, encode the string for secure delivery. + * + * @param string $str + * @return boolean + */ + public static function isPrintable($str) + { + return (strcspn($str, self::$qpKeysString) == strlen($str)); + } + + /** + * Encode a given string with the QUOTED_PRINTABLE mechanism + * + * @param string $str + * @param int $lineLength Defaults to {@link LINELENGTH} + * @param int $lineEnd Defaults to {@link LINEEND} + * @return string + */ + public static function encodeQuotedPrintable($str, + $lineLength = self::LINELENGTH, + $lineEnd = self::LINEEND) + { + $out = ''; + $str = str_replace('=', '=3D', $str); + $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str); + $str = rtrim($str); + + // Split encoded text into separate lines + while ($str) { + $ptr = strlen($str); + if ($ptr > $lineLength) { + $ptr = $lineLength; + } + + // Ensure we are not splitting across an encoded character + $pos = strrpos(substr($str, 0, $ptr), '='); + if ($pos !== false && $pos >= $ptr - 2) { + $ptr = $pos; + } + + // Check if there is a space at the end of the line and rewind + if ($ptr > 0 && $str[$ptr - 1] == ' ') { + --$ptr; + } + + // Add string and continue + $out .= substr($str, 0, $ptr) . '=' . $lineEnd; + $str = substr($str, $ptr); + } + + $out = rtrim($out, $lineEnd); + $out = rtrim($out, '='); + return $out; + } + + /** + * Encode a given string in base64 encoding and break lines + * according to the maximum linelength. + * + * @param string $str + * @param int $lineLength Defaults to {@link LINELENGTH} + * @param int $lineEnd Defaults to {@link LINEEND} + * @return string + */ + public static function encodeBase64($str, + $lineLength = self::LINELENGTH, + $lineEnd = self::LINEEND) + { + return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd)); + } + + /** + * Constructor + * + * @param null|string $boundary + * @access public + * @return void + */ + public function __construct($boundary = null) + { + // This string needs to be somewhat unique + if ($boundary === null) { + $this->_boundary = '=_' . md5(microtime(1) . self::$makeUnique++); + } else { + $this->_boundary = $boundary; + } + } + + /** + * Encode the given string with the given encoding. + * + * @param string $str + * @param string $encoding + * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} + * @return string + */ + public static function encode($str, $encoding, $EOL = self::LINEEND) + { + switch ($encoding) { + case self::ENCODING_BASE64: + return self::encodeBase64($str, self::LINELENGTH, $EOL); + + case self::ENCODING_QUOTEDPRINTABLE: + return self::encodeQuotedPrintable($str, self::LINELENGTH, $EOL); + + default: + /** + * @todo 7Bit and 8Bit is currently handled the same way. + */ + return $str; + } + } + + /** + * Return a MIME boundary + * + * @access public + * @return string + */ + public function boundary() + { + return $this->_boundary; + } + + /** + * Return a MIME boundary line + * + * @param mixed $EOL Defaults to {@link LINEEND} + * @access public + * @return string + */ + public function boundaryLine($EOL = self::LINEEND) + { + return $EOL . '--' . $this->_boundary . $EOL; + } + + /** + * Return MIME ending + * + * @access public + * @return string + */ + public function mimeEnd($EOL = self::LINEEND) + { + return $EOL . '--' . $this->_boundary . '--' . $EOL; + } +} diff --git a/libs/Zend/Mime/Decode.php b/libs/Zend/Mime/Decode.php index fdd9bc7af1..c8902fcac8 100644 --- a/libs/Zend/Mime/Decode.php +++ b/libs/Zend/Mime/Decode.php @@ -1,238 +1,238 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-/**
- * Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-/**
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mime_Decode
-{
- /**
- * Explode MIME multipart string into seperate parts
- *
- * Parts consist of the header and the body of each MIME part.
- *
- * @param string $body raw body of message
- * @param string $boundary boundary as found in content-type
- * @return array parts with content of each part, empty if no parts found
- * @throws Zend_Exception
- */
- public static function splitMime($body, $boundary)
- {
- // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
- $body = str_replace("\r", '', $body);
-
- $start = 0;
- $res = array();
- // find every mime part limiter and cut out the
- // string before it.
- // the part before the first boundary string is discarded:
- $p = strpos($body, '--' . $boundary . "\n", $start);
- if ($p === false) {
- // no parts found!
- return array();
- }
-
- // position after first boundary line
- $start = $p + 3 + strlen($boundary);
-
- while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
- $res[] = substr($body, $start, $p-$start);
- $start = $p + 3 + strlen($boundary);
- }
-
- // no more parts, find end boundary
- $p = strpos($body, '--' . $boundary . '--', $start);
- if ($p===false) {
- throw new Zend_Exception('Not a valid Mime Message: End Missing');
- }
-
- // the remaining part also needs to be parsed:
- $res[] = substr($body, $start, $p-$start);
- return $res;
- }
-
- /**
- * decodes a mime encoded String and returns a
- * struct of parts with header and body
- *
- * @param string $message raw message content
- * @param string $boundary boundary as found in content-type
- * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
- * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found
- * @throws Zend_Exception
- */
- public static function splitMessageStruct($message, $boundary, $EOL = Zend_Mime::LINEEND)
- {
- $parts = self::splitMime($message, $boundary);
- if (count($parts) <= 0) {
- return null;
- }
- $result = array();
- foreach ($parts as $part) {
- self::splitMessage($part, $headers, $body, $EOL);
- $result[] = array('header' => $headers,
- 'body' => $body );
- }
- return $result;
- }
-
- /**
- * split a message in header and body part, if no header or an
- * invalid header is found $headers is empty
- *
- * The charset of the returned headers depend on your iconv settings.
- *
- * @param string $message raw message with header and optional content
- * @param array $headers output param, array with headers as array(name => value)
- * @param string $body output param, content of message
- * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
- * @return null
- */
- public static function splitMessage($message, &$headers, &$body, $EOL = Zend_Mime::LINEEND)
- {
- // check for valid header at first line
- $firstline = strtok($message, "\n");
- if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
- $headers = array();
- // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
- $body = str_replace(array("\r", "\n"), array('', $EOL), $message);
- return;
- }
-
- // find an empty line between headers and body
- // default is set new line
- if (strpos($message, $EOL . $EOL)) {
- list($headers, $body) = explode($EOL . $EOL, $message, 2);
- // next is the standard new line
- } else if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
- list($headers, $body) = explode("\r\n\r\n", $message, 2);
- // next is the other "standard" new line
- } else if ($EOL != "\n" && strpos($message, "\n\n")) {
- list($headers, $body) = explode("\n\n", $message, 2);
- // at last resort find anything that looks like a new line
- } else {
- @list($headers, $body) = @preg_split("%([\r\n]+)\\1%U", $message, 2);
- }
-
- $headers = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
-
- // normalize header names
- foreach ($headers as $name => $header) {
- $lower = strtolower($name);
- if ($lower == $name) {
- continue;
- }
- unset($headers[$name]);
- if (!isset($headers[$lower])) {
- $headers[$lower] = $header;
- continue;
- }
- if (is_array($headers[$lower])) {
- $headers[$lower][] = $header;
- continue;
- }
- $headers[$lower] = array($headers[$lower], $header);
- }
- }
-
- /**
- * split a content type in its different parts
- *
- * @param string $type content-type
- * @param string $wantedPart the wanted part, else an array with all parts is returned
- * @return string|array wanted part or all parts as array('type' => content-type, partname => value)
- */
- public static function splitContentType($type, $wantedPart = null)
- {
- return self::splitHeaderField($type, $wantedPart, 'type');
- }
-
- /**
- * split a header field like content type in its different parts
- *
- * @param string $type header field
- * @param string $wantedPart the wanted part, else an array with all parts is returned
- * @param string $firstName key name for the first part
- * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
- * @throws Zend_Exception
- */
- public static function splitHeaderField($field, $wantedPart = null, $firstName = 0)
- {
- $wantedPart = strtolower($wantedPart);
- $firstName = strtolower($firstName);
-
- // special case - a bit optimized
- if ($firstName === $wantedPart) {
- $field = strtok($field, ';');
- return $field[0] == '"' ? substr($field, 1, -1) : $field;
- }
-
- $field = $firstName . '=' . $field;
- if (!preg_match_all('%([^=]+)=("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
- throw new Zend_Exception('not a valid header field');
- }
-
- if ($wantedPart) {
- foreach ($matches[1] as $key => $name) {
- if (strcasecmp($name, $wantedPart)) {
- continue;
- }
- if ($matches[2][$key][0] != '"') {
- return $matches[2][$key];
- }
- return substr($matches[2][$key], 1, -1);
- }
- return null;
- }
-
- $split = array();
- foreach ($matches[1] as $key => $name) {
- $name = strtolower($name);
- if ($matches[2][$key][0] == '"') {
- $split[$name] = substr($matches[2][$key], 1, -1);
- } else {
- $split[$name] = $matches[2][$key];
- }
- }
-
- return $split;
- }
-
- /**
- * decode a quoted printable encoded string
- *
- * The charset of the returned string depends on your iconv settings.
- *
- * @param string encoded string
- * @return string decoded string
- */
- public static function decodeQuotedPrintable($string)
- {
- return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR);
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +/** + * Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mime_Decode +{ + /** + * Explode MIME multipart string into seperate parts + * + * Parts consist of the header and the body of each MIME part. + * + * @param string $body raw body of message + * @param string $boundary boundary as found in content-type + * @return array parts with content of each part, empty if no parts found + * @throws Zend_Exception + */ + public static function splitMime($body, $boundary) + { + // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r? + $body = str_replace("\r", '', $body); + + $start = 0; + $res = array(); + // find every mime part limiter and cut out the + // string before it. + // the part before the first boundary string is discarded: + $p = strpos($body, '--' . $boundary . "\n", $start); + if ($p === false) { + // no parts found! + return array(); + } + + // position after first boundary line + $start = $p + 3 + strlen($boundary); + + while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { + $res[] = substr($body, $start, $p-$start); + $start = $p + 3 + strlen($boundary); + } + + // no more parts, find end boundary + $p = strpos($body, '--' . $boundary . '--', $start); + if ($p===false) { + throw new Zend_Exception('Not a valid Mime Message: End Missing'); + } + + // the remaining part also needs to be parsed: + $res[] = substr($body, $start, $p-$start); + return $res; + } + + /** + * decodes a mime encoded String and returns a + * struct of parts with header and body + * + * @param string $message raw message content + * @param string $boundary boundary as found in content-type + * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} + * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found + * @throws Zend_Exception + */ + public static function splitMessageStruct($message, $boundary, $EOL = Zend_Mime::LINEEND) + { + $parts = self::splitMime($message, $boundary); + if (count($parts) <= 0) { + return null; + } + $result = array(); + foreach ($parts as $part) { + self::splitMessage($part, $headers, $body, $EOL); + $result[] = array('header' => $headers, + 'body' => $body ); + } + return $result; + } + + /** + * split a message in header and body part, if no header or an + * invalid header is found $headers is empty + * + * The charset of the returned headers depend on your iconv settings. + * + * @param string $message raw message with header and optional content + * @param array $headers output param, array with headers as array(name => value) + * @param string $body output param, content of message + * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} + * @return null + */ + public static function splitMessage($message, &$headers, &$body, $EOL = Zend_Mime::LINEEND) + { + // check for valid header at first line + $firstline = strtok($message, "\n"); + if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) { + $headers = array(); + // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r? + $body = str_replace(array("\r", "\n"), array('', $EOL), $message); + return; + } + + // find an empty line between headers and body + // default is set new line + if (strpos($message, $EOL . $EOL)) { + list($headers, $body) = explode($EOL . $EOL, $message, 2); + // next is the standard new line + } else if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { + list($headers, $body) = explode("\r\n\r\n", $message, 2); + // next is the other "standard" new line + } else if ($EOL != "\n" && strpos($message, "\n\n")) { + list($headers, $body) = explode("\n\n", $message, 2); + // at last resort find anything that looks like a new line + } else { + @list($headers, $body) = @preg_split("%([\r\n]+)\\1%U", $message, 2); + } + + $headers = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR); + + // normalize header names + foreach ($headers as $name => $header) { + $lower = strtolower($name); + if ($lower == $name) { + continue; + } + unset($headers[$name]); + if (!isset($headers[$lower])) { + $headers[$lower] = $header; + continue; + } + if (is_array($headers[$lower])) { + $headers[$lower][] = $header; + continue; + } + $headers[$lower] = array($headers[$lower], $header); + } + } + + /** + * split a content type in its different parts + * + * @param string $type content-type + * @param string $wantedPart the wanted part, else an array with all parts is returned + * @return string|array wanted part or all parts as array('type' => content-type, partname => value) + */ + public static function splitContentType($type, $wantedPart = null) + { + return self::splitHeaderField($type, $wantedPart, 'type'); + } + + /** + * split a header field like content type in its different parts + * + * @param string $type header field + * @param string $wantedPart the wanted part, else an array with all parts is returned + * @param string $firstName key name for the first part + * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) + * @throws Zend_Exception + */ + public static function splitHeaderField($field, $wantedPart = null, $firstName = 0) + { + $wantedPart = strtolower($wantedPart); + $firstName = strtolower($firstName); + + // special case - a bit optimized + if ($firstName === $wantedPart) { + $field = strtok($field, ';'); + return $field[0] == '"' ? substr($field, 1, -1) : $field; + } + + $field = $firstName . '=' . $field; + if (!preg_match_all('%([^=]+)=("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { + throw new Zend_Exception('not a valid header field'); + } + + if ($wantedPart) { + foreach ($matches[1] as $key => $name) { + if (strcasecmp($name, $wantedPart)) { + continue; + } + if ($matches[2][$key][0] != '"') { + return $matches[2][$key]; + } + return substr($matches[2][$key], 1, -1); + } + return null; + } + + $split = array(); + foreach ($matches[1] as $key => $name) { + $name = strtolower($name); + if ($matches[2][$key][0] == '"') { + $split[$name] = substr($matches[2][$key], 1, -1); + } else { + $split[$name] = $matches[2][$key]; + } + } + + return $split; + } + + /** + * decode a quoted printable encoded string + * + * The charset of the returned string depends on your iconv settings. + * + * @param string encoded string + * @return string decoded string + */ + public static function decodeQuotedPrintable($string) + { + return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR); + } +} diff --git a/libs/Zend/Mime/Exception.php b/libs/Zend/Mime/Exception.php index 7750b5feb2..2c22e9b9dd 100644 --- a/libs/Zend/Mime/Exception.php +++ b/libs/Zend/Mime/Exception.php @@ -1,36 +1,36 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-
-/**
- * Zend_Exception
- */
-require_once 'Zend/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mime_Exception extends Zend_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + + +/** + * Zend_Exception + */ +require_once 'Zend/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mime_Exception extends Zend_Exception +{} + diff --git a/libs/Zend/Mime/Message.php b/libs/Zend/Mime/Message.php index 2be3a45ee2..d2f8dc7216 100644 --- a/libs/Zend/Mime/Message.php +++ b/libs/Zend/Mime/Message.php @@ -1,280 +1,280 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-
-/**
- * Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-/**
- * Zend_Mime_Part
- */
-require_once 'Zend/Mime/Part.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mime_Message
-{
-
- protected $_parts = array();
- protected $_mime = null;
-
- /**
- * Returns the list of all Zend_Mime_Parts in the message
- *
- * @return array of Zend_Mime_Part
- */
- public function getParts()
- {
- return $this->_parts;
- }
-
- /**
- * Sets the given array of Zend_Mime_Parts as the array for the message
- *
- * @param array $parts
- */
- public function setParts($parts)
- {
- $this->_parts = $parts;
- }
-
- /**
- * Append a new Zend_Mime_Part to the current message
- *
- * @param Zend_Mime_Part $part
- */
- public function addPart(Zend_Mime_Part $part)
- {
- /**
- * @todo check for duplicate object handle
- */
- $this->_parts[] = $part;
- }
-
- /**
- * Check if message needs to be sent as multipart
- * MIME message or if it has only one part.
- *
- * @return boolean
- */
- public function isMultiPart()
- {
- return (count($this->_parts) > 1);
- }
-
- /**
- * Set Zend_Mime object for the message
- *
- * This can be used to set the boundary specifically or to use a subclass of
- * Zend_Mime for generating the boundary.
- *
- * @param Zend_Mime $mime
- */
- public function setMime(Zend_Mime $mime)
- {
- $this->_mime = $mime;
- }
-
- /**
- * Returns the Zend_Mime object in use by the message
- *
- * If the object was not present, it is created and returned. Can be used to
- * determine the boundary used in this message.
- *
- * @return Zend_Mime
- */
- public function getMime()
- {
- if ($this->_mime === null) {
- $this->_mime = new Zend_Mime();
- }
-
- return $this->_mime;
- }
-
- /**
- * Generate MIME-compliant message from the current configuration
- *
- * This can be a multipart message if more than one MIME part was added. If
- * only one part is present, the content of this part is returned. If no
- * part had been added, an empty string is returned.
- *
- * Parts are seperated by the mime boundary as defined in Zend_Mime. If
- * {@link setMime()} has been called before this method, the Zend_Mime
- * object set by this call will be used. Otherwise, a new Zend_Mime object
- * is generated and used.
- *
- * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
- * @return string
- */
- public function generateMessage($EOL = Zend_Mime::LINEEND)
- {
- if (! $this->isMultiPart()) {
- $body = array_shift($this->_parts);
- $body = $body->getContent($EOL);
- } else {
- $mime = $this->getMime();
-
- $boundaryLine = $mime->boundaryLine($EOL);
- $body = 'This is a message in Mime Format. If you see this, '
- . "your mail reader does not support this format." . $EOL;
-
- foreach (array_keys($this->_parts) as $p) {
- $body .= $boundaryLine
- . $this->getPartHeaders($p, $EOL)
- . $EOL
- . $this->getPartContent($p, $EOL);
- }
-
- $body .= $mime->mimeEnd($EOL);
- }
-
- return trim($body);
- }
-
- /**
- * Get the headers of a given part as an array
- *
- * @param int $partnum
- * @return array
- */
- public function getPartHeadersArray($partnum)
- {
- return $this->_parts[$partnum]->getHeadersArray();
- }
-
- /**
- * Get the headers of a given part as a string
- *
- * @param int $partnum
- * @return string
- */
- public function getPartHeaders($partnum, $EOL = Zend_Mime::LINEEND)
- {
- return $this->_parts[$partnum]->getHeaders($EOL);
- }
-
- /**
- * Get the (encoded) content of a given part as a string
- *
- * @param int $partnum
- * @return string
- */
- public function getPartContent($partnum, $EOL = Zend_Mime::LINEEND)
- {
- return $this->_parts[$partnum]->getContent($EOL);
- }
-
- /**
- * Explode MIME multipart string into seperate parts
- *
- * Parts consist of the header and the body of each MIME part.
- *
- * @param string $body
- * @param string $boundary
- * @return array
- */
- protected static function _disassembleMime($body, $boundary)
- {
- $start = 0;
- $res = array();
- // find every mime part limiter and cut out the
- // string before it.
- // the part before the first boundary string is discarded:
- $p = strpos($body, '--'.$boundary."\n", $start);
- if ($p === false) {
- // no parts found!
- return array();
- }
-
- // position after first boundary line
- $start = $p + 3 + strlen($boundary);
-
- while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
- $res[] = substr($body, $start, $p-$start);
- $start = $p + 3 + strlen($boundary);
- }
-
- // no more parts, find end boundary
- $p = strpos($body, '--' . $boundary . '--', $start);
- if ($p===false) {
- throw new Zend_Exception('Not a valid Mime Message: End Missing');
- }
-
- // the remaining part also needs to be parsed:
- $res[] = substr($body, $start, $p-$start);
- return $res;
- }
-
- /**
- * Decodes a MIME encoded string and returns a Zend_Mime_Message object with
- * all the MIME parts set according to the given string
- *
- * @param string $message
- * @param string $boundary
- * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
- * @return Zend_Mime_Message
- */
- public static function createFromMessage($message, $boundary, $EOL = Zend_Mime::LINEEND)
- {
- require_once 'Zend/Mime/Decode.php';
- $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL);
-
- $res = new self();
- foreach ($parts as $part) {
- // now we build a new MimePart for the current Message Part:
- $newPart = new Zend_Mime_Part($part);
- foreach ($part['header'] as $key => $value) {
- /**
- * @todo check for characterset and filename
- */
- // list($key, $value) = $header;
- switch($key) {
- case 'content-type':
- $newPart->type = $value;
- break;
- case 'content-transfer-encoding':
- $newPart->encoding = $value;
- break;
- case 'content-id':
- $newPart->id = trim($value,'<>');
- break;
- case 'Content-Disposition':
- $newPart->disposition = $value;
- break;
- case 'content-description':
- $newPart->description = $value;
- break;
- default:
- throw new Zend_Exception('Unknown header ignored for MimePart:' . $key);
- }
- }
- $res->addPart($newPart);
- }
- return $res;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + + +/** + * Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * Zend_Mime_Part + */ +require_once 'Zend/Mime/Part.php'; + + +/** + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mime_Message +{ + + protected $_parts = array(); + protected $_mime = null; + + /** + * Returns the list of all Zend_Mime_Parts in the message + * + * @return array of Zend_Mime_Part + */ + public function getParts() + { + return $this->_parts; + } + + /** + * Sets the given array of Zend_Mime_Parts as the array for the message + * + * @param array $parts + */ + public function setParts($parts) + { + $this->_parts = $parts; + } + + /** + * Append a new Zend_Mime_Part to the current message + * + * @param Zend_Mime_Part $part + */ + public function addPart(Zend_Mime_Part $part) + { + /** + * @todo check for duplicate object handle + */ + $this->_parts[] = $part; + } + + /** + * Check if message needs to be sent as multipart + * MIME message or if it has only one part. + * + * @return boolean + */ + public function isMultiPart() + { + return (count($this->_parts) > 1); + } + + /** + * Set Zend_Mime object for the message + * + * This can be used to set the boundary specifically or to use a subclass of + * Zend_Mime for generating the boundary. + * + * @param Zend_Mime $mime + */ + public function setMime(Zend_Mime $mime) + { + $this->_mime = $mime; + } + + /** + * Returns the Zend_Mime object in use by the message + * + * If the object was not present, it is created and returned. Can be used to + * determine the boundary used in this message. + * + * @return Zend_Mime + */ + public function getMime() + { + if ($this->_mime === null) { + $this->_mime = new Zend_Mime(); + } + + return $this->_mime; + } + + /** + * Generate MIME-compliant message from the current configuration + * + * This can be a multipart message if more than one MIME part was added. If + * only one part is present, the content of this part is returned. If no + * part had been added, an empty string is returned. + * + * Parts are seperated by the mime boundary as defined in Zend_Mime. If + * {@link setMime()} has been called before this method, the Zend_Mime + * object set by this call will be used. Otherwise, a new Zend_Mime object + * is generated and used. + * + * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} + * @return string + */ + public function generateMessage($EOL = Zend_Mime::LINEEND) + { + if (! $this->isMultiPart()) { + $body = array_shift($this->_parts); + $body = $body->getContent($EOL); + } else { + $mime = $this->getMime(); + + $boundaryLine = $mime->boundaryLine($EOL); + $body = 'This is a message in Mime Format. If you see this, ' + . "your mail reader does not support this format." . $EOL; + + foreach (array_keys($this->_parts) as $p) { + $body .= $boundaryLine + . $this->getPartHeaders($p, $EOL) + . $EOL + . $this->getPartContent($p, $EOL); + } + + $body .= $mime->mimeEnd($EOL); + } + + return trim($body); + } + + /** + * Get the headers of a given part as an array + * + * @param int $partnum + * @return array + */ + public function getPartHeadersArray($partnum) + { + return $this->_parts[$partnum]->getHeadersArray(); + } + + /** + * Get the headers of a given part as a string + * + * @param int $partnum + * @return string + */ + public function getPartHeaders($partnum, $EOL = Zend_Mime::LINEEND) + { + return $this->_parts[$partnum]->getHeaders($EOL); + } + + /** + * Get the (encoded) content of a given part as a string + * + * @param int $partnum + * @return string + */ + public function getPartContent($partnum, $EOL = Zend_Mime::LINEEND) + { + return $this->_parts[$partnum]->getContent($EOL); + } + + /** + * Explode MIME multipart string into seperate parts + * + * Parts consist of the header and the body of each MIME part. + * + * @param string $body + * @param string $boundary + * @return array + */ + protected static function _disassembleMime($body, $boundary) + { + $start = 0; + $res = array(); + // find every mime part limiter and cut out the + // string before it. + // the part before the first boundary string is discarded: + $p = strpos($body, '--'.$boundary."\n", $start); + if ($p === false) { + // no parts found! + return array(); + } + + // position after first boundary line + $start = $p + 3 + strlen($boundary); + + while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { + $res[] = substr($body, $start, $p-$start); + $start = $p + 3 + strlen($boundary); + } + + // no more parts, find end boundary + $p = strpos($body, '--' . $boundary . '--', $start); + if ($p===false) { + throw new Zend_Exception('Not a valid Mime Message: End Missing'); + } + + // the remaining part also needs to be parsed: + $res[] = substr($body, $start, $p-$start); + return $res; + } + + /** + * Decodes a MIME encoded string and returns a Zend_Mime_Message object with + * all the MIME parts set according to the given string + * + * @param string $message + * @param string $boundary + * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} + * @return Zend_Mime_Message + */ + public static function createFromMessage($message, $boundary, $EOL = Zend_Mime::LINEEND) + { + require_once 'Zend/Mime/Decode.php'; + $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL); + + $res = new self(); + foreach ($parts as $part) { + // now we build a new MimePart for the current Message Part: + $newPart = new Zend_Mime_Part($part); + foreach ($part['header'] as $key => $value) { + /** + * @todo check for characterset and filename + */ + // list($key, $value) = $header; + switch($key) { + case 'content-type': + $newPart->type = $value; + break; + case 'content-transfer-encoding': + $newPart->encoding = $value; + break; + case 'content-id': + $newPart->id = trim($value,'<>'); + break; + case 'Content-Disposition': + $newPart->disposition = $value; + break; + case 'content-description': + $newPart->description = $value; + break; + default: + throw new Zend_Exception('Unknown header ignored for MimePart:' . $key); + } + } + $res->addPart($newPart); + } + return $res; + } +} diff --git a/libs/Zend/Mime/Part.php b/libs/Zend/Mime/Part.php index d7842d4bf2..d400529d75 100644 --- a/libs/Zend/Mime/Part.php +++ b/libs/Zend/Mime/Part.php @@ -1,208 +1,208 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
-/**
- * Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-/**
- * Zend_Mime_Exception
- */
-require_once 'Zend/Mime/Exception.php';
-
-/**
- * Class representing a MIME part.
- *
- * @category Zend
- * @package Zend_Mime
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mime_Part {
-
- public $type = Zend_Mime::TYPE_OCTETSTREAM;
- public $encoding = Zend_Mime::ENCODING_8BIT;
- public $id;
- public $disposition;
- public $filename;
- public $description;
- public $charset;
- public $boundary;
- protected $_content;
- protected $_isStream = false;
-
-
- /**
- * create a new Mime Part.
- * The (unencoded) content of the Part as passed
- * as a string or stream
- *
- * @param mixed $content String or Stream containing the content
- */
- public function __construct($content)
- {
- $this->_content = $content;
- if (is_resource($content)) {
- $this->_isStream = true;
- }
- }
-
- /**
- * @todo setters/getters
- * @todo error checking for setting $type
- * @todo error checking for setting $encoding
- */
-
- /**
- * check if this part can be read as a stream.
- * if true, getEncodedStream can be called, otherwise
- * only getContent can be used to fetch the encoded
- * content of the part
- *
- * @return bool
- */
- public function isStream()
- {
- return $this->_isStream;
- }
-
- /**
- * if this was created with a stream, return a filtered stream for
- * reading the content. very useful for large file attachments.
- *
- * @return stream
- * @throws Zend_Mime_Exception if not a stream or unable to append filter
- */
- public function getEncodedStream()
- {
- if (!$this->_isStream) {
- throw new Zend_Mime_Exception('Attempt to get a stream from a string part');
- }
-
- //stream_filter_remove(); // ??? is that right?
- switch ($this->encoding) {
- case Zend_Mime::ENCODING_QUOTEDPRINTABLE:
- $filter = stream_filter_append(
- $this->_content,
- 'convert.quoted-printable-encode',
- STREAM_FILTER_READ,
- array(
- 'line-length' => 76,
- 'line-break-chars' => Zend_Mime::LINEEND
- )
- );
- if (!is_resource($filter)) {
- throw new Zend_Mime_Exception('Failed to append quoted-printable filter');
- }
- break;
- case Zend_Mime::ENCODING_BASE64:
- $filter = stream_filter_append(
- $this->_content,
- 'convert.base64-encode',
- STREAM_FILTER_READ,
- array(
- 'line-length' => 76,
- 'line-break-chars' => Zend_Mime::LINEEND
- )
- );
- if (!is_resource($filter)) {
- throw new Zend_Mime_Exception('Failed to append base64 filter');
- }
- break;
- default:
- }
- return $this->_content;
- }
-
- /**
- * Get the Content of the current Mime Part in the given encoding.
- *
- * @return String
- */
- public function getContent($EOL = Zend_Mime::LINEEND)
- {
- if ($this->_isStream) {
- return stream_get_contents($this->getEncodedStream());
- } else {
- return Zend_Mime::encode($this->_content, $this->encoding, $EOL);
- }
- }
-
- /**
- * Create and return the array of headers for this MIME part
- *
- * @access public
- * @return array
- */
- public function getHeadersArray($EOL = Zend_Mime::LINEEND)
- {
- $headers = array();
-
- $contentType = $this->type;
- if ($this->charset) {
- $contentType .= '; charset="' . $this->charset . '"';
- }
-
- if ($this->boundary) {
- $contentType .= ';' . $EOL
- . " boundary=\"" . $this->boundary . '"';
- }
-
- $headers[] = array('Content-Type', $contentType);
-
- if ($this->encoding) {
- $headers[] = array('Content-Transfer-Encoding', $this->encoding);
- }
-
- if ($this->id) {
- $headers[] = array('Content-ID', '<' . $this->id . '>');
- }
-
- if ($this->disposition) {
- $disposition = $this->disposition;
- if ($this->filename) {
- $disposition .= '; filename="' . $this->filename . '"';
- }
- $headers[] = array('Content-Disposition', $disposition);
- }
-
- if ($this->description) {
- $headers[] = array('Content-Description', $this->description);
- }
-
- return $headers;
- }
-
- /**
- * Return the headers for this part as a string
- *
- * @return String
- */
- public function getHeaders($EOL = Zend_Mime::LINEEND)
- {
- $res = '';
- foreach ($this->getHeadersArray($EOL) as $header) {
- $res .= $header[0] . ': ' . $header[1] . $EOL;
- }
-
- return $res;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +/** + * Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * Zend_Mime_Exception + */ +require_once 'Zend/Mime/Exception.php'; + +/** + * Class representing a MIME part. + * + * @category Zend + * @package Zend_Mime + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mime_Part { + + public $type = Zend_Mime::TYPE_OCTETSTREAM; + public $encoding = Zend_Mime::ENCODING_8BIT; + public $id; + public $disposition; + public $filename; + public $description; + public $charset; + public $boundary; + protected $_content; + protected $_isStream = false; + + + /** + * create a new Mime Part. + * The (unencoded) content of the Part as passed + * as a string or stream + * + * @param mixed $content String or Stream containing the content + */ + public function __construct($content) + { + $this->_content = $content; + if (is_resource($content)) { + $this->_isStream = true; + } + } + + /** + * @todo setters/getters + * @todo error checking for setting $type + * @todo error checking for setting $encoding + */ + + /** + * check if this part can be read as a stream. + * if true, getEncodedStream can be called, otherwise + * only getContent can be used to fetch the encoded + * content of the part + * + * @return bool + */ + public function isStream() + { + return $this->_isStream; + } + + /** + * if this was created with a stream, return a filtered stream for + * reading the content. very useful for large file attachments. + * + * @return stream + * @throws Zend_Mime_Exception if not a stream or unable to append filter + */ + public function getEncodedStream() + { + if (!$this->_isStream) { + throw new Zend_Mime_Exception('Attempt to get a stream from a string part'); + } + + //stream_filter_remove(); // ??? is that right? + switch ($this->encoding) { + case Zend_Mime::ENCODING_QUOTEDPRINTABLE: + $filter = stream_filter_append( + $this->_content, + 'convert.quoted-printable-encode', + STREAM_FILTER_READ, + array( + 'line-length' => 76, + 'line-break-chars' => Zend_Mime::LINEEND + ) + ); + if (!is_resource($filter)) { + throw new Zend_Mime_Exception('Failed to append quoted-printable filter'); + } + break; + case Zend_Mime::ENCODING_BASE64: + $filter = stream_filter_append( + $this->_content, + 'convert.base64-encode', + STREAM_FILTER_READ, + array( + 'line-length' => 76, + 'line-break-chars' => Zend_Mime::LINEEND + ) + ); + if (!is_resource($filter)) { + throw new Zend_Mime_Exception('Failed to append base64 filter'); + } + break; + default: + } + return $this->_content; + } + + /** + * Get the Content of the current Mime Part in the given encoding. + * + * @return String + */ + public function getContent($EOL = Zend_Mime::LINEEND) + { + if ($this->_isStream) { + return stream_get_contents($this->getEncodedStream()); + } else { + return Zend_Mime::encode($this->_content, $this->encoding, $EOL); + } + } + + /** + * Create and return the array of headers for this MIME part + * + * @access public + * @return array + */ + public function getHeadersArray($EOL = Zend_Mime::LINEEND) + { + $headers = array(); + + $contentType = $this->type; + if ($this->charset) { + $contentType .= '; charset="' . $this->charset . '"'; + } + + if ($this->boundary) { + $contentType .= ';' . $EOL + . " boundary=\"" . $this->boundary . '"'; + } + + $headers[] = array('Content-Type', $contentType); + + if ($this->encoding) { + $headers[] = array('Content-Transfer-Encoding', $this->encoding); + } + + if ($this->id) { + $headers[] = array('Content-ID', '<' . $this->id . '>'); + } + + if ($this->disposition) { + $disposition = $this->disposition; + if ($this->filename) { + $disposition .= '; filename="' . $this->filename . '"'; + } + $headers[] = array('Content-Disposition', $disposition); + } + + if ($this->description) { + $headers[] = array('Content-Description', $this->description); + } + + return $headers; + } + + /** + * Return the headers for this part as a string + * + * @return String + */ + public function getHeaders($EOL = Zend_Mime::LINEEND) + { + $res = ''; + foreach ($this->getHeadersArray($EOL) as $header) { + $res .= $header[0] . ': ' . $header[1] . $EOL; + } + + return $res; + } +} diff --git a/libs/Zend/Validate/Hostname/At.php b/libs/Zend/Validate/Hostname/At.php index fff6bf247d..9c1af3c16f 100644 --- a/libs/Zend/Validate/Hostname/At.php +++ b/libs/Zend/Validate/Hostname/At.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_At implements Zend_Validate_Hostname_Interface return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}\x{0161}\x{017E}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Ch.php b/libs/Zend/Validate/Hostname/Ch.php index 72fae7b5b2..4ec753c9b4 100644 --- a/libs/Zend/Validate/Hostname/Ch.php +++ b/libs/Zend/Validate/Hostname/Ch.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_Ch implements Zend_Validate_Hostname_Interface return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/De.php b/libs/Zend/Validate/Hostname/De.php index cfea068275..c0ba18476f 100644 --- a/libs/Zend/Validate/Hostname/De.php +++ b/libs/Zend/Validate/Hostname/De.php @@ -55,4 +55,4 @@ class Zend_Validate_Hostname_De implements Zend_Validate_Hostname_Interface '\x{017E}\x{017C}\x{00F0}\x{00FE}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Fi.php b/libs/Zend/Validate/Hostname/Fi.php index a28ba56b3f..e4227e54d9 100644 --- a/libs/Zend/Validate/Hostname/Fi.php +++ b/libs/Zend/Validate/Hostname/Fi.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_Fi implements Zend_Validate_Hostname_Interface return '\x{00E5}\x{00E4}\x{00F6}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Hu.php b/libs/Zend/Validate/Hostname/Hu.php index e6f979540e..d8a8390de1 100644 --- a/libs/Zend/Validate/Hostname/Hu.php +++ b/libs/Zend/Validate/Hostname/Hu.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_Hu implements Zend_Validate_Hostname_Interface return '\x{00E1}\x{00E9}\x{00ED}\x{00F3}\x{00F6}\x{0151}\x{00FA}\x{00FC}\x{0171}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Interface.php b/libs/Zend/Validate/Hostname/Interface.php index 4426d8bd6e..dd583f5439 100644 --- a/libs/Zend/Validate/Hostname/Interface.php +++ b/libs/Zend/Validate/Hostname/Interface.php @@ -49,4 +49,4 @@ interface Zend_Validate_Hostname_Interface */ static function getCharacters(); -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Li.php b/libs/Zend/Validate/Hostname/Li.php index 0739c93824..a4d2ef7d18 100644 --- a/libs/Zend/Validate/Hostname/Li.php +++ b/libs/Zend/Validate/Hostname/Li.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_Li implements Zend_Validate_Hostname_Interface return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}'; } -}
\ No newline at end of file +} diff --git a/libs/Zend/Validate/Hostname/Se.php b/libs/Zend/Validate/Hostname/Se.php index 6f181cb652..19bf3cfc7c 100644 --- a/libs/Zend/Validate/Hostname/Se.php +++ b/libs/Zend/Validate/Hostname/Se.php @@ -47,4 +47,4 @@ class Zend_Validate_Hostname_Se implements Zend_Validate_Hostname_Interface return '\x{00E5}\x{00E4}\x{00F6}\x{00FC}\x{00E9}'; } -}
\ No newline at end of file +} diff --git a/libs/javascript/sprintf.js b/libs/javascript/sprintf.js index 6679db2c5c..96f8182415 100644 --- a/libs/javascript/sprintf.js +++ b/libs/javascript/sprintf.js @@ -1,55 +1,55 @@ -/**
- * sprintf() for JavaScript v.0.4
- *
- * Copyright (c) 2007 Alexandru Marasteanu <http://alexei.417.ro/>
- * Thanks to David Baird (unit test and patch).
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-function str_repeat(i, m) { for (var o = []; m > 0; o[--m] = i); return(o.join('')); }
-
-function sprintf (fmt, s) {
- var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
- while (f) {
- if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
- else if (m = /^\x25{2}/.exec(f)) o.push('%');
- else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
- if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments.");
- if (/[^s]/.test(m[7]) && (typeof(a) != 'number'))
- throw("Expecting number but found " + typeof(a));
- switch (m[7]) {
- case 'b': a = a.toString(2); break;
- case 'c': a = String.fromCharCode(a); break;
- case 'd': a = parseInt(a); break;
- case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
- case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
- case 'o': a = a.toString(8); break;
- case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
- case 'u': a = Math.abs(a); break;
- case 'x': a = a.toString(16); break;
- case 'X': a = a.toString(16).toUpperCase(); break;
- }
- a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
- c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
- x = m[5] - String(a).length;
- p = m[5] ? str_repeat(c, x) : '';
- o.push(m[4] ? a + p : p + a);
- }
- else throw ("Huh ?!");
- f = f.substring(m[0].length);
- }
- return o.join('');
-}
+/** + * sprintf() for JavaScript v.0.4 + * + * Copyright (c) 2007 Alexandru Marasteanu <http://alexei.417.ro/> + * Thanks to David Baird (unit test and patch). + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +function str_repeat(i, m) { for (var o = []; m > 0; o[--m] = i); return(o.join('')); } + +function sprintf (fmt, s) { + var i = 0, a, f = arguments[i++], o = [], m, p, c, x; + while (f) { + if (m = /^[^\x25]+/.exec(f)) o.push(m[0]); + else if (m = /^\x25{2}/.exec(f)) o.push('%'); + else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { + if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments."); + if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) + throw("Expecting number but found " + typeof(a)); + switch (m[7]) { + case 'b': a = a.toString(2); break; + case 'c': a = String.fromCharCode(a); break; + case 'd': a = parseInt(a); break; + case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; + case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; + case 'o': a = a.toString(8); break; + case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; + case 'u': a = Math.abs(a); break; + case 'x': a = a.toString(16); break; + case 'X': a = a.toString(16).toUpperCase(); break; + } + a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a); + c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; + x = m[5] - String(a).length; + p = m[5] ? str_repeat(c, x) : ''; + o.push(m[4] ? a + p : p + a); + } + else throw ("Huh ?!"); + f = f.substring(m[0].length); + } + return o.join(''); +} diff --git a/libs/jquery/fdd2div-modified.js b/libs/jquery/fdd2div-modified.js index 1d4a1096f5..a72c70ec72 100644 --- a/libs/jquery/fdd2div-modified.js +++ b/libs/jquery/fdd2div-modified.js @@ -1,148 +1,148 @@ -/*
- * jQuery fdd2div (Form Drop Down into Div plugin
- *
- * version 1.0 (6 May 2008)
- *
- * Licensed under GPL licenses:
- * http://www.gnu.org/licenses/gpl-3.0.html
- */
-
-/**
- * The fdd2div() method provides a simple way of converting form drop down <select> into <div>.
- *
- * fdd2div() takes 2 string and 2 integer argument: $().fdd2div({css class name, open status of the menu, create html hyper links})
- *
- * CssClassName: It will take the css class name or it will take the class name from the <div>.
- * If you don't specify an css class, default css will be used.
- *
- * OpenStatus: It will be let the menu open or close. By default it will be closed. 1 for open and 0 for closed
- *
- * @example $('#form_wrapper').fdd2div({CssClassName: "OverWrite_Default_Css_Class",OpenStatus: 1});
- * @desc Convert form drop down into div menu with css my own class (OverWrite_Default_Css_Class), menu will be open, take page name from <option> and create normal hyperlinks
- *
- * @example $('#form_wrapper').fdd2div();
- * @desc Convert form drop down into div menu with default css class which is (fdd2div_default), OpenStatus: 0 (closed)
- * @name fdd2div
- * @type jQuery
- * @param 2 String and 2 Integers Options which control the drop down menu style and status
- * @cat Plugins/fdd2div
- * @return jQuery
- * @author Aamir Afridi (aamirafridi97@hotmail.com)
- * @author Sam Clark (sam@clark.name)
- */
-
-(function($){
- $.fn.fdd2div = function(options)
- {
- var MianCssClassName="";
-
- var defaults = {
- CssClassName: "fdd2div_default"
- }
- var options = $.extend(defaults, options);
-
- if($(this).attr('class')!=null) {
- MianCssClassName=$(this).attr('class');
- } else {
- MianCssClassName=defaults.CssClassName;
- $(this).attr("class", MianCssClassName);
- }
-
- var unique_id = $(this).attr("id");
- var form = $(this).find('form');
-
- if($(this).find('form').length == 0) {
- alert("There is no/bad markup for form tag");
- } else {
- var SelectName = $(form).find('select').attr('name');
- var SelectOptions = $(form).find('option');
-
- if(SelectOptions.length == 1) {
- $(this).html(SelectOptions.html()).attr('class','test');
- return;
- }
-
- var FormMethod = $(form).attr('method');
- if(FormMethod!=null && FormMethod!="get") {
- FormMethod="post";
- }
-
- var FormAction = $(form).attr('action');
- if(FormAction == null) {
- FormAction="?";
- } else {
- FormAction+="&";
- }
-
- var main_option;
- var child_options="";
- SelectOptions.each (
- function(n,i) {
- var OptionValue="";
- if( $(i).attr('value') != "" ) {
- OptionValue=$(i).attr('value');
- } else {
- OptionValue=i.firstChild.nodeValue;
- }
-
- if($(i).attr('selected') == true) {
- main_option="<a class=\""+MianCssClassName+"_main_link collapsed\" href='"+FormAction+SelectName+"="+OptionValue+"'>"+i.firstChild.nodeValue+"</a>\n";
- } else {
- if(FormMethod=="post") {
- var newForm = CreateHiddenForm("form"+unique_id+"_"+n,FormAction,SelectName,OptionValue);
- $('body').append("<div style=\"position:absolute\">"+newForm+"</div>");
- child_options+="<li><a href='"+FormAction+"' onclick=\"document.form"+unique_id+"_"+n+".submit();return false;\">"+i.firstChild.nodeValue+"</a></li>\n";
- } else {
- child_options+="<li><a href='"+FormAction+SelectName+"="+OptionValue+"'>"+i.firstChild.nodeValue+"</a></li>\n";
- }
- }
- });
-
- var menu = main_option+"<ul class=\""+MianCssClassName+"_ul_list\" style=\"position:relative\" >"+child_options+"</ul>";
- $(this).html(menu);
-
- var child_options = "#" + unique_id + " ul";
- var main_option = "#" + unique_id + " a."+MianCssClassName+"_main_link";
-
- // hide by default
- $(child_options).hide();
-
- $(main_option).click(function () {
- if( $(this).attr("class") == MianCssClassName+"_main_link collapsed" ) {
- $(this).attr("class", MianCssClassName+"_main_link expanded");
- $(child_options).slideToggle(1);
- } else {
- $(this).attr("class", MianCssClassName+"_main_link collapsed");
- $(child_options).slideToggle(1);
- }
- return false;
- });
-
- $(window).click( function(){
- slideUpMenu();
- });
-
- $(main_option).blur( function() {
- if(!jQuery.browser.opera) {
- slideUpMenu();
- }
- });
-
- function slideUpMenu(){
- timeout = setTimeout( function(){
- // timeout after 100ms to make sure the click is triggered before the blur
- $(child_options).slideUp(1);
- $(main_option).attr("class", MianCssClassName+"_main_link collapsed");
- return false;
- }, 150);
- }
- }
-
- function CreateHiddenForm(FormName,FormAction,SelectName,OptionValue) {
- var HiddenForm;
- HiddenForm="<form method=\"post\" name='"+FormName+"' action='"+FormAction+"'><input type='hidden' name='"+SelectName+"' value='"+OptionValue+"'></form>";
- return HiddenForm;
- }
- }
-})
-(jQuery);
+/* + * jQuery fdd2div (Form Drop Down into Div plugin + * + * version 1.0 (6 May 2008) + * + * Licensed under GPL licenses: + * http://www.gnu.org/licenses/gpl-3.0.html + */ + +/** + * The fdd2div() method provides a simple way of converting form drop down <select> into <div>. + * + * fdd2div() takes 2 string and 2 integer argument: $().fdd2div({css class name, open status of the menu, create html hyper links}) + * + * CssClassName: It will take the css class name or it will take the class name from the <div>. + * If you don't specify an css class, default css will be used. + * + * OpenStatus: It will be let the menu open or close. By default it will be closed. 1 for open and 0 for closed + * + * @example $('#form_wrapper').fdd2div({CssClassName: "OverWrite_Default_Css_Class",OpenStatus: 1}); + * @desc Convert form drop down into div menu with css my own class (OverWrite_Default_Css_Class), menu will be open, take page name from <option> and create normal hyperlinks + * + * @example $('#form_wrapper').fdd2div(); + * @desc Convert form drop down into div menu with default css class which is (fdd2div_default), OpenStatus: 0 (closed) + * @name fdd2div + * @type jQuery + * @param 2 String and 2 Integers Options which control the drop down menu style and status + * @cat Plugins/fdd2div + * @return jQuery + * @author Aamir Afridi (aamirafridi97@hotmail.com) + * @author Sam Clark (sam@clark.name) + */ + +(function($){ + $.fn.fdd2div = function(options) + { + var MianCssClassName=""; + + var defaults = { + CssClassName: "fdd2div_default" + } + var options = $.extend(defaults, options); + + if($(this).attr('class')!=null) { + MianCssClassName=$(this).attr('class'); + } else { + MianCssClassName=defaults.CssClassName; + $(this).attr("class", MianCssClassName); + } + + var unique_id = $(this).attr("id"); + var form = $(this).find('form'); + + if($(this).find('form').length == 0) { + alert("There is no/bad markup for form tag"); + } else { + var SelectName = $(form).find('select').attr('name'); + var SelectOptions = $(form).find('option'); + + if(SelectOptions.length == 1) { + $(this).html(SelectOptions.html()).attr('class','test'); + return; + } + + var FormMethod = $(form).attr('method'); + if(FormMethod!=null && FormMethod!="get") { + FormMethod="post"; + } + + var FormAction = $(form).attr('action'); + if(FormAction == null) { + FormAction="?"; + } else { + FormAction+="&"; + } + + var main_option; + var child_options=""; + SelectOptions.each ( + function(n,i) { + var OptionValue=""; + if( $(i).attr('value') != "" ) { + OptionValue=$(i).attr('value'); + } else { + OptionValue=i.firstChild.nodeValue; + } + + if($(i).attr('selected') == true) { + main_option="<a class=\""+MianCssClassName+"_main_link collapsed\" href='"+FormAction+SelectName+"="+OptionValue+"'>"+i.firstChild.nodeValue+"</a>\n"; + } else { + if(FormMethod=="post") { + var newForm = CreateHiddenForm("form"+unique_id+"_"+n,FormAction,SelectName,OptionValue); + $('body').append("<div style=\"position:absolute\">"+newForm+"</div>"); + child_options+="<li><a href='"+FormAction+"' onclick=\"document.form"+unique_id+"_"+n+".submit();return false;\">"+i.firstChild.nodeValue+"</a></li>\n"; + } else { + child_options+="<li><a href='"+FormAction+SelectName+"="+OptionValue+"'>"+i.firstChild.nodeValue+"</a></li>\n"; + } + } + }); + + var menu = main_option+"<ul class=\""+MianCssClassName+"_ul_list\" style=\"position:relative\" >"+child_options+"</ul>"; + $(this).html(menu); + + var child_options = "#" + unique_id + " ul"; + var main_option = "#" + unique_id + " a."+MianCssClassName+"_main_link"; + + // hide by default + $(child_options).hide(); + + $(main_option).click(function () { + if( $(this).attr("class") == MianCssClassName+"_main_link collapsed" ) { + $(this).attr("class", MianCssClassName+"_main_link expanded"); + $(child_options).slideToggle(1); + } else { + $(this).attr("class", MianCssClassName+"_main_link collapsed"); + $(child_options).slideToggle(1); + } + return false; + }); + + $(window).click( function(){ + slideUpMenu(); + }); + + $(main_option).blur( function() { + if(!jQuery.browser.opera) { + slideUpMenu(); + } + }); + + function slideUpMenu(){ + timeout = setTimeout( function(){ + // timeout after 100ms to make sure the click is triggered before the blur + $(child_options).slideUp(1); + $(main_option).attr("class", MianCssClassName+"_main_link collapsed"); + return false; + }, 150); + } + } + + function CreateHiddenForm(FormName,FormAction,SelectName,OptionValue) { + var HiddenForm; + HiddenForm="<form method=\"post\" name='"+FormName+"' action='"+FormAction+"'><input type='hidden' name='"+SelectName+"' value='"+OptionValue+"'></form>"; + return HiddenForm; + } + } +}) +(jQuery); diff --git a/libs/jquery/jquery-calendar.css b/libs/jquery/jquery-calendar.css index 9bb82cfca9..fc40fd1d3e 100644 --- a/libs/jquery/jquery-calendar.css +++ b/libs/jquery/jquery-calendar.css @@ -187,4 +187,4 @@ img.calendar_trigger { left: -4px; /*must have*/ width: 193px; /*must have to match width and borders*/ height: 200px; /*must have to match maximum height*/ -}
\ No newline at end of file +} diff --git a/libs/jquery/jquery-calendar.js b/libs/jquery/jquery-calendar.js index cab4b44f27..6b80456d29 100644 --- a/libs/jquery/jquery-calendar.js +++ b/libs/jquery/jquery-calendar.js @@ -69,4 +69,4 @@ return this._isInRange(date);},_isInRange:function(date){var minDate=this._get(' return dateString.substring(dateFormat.charAt(3)?1:0);}});$.fn.calendar=function(settings,defaultDate){return this.each(function(){var inlineSettings=null;for(attrName in popUpCal._defaults){var attrValue=this.getAttribute('cal:'+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue);} catch(err){inlineSettings[attrName]=attrValue;}}} var nodeName=this.nodeName.toLowerCase();if(nodeName=='input'){var instSettings=(inlineSettings?$.extend($.extend({},settings||{}),inlineSettings||{}):settings);var inst=(inst&&!inlineSettings?inst:new PopUpCalInstance(instSettings,false,defaultDate));popUpCal._connectCalendar(this,inst);} -else if(nodeName=='div'||nodeName=='span'){var instSettings=$.extend($.extend({},settings||{}),inlineSettings||{});var inst=new PopUpCalInstance(instSettings,true,defaultDate);popUpCal._inlineCalendar(this,inst,defaultDate);}});};$(document).ready(function(){popUpCal=new PopUpCal();});
\ No newline at end of file +else if(nodeName=='div'||nodeName=='span'){var instSettings=$.extend($.extend({},settings||{}),inlineSettings||{});var inst=new PopUpCalInstance(instSettings,true,defaultDate);popUpCal._inlineCalendar(this,inst,defaultDate);}});};$(document).ready(function(){popUpCal=new PopUpCal();}); diff --git a/libs/jquery/jquery.blockUI.js b/libs/jquery/jquery.blockUI.js index 640e763ba9..0bb818de7a 100644 --- a/libs/jquery/jquery.blockUI.js +++ b/libs/jquery/jquery.blockUI.js @@ -19,4 +19,4 @@ else els.remove();},boxRemove:function(el){$().unbind('click',$.blockUI.impl.box this.boxCallback(this.box);$('body .displayBox').hide().remove();},handler:function(e){if(e.keyCode&&e.keyCode==9){if($.blockUI.impl.pageBlock&&!$.blockUI.defaults.allowTabToLeave){var els=$.blockUI.impl.pageBlockEls;var fwd=!e.shiftKey&&e.target==els[els.length-1];var back=e.shiftKey&&e.target==els[0];if(fwd||back){setTimeout(function(){$.blockUI.impl.focus(back)},10);return false;}}} if($(e.target).parents('div.blockMsg').length>0) return true;return $(e.target).parents().children().filter('div.blockUI').length==0;},boxHandler:function(e){if((e.keyCode&&e.keyCode==27)||(e.type=='click'&&$(e.target).parents('div.blockMsg').length==0)) -$.blockUI.impl.boxRemove();return true;},bind:function(b,el){var full=el==window;if(!b&&(full&&!this.pageBlock||!full&&!el.$blocked))return;if(!full)el.$blocked=b;var $e=$(el).find('a,:input');$.each(['mousedown','mouseup','keydown','keypress','click'],function(i,o){$e[b?'bind':'unbind'](o,$.blockUI.impl.handler);});},focus:function(back){if(!$.blockUI.impl.pageBlockEls)return;var e=$.blockUI.impl.pageBlockEls[back===true?$.blockUI.impl.pageBlockEls.length-1:0];if(e)e.focus();},center:function(el){var p=el.parentNode,s=el.style;var l=((p.offsetWidth-el.offsetWidth)/2)-this.sz(p,'borderLeftWidth');var t=((p.offsetHeight-el.offsetHeight)/2)-this.sz(p,'borderTopWidth');s.left=l>0?(l+'px'):'0';s.top=t>0?(t+'px'):'0';},sz:function(el,p){return parseInt($.css(el,p))||0;}};})(jQuery);
\ No newline at end of file +$.blockUI.impl.boxRemove();return true;},bind:function(b,el){var full=el==window;if(!b&&(full&&!this.pageBlock||!full&&!el.$blocked))return;if(!full)el.$blocked=b;var $e=$(el).find('a,:input');$.each(['mousedown','mouseup','keydown','keypress','click'],function(i,o){$e[b?'bind':'unbind'](o,$.blockUI.impl.handler);});},focus:function(back){if(!$.blockUI.impl.pageBlockEls)return;var e=$.blockUI.impl.pageBlockEls[back===true?$.blockUI.impl.pageBlockEls.length-1:0];if(e)e.focus();},center:function(el){var p=el.parentNode,s=el.style;var l=((p.offsetWidth-el.offsetWidth)/2)-this.sz(p,'borderLeftWidth');var t=((p.offsetHeight-el.offsetHeight)/2)-this.sz(p,'borderTopWidth');s.left=l>0?(l+'px'):'0';s.top=t>0?(t+'px'):'0';},sz:function(el,p){return parseInt($.css(el,p))||0;}};})(jQuery); diff --git a/libs/jquery/jquery.dimensions.js b/libs/jquery/jquery.dimensions.js index 135fcb94f5..ee79f1c7bb 100644 --- a/libs/jquery/jquery.dimensions.js +++ b/libs/jquery/jquery.dimensions.js @@ -48,4 +48,4 @@ if(options.border&&(($.browser.safari&&parseInt($.browser.version)<520)||$.brows if(options.padding){x+=num(elem,'paddingLeft');y+=num(elem,'paddingTop');} if(options.scroll&&(!$.browser.opera||elem.offsetLeft!=elem.scrollLeft&&elem.offsetTop!=elem.scrollLeft)){sl-=elem.scrollLeft;st-=elem.scrollTop;} return options.scroll?{top:y-st,left:x-sl,scrollTop:st,scrollLeft:sl}:{top:y,left:x};};var scrollbarWidth=0;var getScrollbarWidth=function(){if(!scrollbarWidth){var testEl=$('<div>').css({width:100,height:100,overflow:'auto',position:'absolute',top:-1000,left:-1000}).appendTo('body');scrollbarWidth=100-testEl.append('<div>').find('div').css({width:'100%',height:200}).width();testEl.remove();} -return scrollbarWidth;};})(jQuery);
\ No newline at end of file +return scrollbarWidth;};})(jQuery); diff --git a/libs/jquery/jquery.js b/libs/jquery/jquery.js index fbe23126e0..d44422a723 100644 --- a/libs/jquery/jquery.js +++ b/libs/jquery/jquery.js @@ -28,4 +28,4 @@ jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}}); jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else -e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=(new Date()).getTime();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522,fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})();
\ No newline at end of file +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=(new Date()).getTime();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522,fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})(); diff --git a/libs/jquery/jquery.scrollTo-min.js b/libs/jquery/jquery.scrollTo-min.js index 58512e9f25..efb727b2b0 100644 --- a/libs/jquery/jquery.scrollTo-min.js +++ b/libs/jquery/jquery.scrollTo-min.js @@ -6,4 +6,4 @@ * @author Ariel Flesler * @version 1.3 */ -;(function($){$.scrollTo=function(a,b,c){$($.browser.safari?'body':'html').scrollTo(a,b,c)};$.scrollTo.defaults={axis:'y',duration:1};$.fn.scrollTo=function(c,d,f){if(typeof d=='object'){f=d;d=0}f=$.extend({},$.scrollTo.defaults,f);if(!d)d=f.speed||f.duration;f.queue=f.queue&&f.axis.length==2;if(f.queue)d=Math.ceil(d/2);if(typeof f.offset=='number')f.offset={left:f.offset,top:f.offset};return this.each(function(){var e=this,$e=$(e),t=c,toff,j={},w=$e.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t={top:t,left:t};break}t=$(t,this);case'object':if(t.is||t.style)toff=(t=$(t)).offset()}$.each(f.axis.split(''),parse);animate(f.onAfter);function parse(i,a){var P=a=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,u=e[k];if(toff){j[k]=toff[p]+(w?0:u-$e.offset()[p]);if(f.margin){j[k]-=parseInt(t.css('margin'+P))||0;j[k]-=parseInt(t.css('border'+P+'Width'))||0}if(f.offset&&f.offset[p])j[k]+=f.offset[p]}else{j[k]=t[p]}if(/^\d+$/.test(j[k]))j[k]=j[k]<=0?0:Math.min(j[k],max(a));if(!i&&f.queue){if(u!=j[k])animate(f.onAfterFirst);delete j[k]}};function animate(a){$e.animate(j,d,f.easing,function(){if(a)a.call(this,$e,j,t)})};function max(a){var b=w?$.browser.opera?document.body:document.documentElement:e,D=a=='x'?'Width':'Height';return b['scroll'+D]-b['client'+D]}})}})(jQuery);
\ No newline at end of file +;(function($){$.scrollTo=function(a,b,c){$($.browser.safari?'body':'html').scrollTo(a,b,c)};$.scrollTo.defaults={axis:'y',duration:1};$.fn.scrollTo=function(c,d,f){if(typeof d=='object'){f=d;d=0}f=$.extend({},$.scrollTo.defaults,f);if(!d)d=f.speed||f.duration;f.queue=f.queue&&f.axis.length==2;if(f.queue)d=Math.ceil(d/2);if(typeof f.offset=='number')f.offset={left:f.offset,top:f.offset};return this.each(function(){var e=this,$e=$(e),t=c,toff,j={},w=$e.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t={top:t,left:t};break}t=$(t,this);case'object':if(t.is||t.style)toff=(t=$(t)).offset()}$.each(f.axis.split(''),parse);animate(f.onAfter);function parse(i,a){var P=a=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,u=e[k];if(toff){j[k]=toff[p]+(w?0:u-$e.offset()[p]);if(f.margin){j[k]-=parseInt(t.css('margin'+P))||0;j[k]-=parseInt(t.css('border'+P+'Width'))||0}if(f.offset&&f.offset[p])j[k]+=f.offset[p]}else{j[k]=t[p]}if(/^\d+$/.test(j[k]))j[k]=j[k]<=0?0:Math.min(j[k],max(a));if(!i&&f.queue){if(u!=j[k])animate(f.onAfterFirst);delete j[k]}};function animate(a){$e.animate(j,d,f.easing,function(){if(a)a.call(this,$e,j,t)})};function max(a){var b=w?$.browser.opera?document.body:document.documentElement:e,D=a=='x'?'Width':'Height';return b['scroll'+D]-b['client'+D]}})}})(jQuery); diff --git a/libs/jquery/jquery.scrollTo.js b/libs/jquery/jquery.scrollTo.js index ab1fe87af0..e9549c5f20 100644 --- a/libs/jquery/jquery.scrollTo.js +++ b/libs/jquery/jquery.scrollTo.js @@ -11,4 +11,4 @@ attr[key]+=settings.offset[pos];}else{attr[key]=t[pos];} if(/^\d+$/.test(attr[key])) attr[key]=attr[key]<=0?0:Math.min(attr[key],max(axis));if(!i&&settings.queue){if(act!=attr[key]) animate(settings.onAfterFirst);delete attr[key];}};function animate(callback){$elem.animate(attr,duration,settings.easing,function(){if(callback) -callback.call(this,$elem,attr,t);});};function max(axis){var el=win?$.browser.opera?document.body:document.documentElement:elem,Dim=axis=='x'?'Width':'Height';return el['scroll'+Dim]-el['client'+Dim];};});};})(jQuery);
\ No newline at end of file +callback.call(this,$elem,attr,t);});};function max(axis){var el=win?$.browser.opera?document.body:document.documentElement:elem,Dim=axis=='x'?'Width':'Height';return el['scroll'+Dim]-el['client'+Dim];};});};})(jQuery); diff --git a/libs/jquery/original lib/jquery.dimensions.js b/libs/jquery/original lib/jquery.dimensions.js index 620e182342..a05f180a60 100644 --- a/libs/jquery/original lib/jquery.dimensions.js +++ b/libs/jquery/original lib/jquery.dimensions.js @@ -652,4 +652,4 @@ var getScrollbarWidth = function() { return scrollbarWidth; }; -})(jQuery);
\ No newline at end of file +})(jQuery); diff --git a/libs/jquery/original lib/jquery.js b/libs/jquery/original lib/jquery.js index fbe23126e0..d44422a723 100644 --- a/libs/jquery/original lib/jquery.js +++ b/libs/jquery/original lib/jquery.js @@ -28,4 +28,4 @@ jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}}); jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else -e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=(new Date()).getTime();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522,fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})();
\ No newline at end of file +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=(new Date()).getTime();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522,fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})(); diff --git a/libs/jquery/original lib/jquery.scrollTo.js b/libs/jquery/original lib/jquery.scrollTo.js index eb26fc231e..4a52b73abb 100644 --- a/libs/jquery/original lib/jquery.scrollTo.js +++ b/libs/jquery/original lib/jquery.scrollTo.js @@ -139,4 +139,4 @@ }); }; -})( jQuery );
\ No newline at end of file +})( jQuery ); diff --git a/libs/jquery/superfish_modified.js b/libs/jquery/superfish_modified.js index a9557b63fd..bae8b7eb29 100644 --- a/libs/jquery/superfish_modified.js +++ b/libs/jquery/superfish_modified.js @@ -146,4 +146,4 @@ $('li',this).unbind('mouseover','mouseout','mouseenter','mouseleave'); }); }); -})(jQuery);
\ No newline at end of file +})(jQuery); diff --git a/libs/jquery/thickbox.css b/libs/jquery/thickbox.css index 1c92b89cee..1f58bc6785 100644 --- a/libs/jquery/thickbox.css +++ b/libs/jquery/thickbox.css @@ -1,194 +1,194 @@ -/* ----------------------------------------------------------------------------------------------------------------*/
- /* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/
- /* ----------------------------------------------------------------------------------------------------------------*/
- /* ----------------------------------------------------------------------------------------------------------------*/
- /* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/
- /* ----------------------------------------------------------------------------------------------------------------*/
-#TB_window {
- font: 12px Arial, Helvetica, sans-serif;
- color: #333333;
-}
-
-#TB_secondLine {
- font: 10px Arial, Helvetica, sans-serif;
- color: #666666;
-}
-
-#TB_window a:link {
- color: #666666;
-}
-
-#TB_window a:visited {
- color: #666666;
-}
-
-#TB_window a:hover {
- color: #000;
-}
-
-#TB_window a:active {
- color: #666666;
-}
-
-#TB_window a:focus {
- color: #666666;
-}
-
-/* ----------------------------------------------------------------------------------------------------------------*/
- /* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/
- /* ----------------------------------------------------------------------------------------------------------------*/
-#TB_overlay {
- position: fixed;
- z-index: 100;
- top: 0px;
- left: 0px;
- height: 100%;
- width: 100%;
-}
-
-.TB_overlayMacFFBGHack {
- background: url(libs/jquery/macFFBgHack.png) repeat;
-}
-
-.TB_overlayBG {
- background-color: #000;
- filter: alpha(opacity = 75);
- -moz-opacity: 0.75;
- opacity: 0.75;
-}
-
-* html #TB_overlay { /* ie6 hack */
- position: absolute;
- height: expression(document . body . scrollHeight > document . body .
- offsetHeight ? document . body . scrollHeight : document
- . body .
- offsetHeight + 'px');
-}
-
-#TB_window {
- position: fixed;
- background: #ffffff;
- z-index: 102;
- color: #000000;
- display: none;
- border: 4px solid #525252;
- text-align: left;
- top: 50%;
- left: 50%;
-}
-
-* html #TB_window { /* ie6 hack */
- position: absolute;
- margin-top: expression(0 - parseInt(this . offsetHeight/ 2) +
- (
- TBWindowMargin = document . documentElement && document .
- documentElement . scrollTop || document . body . scrollTop
- ) +
- 'px' );
-}
-
-#TB_window img#TB_Image {
- display: block;
- margin: 15px 0 0 15px;
- border-right: 1px solid #ccc;
- border-bottom: 1px solid #ccc;
- border-top: 1px solid #666;
- border-left: 1px solid #666;
-}
-
-#TB_caption {
- height: 25px;
- padding: 7px 30px 10px 25px;
- float: left;
-}
-
-#TB_closeWindow {
- height: 25px;
- padding: 11px 25px 10px 0;
- float: right;
-}
-
-#TB_closeAjaxWindow {
- padding: 7px 10px 5px 0;
- margin-bottom: 1px;
- text-align: right;
- float: right;
-}
-
-#TB_ajaxWindowTitle {
- float: left;
- padding: 7px 0 5px 10px;
- margin-bottom: 1px;
-}
-
-#TB_title {
- background-color: #e8e8e8;
- height: 27px;
-}
-
-#TB_ajaxContent {
- clear: both;
- padding: 2px 15px 15px 15px;
- overflow: auto;
- text-align: left;
- line-height: 1.4em;
-}
-
-#TB_ajaxContent.TB_modal {
- padding: 15px;
-}
-
-#TB_ajaxContent p {
- padding: 5px 0px 5px 0px;
-}
-
-#TB_load {
- position: fixed;
- display: none;
- height: 13px;
- width: 208px;
- z-index: 103;
- top: 50%;
- left: 50%;
- margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */
-}
-
-* html #TB_load { /* ie6 hack */
- position: absolute;
- margin-top: expression(0 - parseInt(this . offsetHeight/ 2) +
- (
- TBWindowMargin = document . documentElement && document .
- documentElement . scrollTop || document . body . scrollTop
- ) +
- 'px' );
-}
-
-#TB_HideSelect {
- z-index: 99;
- position: fixed;
- top: 0;
- left: 0;
- background-color: #fff;
- border: none;
- filter: alpha(opacity = 0);
- -moz-opacity: 0;
- opacity: 0;
- height: 100%;
- width: 100%;
-}
-
-* html #TB_HideSelect { /* ie6 hack */
- position: absolute;
- height: expression(document . body . scrollHeight > document . body .
- offsetHeight ? document . body . scrollHeight : document
- . body .
- offsetHeight + 'px');
-}
-
-#TB_iframeContent {
- clear: both;
- border: none;
- margin-bottom: -1px;
- margin-top: 1px;
- _margin-bottom: 1px;
-}
+/* ----------------------------------------------------------------------------------------------------------------*/ + /* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/ + /* ----------------------------------------------------------------------------------------------------------------*/ + /* ----------------------------------------------------------------------------------------------------------------*/ + /* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/ + /* ----------------------------------------------------------------------------------------------------------------*/ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color: #666666; +} + +#TB_window a:link { + color: #666666; +} + +#TB_window a:visited { + color: #666666; +} + +#TB_window a:hover { + color: #000; +} + +#TB_window a:active { + color: #666666; +} + +#TB_window a:focus { + color: #666666; +} + +/* ----------------------------------------------------------------------------------------------------------------*/ + /* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/ + /* ----------------------------------------------------------------------------------------------------------------*/ +#TB_overlay { + position: fixed; + z-index: 100; + top: 0px; + left: 0px; + height: 100%; + width: 100%; +} + +.TB_overlayMacFFBGHack { + background: url(libs/jquery/macFFBgHack.png) repeat; +} + +.TB_overlayBG { + background-color: #000; + filter: alpha(opacity = 75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +* html #TB_overlay { /* ie6 hack */ + position: absolute; + height: expression(document . body . scrollHeight > document . body . + offsetHeight ? document . body . scrollHeight : document + . body . + offsetHeight + 'px'); +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + color: #000000; + display: none; + border: 4px solid #525252; + text-align: left; + top: 50%; + left: 50%; +} + +* html #TB_window { /* ie6 hack */ + position: absolute; + margin-top: expression(0 - parseInt(this . offsetHeight/ 2) + + ( + TBWindowMargin = document . documentElement && document . + documentElement . scrollTop || document . body . scrollTop + ) + + 'px' ); +} + +#TB_window img#TB_Image { + display: block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption { + height: 25px; + padding: 7px 30px 10px 25px; + float: left; +} + +#TB_closeWindow { + height: 25px; + padding: 11px 25px 10px 0; + float: right; +} + +#TB_closeAjaxWindow { + padding: 7px 10px 5px 0; + margin-bottom: 1px; + text-align: right; + float: right; +} + +#TB_ajaxWindowTitle { + float: left; + padding: 7px 0 5px 10px; + margin-bottom: 1px; +} + +#TB_title { + background-color: #e8e8e8; + height: 27px; +} + +#TB_ajaxContent { + clear: both; + padding: 2px 15px 15px 15px; + overflow: auto; + text-align: left; + line-height: 1.4em; +} + +#TB_ajaxContent.TB_modal { + padding: 15px; +} + +#TB_ajaxContent p { + padding: 5px 0px 5px 0px; +} + +#TB_load { + position: fixed; + display: none; + height: 13px; + width: 208px; + z-index: 103; + top: 50%; + left: 50%; + margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ +} + +* html #TB_load { /* ie6 hack */ + position: absolute; + margin-top: expression(0 - parseInt(this . offsetHeight/ 2) + + ( + TBWindowMargin = document . documentElement && document . + documentElement . scrollTop || document . body . scrollTop + ) + + 'px' ); +} + +#TB_HideSelect { + z-index: 99; + position: fixed; + top: 0; + left: 0; + background-color: #fff; + border: none; + filter: alpha(opacity = 0); + -moz-opacity: 0; + opacity: 0; + height: 100%; + width: 100%; +} + +* html #TB_HideSelect { /* ie6 hack */ + position: absolute; + height: expression(document . body . scrollHeight > document . body . + offsetHeight ? document . body . scrollHeight : document + . body . + offsetHeight + 'px'); +} + +#TB_iframeContent { + clear: both; + border: none; + margin-bottom: -1px; + margin-top: 1px; + _margin-bottom: 1px; +} diff --git a/libs/jquery/thickbox.js b/libs/jquery/thickbox.js index 95b8ce34d2..d2cf5404a6 100644 --- a/libs/jquery/thickbox.js +++ b/libs/jquery/thickbox.js @@ -1,319 +1,319 @@ -/*
- * Thickbox 3.1 - One Box To Rule Them All.
- * By Cody Lindley (http://www.codylindley.com)
- * Copyright (c) 2007 cody lindley
- * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-var tb_pathToImage = "libs/jquery/thickbox-loading.gif";
-
-/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/
-
-//on page load call tb_init
-$(document).ready(function(){
- tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
- imgLoader = new Image();// preload image
- imgLoader.src = tb_pathToImage;
-});
-
-//add thickbox to href & area elements that have a class of .thickbox
-function tb_init(domChunk){
- $(domChunk).click(function(){
- var t = this.title || this.name || null;
- var a = this.href || this.alt;
- var g = this.rel || false;
- tb_show(t,a,g);
- this.blur();
- return false;
- });
-}
-
-function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link
-
- try {
- if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
- $("body","html").css({height: "100%", width: "100%"});
- $("html").css("overflow","hidden");
- if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
- $("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
- $("#TB_overlay").click(tb_remove);
- }
- }else{//all others
- if(document.getElementById("TB_overlay") === null){
- $("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");
- $("#TB_overlay").click(tb_remove);
- }
- }
-
- if(tb_detectMacXFF()){
- $("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
- }else{
- $("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
- }
-
- if(caption===null){caption="";}
- $("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page
- $('#TB_load').show();//show loader
-
- var baseURL;
- if(url.indexOf("?")!==-1){ //ff there is a query string involved
- baseURL = url.substr(0, url.indexOf("?"));
- }else{
- baseURL = url;
- }
-
- var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
- var urlType = baseURL.toLowerCase().match(urlString);
-
- if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images
-
- TB_PrevCaption = "";
- TB_PrevURL = "";
- TB_PrevHTML = "";
- TB_NextCaption = "";
- TB_NextURL = "";
- TB_NextHTML = "";
- TB_imageCount = "";
- TB_FoundURL = false;
- if(imageGroup){
- TB_TempArray = $("a[@rel="+imageGroup+"]").get();
- for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) {
- var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
- if (!(TB_TempArray[TB_Counter].href == url)) {
- if (TB_FoundURL) {
- TB_NextCaption = TB_TempArray[TB_Counter].title;
- TB_NextURL = TB_TempArray[TB_Counter].href;
- TB_NextHTML = "<span id='TB_next'> <a href='#'>Next ></a></span>";
- } else {
- TB_PrevCaption = TB_TempArray[TB_Counter].title;
- TB_PrevURL = TB_TempArray[TB_Counter].href;
- TB_PrevHTML = "<span id='TB_prev'> <a href='#'>< Prev</a></span>";
- }
- } else {
- TB_FoundURL = true;
- TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length);
- }
- }
- }
-
- imgPreloader = new Image();
- imgPreloader.onload = function(){
- imgPreloader.onload = null;
-
- // Resizing large images - orginal by Christian Montoya edited by me.
- var pagesize = tb_getPageSize();
- var x = pagesize[0] - 150;
- var y = pagesize[1] - 150;
- var imageWidth = imgPreloader.width;
- var imageHeight = imgPreloader.height;
- if (imageWidth > x) {
- imageHeight = imageHeight * (x / imageWidth);
- imageWidth = x;
- if (imageHeight > y) {
- imageWidth = imageWidth * (y / imageHeight);
- imageHeight = y;
- }
- } else if (imageHeight > y) {
- imageWidth = imageWidth * (y / imageHeight);
- imageHeight = y;
- if (imageWidth > x) {
- imageHeight = imageHeight * (x / imageWidth);
- imageWidth = x;
- }
- }
- // End Resizing
-
- TB_WIDTH = imageWidth + 30;
- TB_HEIGHT = imageHeight + 60;
- $("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'><img src='libs/jquery/stop.png' alt='close' /></a></div>");
-
- $("#TB_closeWindowButton").click(tb_remove);
-
- if (!(TB_PrevHTML === "")) {
- function goPrev(){
- if($(document).unbind("click",goPrev)){$(document).unbind("click",goPrev);}
- $("#TB_window").remove();
- $("body").append("<div id='TB_window'></div>");
- tb_show(TB_PrevCaption, TB_PrevURL, imageGroup);
- return false;
- }
- $("#TB_prev").click(goPrev);
- }
-
- if (!(TB_NextHTML === "")) {
- function goNext(){
- $("#TB_window").remove();
- $("body").append("<div id='TB_window'></div>");
- tb_show(TB_NextCaption, TB_NextURL, imageGroup);
- return false;
- }
- $("#TB_next").click(goNext);
-
- }
-
- document.onkeydown = function(e){
- if (e == null) { // ie
- keycode = event.keyCode;
- } else { // mozilla
- keycode = e.which;
- }
- if(keycode == 27){ // close
- tb_remove();
- } else if(keycode == 190){ // display previous image
- if(!(TB_NextHTML == "")){
- document.onkeydown = "";
- goNext();
- }
- } else if(keycode == 188){ // display next image
- if(!(TB_PrevHTML == "")){
- document.onkeydown = "";
- goPrev();
- }
- }
- };
-
- tb_position();
- $("#TB_load").remove();
- $("#TB_ImageOff").click(tb_remove);
- $("#TB_window").css({display:"block"}); //for safari using css instead of show
- };
-
- imgPreloader.src = url;
- }else{//code to show html
-
- var queryString = url.replace(/^[^\?]+\??/,'');
- var params = tb_parseQuery( queryString );
-
- TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
- TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
- ajaxContentW = TB_WIDTH - 30;
- ajaxContentH = TB_HEIGHT - 45;
-
- if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window
- urlNoQuery = url.split('TB_');
- $("#TB_iframeContent").remove();
- if(params['modal'] != "true"){//iframe no modal
- $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'><img src='libs/jquery/stop.png' alt='close' /></a></div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>");
- }else{//iframe modal
- $("#TB_overlay").unbind();
- $("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>");
- }
- }else{// not an iframe, ajax
- if($("#TB_window").css("display") != "block"){
- if(params['modal'] != "true"){//ajax no modal
- $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'><img src='libs/jquery/stop.png' alt='close' /></a></div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>");
- }else{//ajax modal
- $("#TB_overlay").unbind();
- $("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>");
- }
- }else{//this means the window is already up, we are just loading new content via ajax
- $("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
- $("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
- $("#TB_ajaxContent")[0].scrollTop = 0;
- $("#TB_ajaxWindowTitle").html(caption);
- }
- }
-
- $("#TB_closeWindowButton").click(tb_remove);
-
- if(url.indexOf('TB_inline') != -1){
- $("#TB_ajaxContent").append($('#' + params['inlineId']).children());
- $("#TB_window").unload(function () {
- $('#' + params['inlineId']).append( $("#TB_ajaxContent").children() ); // move elements back when you're finished
- });
- tb_position();
- $("#TB_load").remove();
- $("#TB_window").css({display:"block"});
- }else if(url.indexOf('TB_iframe') != -1){
- tb_position();
- if($.browser.safari){//safari needs help because it will not fire iframe onload
- $("#TB_load").remove();
- $("#TB_window").css({display:"block"});
- }
- }else{
- $("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method
- tb_position();
- $("#TB_load").remove();
- tb_init("#TB_ajaxContent a.thickbox");
- $("#TB_window").css({display:"block"});
- });
- }
-
- }
-
- if(!params['modal']){
- document.onkeyup = function(e){
- if (e == null) { // ie
- keycode = event.keyCode;
- } else { // mozilla
- keycode = e.which;
- }
- if(keycode == 27){ // close
- tb_remove();
- }
- };
- }
-
- } catch(e) {
- //nothing here
- }
-}
-
-//helper functions below
-function tb_showIframe(){
- $("#TB_load").remove();
- $("#TB_window").css({display:"block"});
-}
-
-function tb_remove() {
- $("#TB_imageOff").unbind("click");
- $("#TB_closeWindowButton").unbind("click");
- $("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();});
- $("#TB_load").remove();
- if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
- $("body","html").css({height: "auto", width: "auto"});
- $("html").css("overflow","");
- }
- document.onkeydown = "";
- document.onkeyup = "";
- return false;
-}
-
-function tb_position() {
-$("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
- if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
- $("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
- }
-}
-
-function tb_parseQuery ( query ) {
- var Params = {};
- if ( ! query ) {return Params;}// return empty object
- var Pairs = query.split(/[;&]/);
- for ( var i = 0; i < Pairs.length; i++ ) {
- var KeyVal = Pairs[i].split('=');
- if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
- var key = unescape( KeyVal[0] );
- var val = unescape( KeyVal[1] );
- val = val.replace(/\+/g, ' ');
- Params[key] = val;
- }
- return Params;
-}
-
-function tb_getPageSize(){
- var de = document.documentElement;
- var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
- var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
- arrayPageSize = [w,h];
- return arrayPageSize;
-}
-
-function tb_detectMacXFF() {
- var userAgent = navigator.userAgent.toLowerCase();
- if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
- return true;
- }
-}
-
-
+/* + * Thickbox 3.1 - One Box To Rule Them All. + * By Cody Lindley (http://www.codylindley.com) + * Copyright (c) 2007 cody lindley + * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php +*/ + +var tb_pathToImage = "libs/jquery/thickbox-loading.gif"; + +/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/ + +//on page load call tb_init +$(document).ready(function(){ + tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox + imgLoader = new Image();// preload image + imgLoader.src = tb_pathToImage; +}); + +//add thickbox to href & area elements that have a class of .thickbox +function tb_init(domChunk){ + $(domChunk).click(function(){ + var t = this.title || this.name || null; + var a = this.href || this.alt; + var g = this.rel || false; + tb_show(t,a,g); + this.blur(); + return false; + }); +} + +function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link + + try { + if (typeof document.body.style.maxHeight === "undefined") {//if IE 6 + $("body","html").css({height: "100%", width: "100%"}); + $("html").css("overflow","hidden"); + if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6 + $("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>"); + $("#TB_overlay").click(tb_remove); + } + }else{//all others + if(document.getElementById("TB_overlay") === null){ + $("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>"); + $("#TB_overlay").click(tb_remove); + } + } + + if(tb_detectMacXFF()){ + $("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash + }else{ + $("#TB_overlay").addClass("TB_overlayBG");//use background and opacity + } + + if(caption===null){caption="";} + $("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page + $('#TB_load').show();//show loader + + var baseURL; + if(url.indexOf("?")!==-1){ //ff there is a query string involved + baseURL = url.substr(0, url.indexOf("?")); + }else{ + baseURL = url; + } + + var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/; + var urlType = baseURL.toLowerCase().match(urlString); + + if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images + + TB_PrevCaption = ""; + TB_PrevURL = ""; + TB_PrevHTML = ""; + TB_NextCaption = ""; + TB_NextURL = ""; + TB_NextHTML = ""; + TB_imageCount = ""; + TB_FoundURL = false; + if(imageGroup){ + TB_TempArray = $("a[@rel="+imageGroup+"]").get(); + for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) { + var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString); + if (!(TB_TempArray[TB_Counter].href == url)) { + if (TB_FoundURL) { + TB_NextCaption = TB_TempArray[TB_Counter].title; + TB_NextURL = TB_TempArray[TB_Counter].href; + TB_NextHTML = "<span id='TB_next'> <a href='#'>Next ></a></span>"; + } else { + TB_PrevCaption = TB_TempArray[TB_Counter].title; + TB_PrevURL = TB_TempArray[TB_Counter].href; + TB_PrevHTML = "<span id='TB_prev'> <a href='#'>< Prev</a></span>"; + } + } else { + TB_FoundURL = true; + TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length); + } + } + } + + imgPreloader = new Image(); + imgPreloader.onload = function(){ + imgPreloader.onload = null; + + // Resizing large images - orginal by Christian Montoya edited by me. + var pagesize = tb_getPageSize(); + var x = pagesize[0] - 150; + var y = pagesize[1] - 150; + var imageWidth = imgPreloader.width; + var imageHeight = imgPreloader.height; + if (imageWidth > x) { + imageHeight = imageHeight * (x / imageWidth); + imageWidth = x; + if (imageHeight > y) { + imageWidth = imageWidth * (y / imageHeight); + imageHeight = y; + } + } else if (imageHeight > y) { + imageWidth = imageWidth * (y / imageHeight); + imageHeight = y; + if (imageWidth > x) { + imageHeight = imageHeight * (x / imageWidth); + imageWidth = x; + } + } + // End Resizing + + TB_WIDTH = imageWidth + 30; + TB_HEIGHT = imageHeight + 60; + $("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'><img src='libs/jquery/stop.png' alt='close' /></a></div>"); + + $("#TB_closeWindowButton").click(tb_remove); + + if (!(TB_PrevHTML === "")) { + function goPrev(){ + if($(document).unbind("click",goPrev)){$(document).unbind("click",goPrev);} + $("#TB_window").remove(); + $("body").append("<div id='TB_window'></div>"); + tb_show(TB_PrevCaption, TB_PrevURL, imageGroup); + return false; + } + $("#TB_prev").click(goPrev); + } + + if (!(TB_NextHTML === "")) { + function goNext(){ + $("#TB_window").remove(); + $("body").append("<div id='TB_window'></div>"); + tb_show(TB_NextCaption, TB_NextURL, imageGroup); + return false; + } + $("#TB_next").click(goNext); + + } + + document.onkeydown = function(e){ + if (e == null) { // ie + keycode = event.keyCode; + } else { // mozilla + keycode = e.which; + } + if(keycode == 27){ // close + tb_remove(); + } else if(keycode == 190){ // display previous image + if(!(TB_NextHTML == "")){ + document.onkeydown = ""; + goNext(); + } + } else if(keycode == 188){ // display next image + if(!(TB_PrevHTML == "")){ + document.onkeydown = ""; + goPrev(); + } + } + }; + + tb_position(); + $("#TB_load").remove(); + $("#TB_ImageOff").click(tb_remove); + $("#TB_window").css({display:"block"}); //for safari using css instead of show + }; + + imgPreloader.src = url; + }else{//code to show html + + var queryString = url.replace(/^[^\?]+\??/,''); + var params = tb_parseQuery( queryString ); + + TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL + TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL + ajaxContentW = TB_WIDTH - 30; + ajaxContentH = TB_HEIGHT - 45; + + if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window + urlNoQuery = url.split('TB_'); + $("#TB_iframeContent").remove(); + if(params['modal'] != "true"){//iframe no modal + $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'><img src='libs/jquery/stop.png' alt='close' /></a></div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>"); + }else{//iframe modal + $("#TB_overlay").unbind(); + $("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>"); + } + }else{// not an iframe, ajax + if($("#TB_window").css("display") != "block"){ + if(params['modal'] != "true"){//ajax no modal + $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'><img src='libs/jquery/stop.png' alt='close' /></a></div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>"); + }else{//ajax modal + $("#TB_overlay").unbind(); + $("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>"); + } + }else{//this means the window is already up, we are just loading new content via ajax + $("#TB_ajaxContent")[0].style.width = ajaxContentW +"px"; + $("#TB_ajaxContent")[0].style.height = ajaxContentH +"px"; + $("#TB_ajaxContent")[0].scrollTop = 0; + $("#TB_ajaxWindowTitle").html(caption); + } + } + + $("#TB_closeWindowButton").click(tb_remove); + + if(url.indexOf('TB_inline') != -1){ + $("#TB_ajaxContent").append($('#' + params['inlineId']).children()); + $("#TB_window").unload(function () { + $('#' + params['inlineId']).append( $("#TB_ajaxContent").children() ); // move elements back when you're finished + }); + tb_position(); + $("#TB_load").remove(); + $("#TB_window").css({display:"block"}); + }else if(url.indexOf('TB_iframe') != -1){ + tb_position(); + if($.browser.safari){//safari needs help because it will not fire iframe onload + $("#TB_load").remove(); + $("#TB_window").css({display:"block"}); + } + }else{ + $("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method + tb_position(); + $("#TB_load").remove(); + tb_init("#TB_ajaxContent a.thickbox"); + $("#TB_window").css({display:"block"}); + }); + } + + } + + if(!params['modal']){ + document.onkeyup = function(e){ + if (e == null) { // ie + keycode = event.keyCode; + } else { // mozilla + keycode = e.which; + } + if(keycode == 27){ // close + tb_remove(); + } + }; + } + + } catch(e) { + //nothing here + } +} + +//helper functions below +function tb_showIframe(){ + $("#TB_load").remove(); + $("#TB_window").css({display:"block"}); +} + +function tb_remove() { + $("#TB_imageOff").unbind("click"); + $("#TB_closeWindowButton").unbind("click"); + $("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();}); + $("#TB_load").remove(); + if (typeof document.body.style.maxHeight == "undefined") {//if IE 6 + $("body","html").css({height: "auto", width: "auto"}); + $("html").css("overflow",""); + } + document.onkeydown = ""; + document.onkeyup = ""; + return false; +} + +function tb_position() { +$("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'}); + if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6 + $("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'}); + } +} + +function tb_parseQuery ( query ) { + var Params = {}; + if ( ! query ) {return Params;}// return empty object + var Pairs = query.split(/[;&]/); + for ( var i = 0; i < Pairs.length; i++ ) { + var KeyVal = Pairs[i].split('='); + if ( ! KeyVal || KeyVal.length != 2 ) {continue;} + var key = unescape( KeyVal[0] ); + var val = unescape( KeyVal[1] ); + val = val.replace(/\+/g, ' '); + Params[key] = val; + } + return Params; +} + +function tb_getPageSize(){ + var de = document.documentElement; + var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; + var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight; + arrayPageSize = [w,h]; + return arrayPageSize; +} + +function tb_detectMacXFF() { + var userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) { + return true; + } +} + + diff --git a/libs/jquery/tooltip/changelog.txt b/libs/jquery/tooltip/changelog.txt index b227a63a59..6d1d5abffd 100644 --- a/libs/jquery/tooltip/changelog.txt +++ b/libs/jquery/tooltip/changelog.txt @@ -1,17 +1,17 @@ -1.1
----
-
-* Use bgiframe-plugin if available
-* Use dimensions-plugin to calculate viewport
-* Expose global blocked-property via $.Tooltip.blocked to programmatically disable all tooltips
-* Fixed image maps in IE by setting the alt-attribute to an empty string
-* Removed event-option (only hover-tooltips now)
-* Simplified event-handling (using hover instead of mouseover und mouseout)
-* Added another "pretty" example
-* Added top and left options to specify tooltip offset
-* Reworked example page: New layout, code examples
-
-1.0
----
-
-* first release considered stable
\ No newline at end of file +1.1 +--- + +* Use bgiframe-plugin if available +* Use dimensions-plugin to calculate viewport +* Expose global blocked-property via $.Tooltip.blocked to programmatically disable all tooltips +* Fixed image maps in IE by setting the alt-attribute to an empty string +* Removed event-option (only hover-tooltips now) +* Simplified event-handling (using hover instead of mouseover und mouseout) +* Added another "pretty" example +* Added top and left options to specify tooltip offset +* Reworked example page: New layout, code examples + +1.0 +--- + +* first release considered stable diff --git a/libs/jquery/tooltip/index.html b/libs/jquery/tooltip/index.html index fe9f5bd3cf..2588cfae94 100644 --- a/libs/jquery/tooltip/index.html +++ b/libs/jquery/tooltip/index.html @@ -236,4 +236,4 @@ borders</legend> $('#right2 a').Tooltip({ showURL: false });</code></pre></fieldset> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/libs/jquery/tooltip/jquery.bgiframe.js b/libs/jquery/tooltip/jquery.bgiframe.js index 5d270f3860..a6d135a595 100644 --- a/libs/jquery/tooltip/jquery.bgiframe.js +++ b/libs/jquery/tooltip/jquery.bgiframe.js @@ -101,4 +101,4 @@ $.fn.bgIframe = $.fn.bgiframe = function(s) { if (!$.browser.version) $.browser.version = navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1]; -})(jQuery);
\ No newline at end of file +})(jQuery); diff --git a/libs/jquery/tooltip/jquery.dimensions.js b/libs/jquery/tooltip/jquery.dimensions.js index 2934714e31..a7369a57e3 100644 --- a/libs/jquery/tooltip/jquery.dimensions.js +++ b/libs/jquery/tooltip/jquery.dimensions.js @@ -501,4 +501,4 @@ var handleOffsetReturn = function(elem, options, x, y, sl, st) { : { top: y, left: x }; }; -})(jQuery);
\ No newline at end of file +})(jQuery); diff --git a/libs/jquery/tooltip/jquery.tooltip.js b/libs/jquery/tooltip/jquery.tooltip.js index e3c2e9d2bf..7865f0038a 100644 --- a/libs/jquery/tooltip/jquery.tooltip.js +++ b/libs/jquery/tooltip/jquery.tooltip.js @@ -25,4 +25,4 @@ function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$ function hide(event){if($.Tooltip.blocked) return;if(tID) clearTimeout(tID);current=null;helper.parent.hide().removeClass(this.tSettings.extraClass);if(this.tSettings.fixPNG) -helper.parent.unfixPNG();}})(jQuery);
\ No newline at end of file +helper.parent.unfixPNG();}})(jQuery); diff --git a/libs/jquery/ui.mouse.js b/libs/jquery/ui.mouse.js index 76926701a2..60ef4a7868 100644 --- a/libs/jquery/ui.mouse.js +++ b/libs/jquery/ui.mouse.js @@ -22,4 +22,4 @@ this.start.apply(this,[e]);else{if(this.init==false)return false;} if(o._drag)o._drag.apply(this.element,[this.helper,this.pos,o.cursorAt,this,e]);return false;}});var num=function(el,prop){return parseInt($.css(el.jquery?el[0]:el,prop))||0;};function outerWidth(el){var $el=$(el),ow=$el.width();for(var i=0,props=['borderLeftWidth','paddingLeft','paddingRight','borderRightWidth'];i<props.length;i++) ow+=num($el,props[i]);return ow;} function outerHeight(el){var $el=$(el),oh=$el.width();for(var i=0,props=['borderTopWidth','paddingTop','paddingBottom','borderBottomWidth'];i<props.length;i++) -oh+=num($el,props[i]);return oh;}})($);
\ No newline at end of file +oh+=num($el,props[i]);return oh;}})($); diff --git a/libs/json/json.js b/libs/json/json.js index ccb1d05c1c..935bd40ce8 100644 --- a/libs/json/json.js +++ b/libs/json/json.js @@ -314,4 +314,4 @@ if (!Object.prototype.toJSONString) { return '"' + this + '"'; }; })(String.prototype); -}
\ No newline at end of file +} diff --git a/libs/open-flash-chart/README.txt b/libs/open-flash-chart/README.txt index 90f3e77a18..aadc31f98c 100644 --- a/libs/open-flash-chart/README.txt +++ b/libs/open-flash-chart/README.txt @@ -1,8 +1,8 @@ -Hello.
-
-This is the Open Flash Chart source code.
-
-Take a look around :-)
-
-The test data is in the 'data-files' directory.
-
+Hello. + +This is the Open Flash Chart source code. + +Take a look around :-) + +The test data is in the 'data-files' directory. + diff --git a/libs/swfobject/README.txt b/libs/swfobject/README.txt index db54d3ae23..7cd82f02fb 100644 --- a/libs/swfobject/README.txt +++ b/libs/swfobject/README.txt @@ -1,12 +1,12 @@ -***************
-** JS Folder **
-***************
-
-Here are some Javascript libraries used on the code or samples.
-
-- swfobject.js
-
- SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
- *
- * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
+*************** +** JS Folder ** +*************** + +Here are some Javascript libraries used on the code or samples. + +- swfobject.js + + SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ + * + * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php diff --git a/libs/swfobject/swfobject.js b/libs/swfobject/swfobject.js index 654c969a08..91ca980aa2 100644 --- a/libs/swfobject/swfobject.js +++ b/libs/swfobject/swfobject.js @@ -32,4 +32,4 @@ deconcept.SWFObjectUtil.cleanupSWFs=function(){var objects=document.getElementsB if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);} window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}} if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];}} -var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
\ No newline at end of file +var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject; diff --git a/libs/upgradephp/README b/libs/upgradephp/README index 1dd0fa9f54..22e09864c4 100644 --- a/libs/upgradephp/README +++ b/libs/upgradephp/README @@ -6,4 +6,4 @@ This library has been added to port some functions that appeared after the php 5 We removeed most of the function definitions to only leave the ones that are used in piwik. -Find the full library on http://upgradephp.berlios.de/
\ No newline at end of file +Find the full library on http://upgradephp.berlios.de/ diff --git a/libs/upgradephp/upgrade.php b/libs/upgradephp/upgrade.php index bcc862ed6d..349c0e6672 100644 --- a/libs/upgradephp/upgrade.php +++ b/libs/upgradephp/upgrade.php @@ -384,4 +384,4 @@ if (!function_exists("htmlspecialchars_decode")) { -?>
\ No newline at end of file +?> diff --git a/misc/How to install Piwik.html b/misc/How to install Piwik.html index 5632c2d727..1c336394a1 100644 --- a/misc/How to install Piwik.html +++ b/misc/How to install Piwik.html @@ -1,3 +1,3 @@ <html><head> <meta http-equiv="refresh" content="0;url=http://piwik.org/docs/installation/"/> -</head><body>You will be redirected to the Piwik Installation documentation on <a href='http://piwik.org/docs/installation/'>http://piwik.org/docs/installation/</a></html>
\ No newline at end of file +</head><body>You will be redirected to the Piwik Installation documentation on <a href='http://piwik.org/docs/installation/'>http://piwik.org/docs/installation/</a></html> diff --git a/misc/api_internal_call.php b/misc/api_internal_call.php index 9ea1083e8d..0509051c99 100644 --- a/misc/api_internal_call.php +++ b/misc/api_internal_call.php @@ -22,4 +22,4 @@ $request = new Piwik_API_Request(' $result = $request->process(); echo $result; -?>
\ No newline at end of file +?> diff --git a/misc/api_rest_call.php b/misc/api_rest_call.php index 2176c03d7f..6a1aeea231 100644 --- a/misc/api_rest_call.php +++ b/misc/api_rest_call.php @@ -27,4 +27,4 @@ foreach($content as $row) print("<b>$keyword</b> ($hits hits)<br>"); } -?>
\ No newline at end of file +?> diff --git a/misc/db-schema-README b/misc/db-schema-README index d6bc526679..965b89afb0 100755 --- a/misc/db-schema-README +++ b/misc/db-schema-README @@ -11,4 +11,4 @@ and editing beautiful database schema images so that you're proud and happy to s How to install DBDesigner on Linux http://noteplog.com/how-to-install-dbdesigner-on-linux/ - Also available for windows
\ No newline at end of file + Also available for windows diff --git a/misc/download-count.txt b/misc/download-count.txt index d3214bcff2..985144fd35 100644 --- a/misc/download-count.txt +++ b/misc/download-count.txt @@ -10,4 +10,4 @@ Count the no of hits by referers, excluding piwik.org as a referer # cat /var/log/apache2/access.log | awk '{print $11}' | grep -vE "(^"-"$|/dev.piwik.org|/piwik.org)" | sort | uniq -c | sort -rn | head -n20 Count the no of hits by referers -# cat /var/log/apache2/access.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -n20
\ No newline at end of file +# cat /var/log/apache2/access.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -n20 diff --git a/misc/generateVisitsData/AcceptLanguage.php b/misc/generateVisitsData/AcceptLanguage.php index a0d500b0fc..4994eee82b 100644 --- a/misc/generateVisitsData/AcceptLanguage.php +++ b/misc/generateVisitsData/AcceptLanguage.php @@ -525,4 +525,4 @@ $acceptLanguages = array( "fr", ); -
\ No newline at end of file + diff --git a/misc/generateVisitsData/Referers.php b/misc/generateVisitsData/Referers.php index 3515c4a572..863256194a 100644 --- a/misc/generateVisitsData/Referers.php +++ b/misc/generateVisitsData/Referers.php @@ -683,4 +683,4 @@ $referers = array( "http://www.poterie-bois.com/petits animaux/chats", "http://forum.hardware.fr/hfr/WindowsSoftware/ajout-compteur-site-sujet_172698_1.htm", "http://www.gougueule.com/Spongestats", - );
\ No newline at end of file + ); diff --git a/misc/iframeWidget.htm b/misc/iframeWidget.htm index ee070bb8f5..8a83491fbf 100644 --- a/misc/iframeWidget.htm +++ b/misc/iframeWidget.htm @@ -3,4 +3,4 @@ <h3 style="color:#143974">Embedding the Piwik Country widget in an Iframe</h3> <div id="widgetIframe"><iframe width="500" height="350" src="http://piwik.org/demo/index.php?module=Widgetize&action=iframe&moduleToWidgetize=UserCountry&actionToWidgetize=getCountry&idSite=1&period=day&date=yesterday&disableLink=1" scrolling="no" frameborder="0" marginheight="0" marginwidth="0"></iframe></div> -</body></html>
\ No newline at end of file +</body></html> diff --git a/misc/iframeWidget_localhost.htm b/misc/iframeWidget_localhost.htm index e45598f34a..615888d9a1 100644 --- a/misc/iframeWidget_localhost.htm +++ b/misc/iframeWidget_localhost.htm @@ -4,4 +4,4 @@ <div id="widgetIframe"><iframe width="500" height="350" src="http://localhost/trunk/index.php?module=Widgetize&action=iframe&moduleToWidgetize=UserCountry&actionToWidgetize=getCountry&idSite=1&period=day&date=2008-11-17&disableLink=1" scrolling="no" frameborder="0" marginheight="0" marginwidth="0"></iframe></div> -</body></html>
\ No newline at end of file +</body></html> diff --git a/misc/redirectToUrl.php b/misc/redirectToUrl.php index 0402d72192..82cb38bb48 100644 --- a/misc/redirectToUrl.php +++ b/misc/redirectToUrl.php @@ -5,4 +5,4 @@ $url = htmlentities($_GET['url']); ?> <html><head> <meta http-equiv="refresh" content="0;url=<?php echo $url; ?>"/> -</head></html>
\ No newline at end of file +</head></html> diff --git a/misc/testJavascriptTracker/page2.php b/misc/testJavascriptTracker/page2.php index 3c7b207f88..bffd36cd9a 100644 --- a/misc/testJavascriptTracker/page2.php +++ b/misc/testJavascriptTracker/page2.php @@ -42,4 +42,4 @@ piwik_log(piwik_action_name, piwik_idsite,piwik_url); </script><object> <noscript><p>Web analytics <img src="<?php echo $urlPiwik; ?>/piwik.php" style="border:0" alt="piwik"/></p> </noscript></object></a> -<!-- /Piwik -->
\ No newline at end of file +<!-- /Piwik --> diff --git a/misc/widget_example_lastvisits.html b/misc/widget_example_lastvisits.html index b9a84a3003..5adf21fdb2 100644 --- a/misc/widget_example_lastvisits.html +++ b/misc/widget_example_lastvisits.html @@ -2,4 +2,4 @@ <p>Number of visits per week for the last 52 weeks</p> <div id="widgetIframe"><iframe width="800" height="450" src="http://piwik.org/demo/index.php?module=Widgetize&action=iframe&moduleToWidgetize=VisitsSummary&actionToWidgetize=getLastVisitsGraph&idSite=1&period=week&date=last52&disableLink=1" scrolling="no" frameborder="0" marginheight="0" marginwidth="0"></iframe></div> </body> -</html>
\ No newline at end of file +</html> diff --git a/plugins/API/templates/listAllAPI.tpl b/plugins/API/templates/listAllAPI.tpl index 76d2477258..c705023428 100644 --- a/plugins/API/templates/listAllAPI.tpl +++ b/plugins/API/templates/listAllAPI.tpl @@ -22,4 +22,4 @@ {'API_QuickDocumentation'|translate:$token_auth} <span id='token_auth'>token_auth = <b>{$token_auth}</b></span> <p><i>{'API_LoadedAPIs'|translate:$countLoadedAPI}</i></p> -{$list_api_methods_with_links}
\ No newline at end of file +{$list_api_methods_with_links} diff --git a/plugins/CoreAdminHome/templates/footer.tpl b/plugins/CoreAdminHome/templates/footer.tpl index 51f0116ae5..f9ab9402da 100644 --- a/plugins/CoreAdminHome/templates/footer.tpl +++ b/plugins/CoreAdminHome/templates/footer.tpl @@ -1,2 +1,2 @@ -{include file="CoreHome/templates/piwik_tag.tpl"}
\ No newline at end of file +{include file="CoreHome/templates/piwik_tag.tpl"} diff --git a/plugins/CoreAdminHome/templates/header.tpl b/plugins/CoreAdminHome/templates/header.tpl index 55762dccb3..e1f38bf4c4 100644 --- a/plugins/CoreAdminHome/templates/header.tpl +++ b/plugins/CoreAdminHome/templates/header.tpl @@ -36,4 +36,4 @@ <br clear="all"/> -<div id="content">
\ No newline at end of file +<div id="content"> diff --git a/plugins/CoreAdminHome/templates/index.tpl b/plugins/CoreAdminHome/templates/index.tpl index 846d0ea7a3..e5ec6f5b78 100644 --- a/plugins/CoreAdminHome/templates/index.tpl +++ b/plugins/CoreAdminHome/templates/index.tpl @@ -1,17 +1,17 @@ -{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{include file="CoreAdminHome/templates/menu.tpl"}
-
-<div style="clear:both;">
-
-<div id='content'>
-{if $content}{$content}{/if}
-</div>
-
-<div id="footer" style="border-top:1px solid gray; margin-top:20px;padding-top:10px;">
-<a href='?module=CoreHome'>{'General_BackToHomepage'|translate}</a>
-
-</div>
-
-{include file="CoreAdminHome/templates/footer.tpl"}
\ No newline at end of file +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{include file="CoreAdminHome/templates/menu.tpl"} + +<div style="clear:both;"> + +<div id='content'> +{if $content}{$content}{/if} +</div> + +<div id="footer" style="border-top:1px solid gray; margin-top:20px;padding-top:10px;"> +<a href='?module=CoreHome'>{'General_BackToHomepage'|translate}</a> + +</div> + +{include file="CoreAdminHome/templates/footer.tpl"} diff --git a/plugins/CoreAdminHome/templates/menu.css b/plugins/CoreAdminHome/templates/menu.css index 312ba8a436..772e5d90eb 100644 --- a/plugins/CoreAdminHome/templates/menu.css +++ b/plugins/CoreAdminHome/templates/menu.css @@ -34,4 +34,4 @@ #tablist li a.current { background: #defdbb; -}
\ No newline at end of file +} diff --git a/plugins/CoreAdminHome/templates/menu.tpl b/plugins/CoreAdminHome/templates/menu.tpl index 9a12b5e75c..0be387ea96 100644 --- a/plugins/CoreAdminHome/templates/menu.tpl +++ b/plugins/CoreAdminHome/templates/menu.tpl @@ -6,4 +6,4 @@ <li><a href='{$url|@urlRewriteWithParameters}'>{$name}</a></li> {/foreach} </ul> -</div>
\ No newline at end of file +</div> diff --git a/plugins/CoreHome/templates/datatable.css b/plugins/CoreHome/templates/datatable.css index 5a3c3577a7..d053a2b222 100644 --- a/plugins/CoreHome/templates/datatable.css +++ b/plugins/CoreHome/templates/datatable.css @@ -344,4 +344,4 @@ tr td.label img.plusMinus { text-align: center; font-size: 0.9em; font-style: italic; -}
\ No newline at end of file +} diff --git a/plugins/CoreHome/templates/datatable.tpl b/plugins/CoreHome/templates/datatable.tpl index 55291ee9ea..a8c204e478 100644 --- a/plugins/CoreHome/templates/datatable.tpl +++ b/plugins/CoreHome/templates/datatable.tpl @@ -1,42 +1,42 @@ -<div id="{$properties.uniqueId}">
- <div class="{if isset($javascriptVariablesToSet.idSubtable)&& $javascriptVariablesToSet.idSubtable!=0}sub{/if}{if $javascriptVariablesToSet.viewDataTable=='tableAllColumns'}dataTableAllColumnsWrapper{elseif $javascriptVariablesToSet.viewDataTable=='tableGoals'}dataTableAllColumnsWrapper{else}dataTableWrapper{/if}">
- {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'}
- {$arrayDataTable.message}
- {else}
- {if count($arrayDataTable) == 0}
- <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div>
- {else}
- <a name="{$properties.uniqueId}"></a>
- <table cellspacing="0" class="dataTable">
- <thead>
- <tr>
- {foreach from=$dataTableColumns item=column}
- <th class="sortable" id="{$column.name}"><div id="thDIV">{$column.displayName}</div></th>
- {/foreach}
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$arrayDataTable item=row}
- <tr {if $row.idsubdatatable && $javascriptVariablesToSet.controllerActionCalledWhenRequestSubTable != null}class="subDataTable" id="{$row.idsubdatatable}"{/if}>
-{foreach from=$dataTableColumns item=column}
-<td>
-{if !$row.idsubdatatable && $column.name=='label' && isset($row.metadata.url)}<span id="urlLink">{$row.metadata.url}</span>{/if}
-{if $column.name=='label'}{logoHtml metadata=$row.metadata alt=$row.columns.label}{/if}
-{* sometimes all columns are not set in the datatable, we assume the value 0 *}
-{if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if}
-</td>
-{/foreach}
- </tr>
- {/foreach}
- </tbody>
- </table>
- {/if}
-
- {if $properties.show_footer}
- {include file="CoreHome/templates/datatable_footer.tpl"}
- {/if}
- {include file="CoreHome/templates/datatable_js.tpl"}
- {/if}
- </div>
-</div>
+<div id="{$properties.uniqueId}"> + <div class="{if isset($javascriptVariablesToSet.idSubtable)&& $javascriptVariablesToSet.idSubtable!=0}sub{/if}{if $javascriptVariablesToSet.viewDataTable=='tableAllColumns'}dataTableAllColumnsWrapper{elseif $javascriptVariablesToSet.viewDataTable=='tableGoals'}dataTableAllColumnsWrapper{else}dataTableWrapper{/if}"> + {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'} + {$arrayDataTable.message} + {else} + {if count($arrayDataTable) == 0} + <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div> + {else} + <a name="{$properties.uniqueId}"></a> + <table cellspacing="0" class="dataTable"> + <thead> + <tr> + {foreach from=$dataTableColumns item=column} + <th class="sortable" id="{$column.name}"><div id="thDIV">{$column.displayName}</div></th> + {/foreach} + </tr> + </thead> + + <tbody> + {foreach from=$arrayDataTable item=row} + <tr {if $row.idsubdatatable && $javascriptVariablesToSet.controllerActionCalledWhenRequestSubTable != null}class="subDataTable" id="{$row.idsubdatatable}"{/if}> +{foreach from=$dataTableColumns item=column} +<td> +{if !$row.idsubdatatable && $column.name=='label' && isset($row.metadata.url)}<span id="urlLink">{$row.metadata.url}</span>{/if} +{if $column.name=='label'}{logoHtml metadata=$row.metadata alt=$row.columns.label}{/if} +{* sometimes all columns are not set in the datatable, we assume the value 0 *} +{if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if} +</td> +{/foreach} + </tr> + {/foreach} + </tbody> + </table> + {/if} + + {if $properties.show_footer} + {include file="CoreHome/templates/datatable_footer.tpl"} + {/if} + {include file="CoreHome/templates/datatable_js.tpl"} + {/if} + </div> +</div> diff --git a/plugins/CoreHome/templates/datatable_actions.tpl b/plugins/CoreHome/templates/datatable_actions.tpl index c2dbe1868f..a383b20383 100644 --- a/plugins/CoreHome/templates/datatable_actions.tpl +++ b/plugins/CoreHome/templates/datatable_actions.tpl @@ -1,39 +1,39 @@ -<div id="{$properties.uniqueId}">
- <div class="dataTableActionsWrapper">
- {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'}
- {$arrayDataTable.message}
- {else}
- {if count($arrayDataTable) == 0}
- <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div>
- {else}
- <table cellspacing="0" class="dataTable dataTableActions">
- <thead>
- <tr>
- {foreach from=$dataTableColumns item=column}
- <th class="sortable" id="{$column.name}">{$column.displayName}</td>
- {/foreach}
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$arrayDataTable item=row}
- <tr {if $row.idsubdatatable}class="rowToProcess subActionsDataTable" id="{$row.idsubdatatable}"{else} class="actionsDataTable rowToProcess"{/if}>
- {foreach from=$dataTableColumns item=column}
- <td>
- {* sometimes all columns are not set in the datatable, we assume the value 0 *}
- {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if}
- </td>
- {/foreach}
- </tr>
- {/foreach}
- </tbody>
- </table>
- {/if}
-
- {if $properties.show_footer}
- {include file="CoreHome/templates/datatable_footer.tpl"}
- {/if}
- {include file="CoreHome/templates/datatable_actions_js.tpl"}
- {/if}
- </div>
-</div>
+<div id="{$properties.uniqueId}"> + <div class="dataTableActionsWrapper"> + {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'} + {$arrayDataTable.message} + {else} + {if count($arrayDataTable) == 0} + <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div> + {else} + <table cellspacing="0" class="dataTable dataTableActions"> + <thead> + <tr> + {foreach from=$dataTableColumns item=column} + <th class="sortable" id="{$column.name}">{$column.displayName}</td> + {/foreach} + </tr> + </thead> + + <tbody> + {foreach from=$arrayDataTable item=row} + <tr {if $row.idsubdatatable}class="rowToProcess subActionsDataTable" id="{$row.idsubdatatable}"{else} class="actionsDataTable rowToProcess"{/if}> + {foreach from=$dataTableColumns item=column} + <td> + {* sometimes all columns are not set in the datatable, we assume the value 0 *} + {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if} + </td> + {/foreach} + </tr> + {/foreach} + </tbody> + </table> + {/if} + + {if $properties.show_footer} + {include file="CoreHome/templates/datatable_footer.tpl"} + {/if} + {include file="CoreHome/templates/datatable_actions_js.tpl"} + {/if} + </div> +</div> diff --git a/plugins/CoreHome/templates/datatable_actions_recursive.tpl b/plugins/CoreHome/templates/datatable_actions_recursive.tpl index 01a22255ed..d2f1abc846 100644 --- a/plugins/CoreHome/templates/datatable_actions_recursive.tpl +++ b/plugins/CoreHome/templates/datatable_actions_recursive.tpl @@ -1,37 +1,37 @@ -<div id="{$properties.uniqueId}">
- <div class="dataTableActionsWrapper">
- {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'}
- {$arrayDataTable.message}
- {else}
- {if count($arrayDataTable) == 0}
- <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div>
- {else}
- <table cellspacing="0" class="dataTable dataTableActions">
- <thead>
- <tr>
- {foreach from=$dataTableColumns item=column}
- <th class="sortable" id="{$column.name}">{$column.displayName}</td>
- {/foreach}
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$arrayDataTable item=row}
- <tr {if $row.idsubdatatable}class="level{$row.level} rowToProcess subActionsDataTable" id="{$row.idsubdatatable}"{else}class="actionsDataTable rowToProcess level{$row.level}"{/if}>
- {foreach from=$dataTableColumns item=column}
- <td>
- {* sometimes all columns are not set in the datatable, we assume the value 0 *}
- {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if}
- </td>
- {/foreach}
- </tr>
- {/foreach}
- </tbody>
- </table>
- {/if}
-
- {include file="CoreHome/templates/datatable_footer.tpl"}
- {include file="CoreHome/templates/datatable_actions_js.tpl"}
- {/if}
- </div>
-</div>
+<div id="{$properties.uniqueId}"> + <div class="dataTableActionsWrapper"> + {if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'} + {$arrayDataTable.message} + {else} + {if count($arrayDataTable) == 0} + <div id="emptyDatatable">{'CoreHome_TableNoData'|translate}</div> + {else} + <table cellspacing="0" class="dataTable dataTableActions"> + <thead> + <tr> + {foreach from=$dataTableColumns item=column} + <th class="sortable" id="{$column.name}">{$column.displayName}</td> + {/foreach} + </tr> + </thead> + + <tbody> + {foreach from=$arrayDataTable item=row} + <tr {if $row.idsubdatatable}class="level{$row.level} rowToProcess subActionsDataTable" id="{$row.idsubdatatable}"{else}class="actionsDataTable rowToProcess level{$row.level}"{/if}> + {foreach from=$dataTableColumns item=column} + <td> + {* sometimes all columns are not set in the datatable, we assume the value 0 *} + {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if} + </td> + {/foreach} + </tr> + {/foreach} + </tbody> + </table> + {/if} + + {include file="CoreHome/templates/datatable_footer.tpl"} + {include file="CoreHome/templates/datatable_actions_js.tpl"} + {/if} + </div> +</div> diff --git a/plugins/CoreHome/templates/datatable_actions_subdatable.tpl b/plugins/CoreHome/templates/datatable_actions_subdatable.tpl index 1cfe58edc9..810002dea3 100644 --- a/plugins/CoreHome/templates/datatable_actions_subdatable.tpl +++ b/plugins/CoreHome/templates/datatable_actions_subdatable.tpl @@ -1,19 +1,19 @@ -<tr id="{$properties.uniqueId}"></tr>
-{if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'}
- {$arrayDataTable.message}
-{else}
- {if count($arrayDataTable) == 0}
- <tr><td colspan="{$nbColumns}">{'CoreHome_CategoryNoData'|translate}</td></tr>
- {else}
- {foreach from=$arrayDataTable item=row}
- <tr {if $row.idsubdatatable}class="subActionsDataTable" id="{$row.idsubdatatable}"{else}class="actionsDataTable"{/if}>
- {foreach from=$dataTableColumns item=column}
- <td>
- {* sometimes all columns are not set in the datatable, we assume the value 0 *}
- {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if}
- </td>
- {/foreach}
- </tr>
- {/foreach}
- {/if}
-{/if}
+<tr id="{$properties.uniqueId}"></tr> +{if isset($arrayDataTable.result) and $arrayDataTable.result == 'error'} + {$arrayDataTable.message} +{else} + {if count($arrayDataTable) == 0} + <tr><td colspan="{$nbColumns}">{'CoreHome_CategoryNoData'|translate}</td></tr> + {else} + {foreach from=$arrayDataTable item=row} + <tr {if $row.idsubdatatable}class="subActionsDataTable" id="{$row.idsubdatatable}"{else}class="actionsDataTable"{/if}> + {foreach from=$dataTableColumns item=column} + <td> + {* sometimes all columns are not set in the datatable, we assume the value 0 *} + {if isset($row.columns[$column.name])}{$row.columns[$column.name]}{else}0{/if} + </td> + {/foreach} + </tr> + {/foreach} + {/if} +{/if} diff --git a/plugins/CoreHome/templates/datatable_footer.tpl b/plugins/CoreHome/templates/datatable_footer.tpl index 1d92fbcad5..ed0c8f21d0 100644 --- a/plugins/CoreHome/templates/datatable_footer.tpl +++ b/plugins/CoreHome/templates/datatable_footer.tpl @@ -1,62 +1,62 @@ -<div id="dataTableFeatures">
-
-{if $properties.show_exclude_low_population}
- <span id="dataTableExcludeLowPopulation"></span>
-{/if}
-
-{if $properties.show_search}
-<span id="dataTableSearchPattern">
- <input id="keyword" type="text" length="15" />
- <input type="submit" value="{'General_Search'|translate}" />
-</span>
-{/if}
-
-{if $properties.show_offset_information}
- <span id="dataTablePages"></span>
- <span id="dataTablePrevious">‹ {'General_Previous'|translate}</span>
- <span id="dataTableNext">{'General_Next'|translate} ›</span>
-{/if}
-
-{if $properties.show_footer_icons}
- <div>
- <span id="dataTableFooterIcons">
- <span id="exportToFormat" style="display:none;padding-left:4px;">
- <img width="16" height="16" src="{$piwikUrl}themes/default/images/export.png" title="{'General_Export'|translate}" />
- <span id="linksExportToFormat" style="display:none;">
- <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="CSV" filter_limit="100">CSV</a> |
- <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="XML" filter_limit="100">XML</a> |
- <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="JSON" filter_limit="100">Json</a> |
- <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="PHP" filter_limit="100">Php</a> |
- <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="RSS" filter_limit="100" date="last10"><img border="0" src="{$piwikUrl}themes/default/images/feed.png"></a>
- </span>
- <a class="viewDataTable" format="cloud"><img width="16" height="16" src="{$piwikUrl}themes/default/images/tagcloud.png" title="{'General_TagCloud'|translate}" /></a>
- <a class="viewDataTable" format="graphVerticalBar"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_bar.png" title="{'General_VBarGraph'|translate}" /></a>
- <a class="viewDataTable" format="graphPie"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_pie.png" title="{'General_Piechart'|translate}" /></a>
- </span>
- <span id="dataTableFooterIconsShow" style="display:none;padding-left:4px;">
- <img src="{$piwikUrl}plugins/CoreHome/templates/images/more.png" />
- </span>
- {if $properties.show_table_all_columns}
- <span id="tableAllColumnsSwitch" style="display:none;float:right;padding-right:4px;border-right:1px solid #82A1D2;">
- {if $javascriptVariablesToSet.viewDataTable != 'table'}
- <img title="{'General_DisplayNormalTable'|translate}" src="{$piwikUrl}themes/default/images/table.png" />
- {else}
- <img title="{'General_DisplayMoreData'|translate}" src="{$piwikUrl}themes/default/images/table_more.png" />
- {/if}
- </span>
- {/if}
- {if $properties.show_goals}
- <span id="tableGoals" style="display:none;float:right;padding-right:4px;">
- {if $javascriptVariablesToSet.viewDataTable != 'tableGoals'}
- <img title="View Goals" src="{$piwikUrl}themes/default/images/goal.png" />
- {/if}
- </span>
- {/if}
- </span>
- </div>
-{/if}
-
-<span id="loadingDataTable"><img src="{$piwikUrl}themes/default/images/loading-blue.gif" /> {'General_LoadingData'|translate}</span>
-</div>
-
-<div class="dataTableSpacer" />
+<div id="dataTableFeatures"> + +{if $properties.show_exclude_low_population} + <span id="dataTableExcludeLowPopulation"></span> +{/if} + +{if $properties.show_search} +<span id="dataTableSearchPattern"> + <input id="keyword" type="text" length="15" /> + <input type="submit" value="{'General_Search'|translate}" /> +</span> +{/if} + +{if $properties.show_offset_information} + <span id="dataTablePages"></span> + <span id="dataTablePrevious">‹ {'General_Previous'|translate}</span> + <span id="dataTableNext">{'General_Next'|translate} ›</span> +{/if} + +{if $properties.show_footer_icons} + <div> + <span id="dataTableFooterIcons"> + <span id="exportToFormat" style="display:none;padding-left:4px;"> + <img width="16" height="16" src="{$piwikUrl}themes/default/images/export.png" title="{'General_Export'|translate}" /> + <span id="linksExportToFormat" style="display:none;"> + <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="CSV" filter_limit="100">CSV</a> | + <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="XML" filter_limit="100">XML</a> | + <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="JSON" filter_limit="100">Json</a> | + <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="PHP" filter_limit="100">Php</a> | + <a target="_blank" class="exportToFormat" methodToCall="{$properties.apiMethodToRequestDataTable}" format="RSS" filter_limit="100" date="last10"><img border="0" src="{$piwikUrl}themes/default/images/feed.png"></a> + </span> + <a class="viewDataTable" format="cloud"><img width="16" height="16" src="{$piwikUrl}themes/default/images/tagcloud.png" title="{'General_TagCloud'|translate}" /></a> + <a class="viewDataTable" format="graphVerticalBar"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_bar.png" title="{'General_VBarGraph'|translate}" /></a> + <a class="viewDataTable" format="graphPie"><img width="16" height="16" src="{$piwikUrl}themes/default/images/chart_pie.png" title="{'General_Piechart'|translate}" /></a> + </span> + <span id="dataTableFooterIconsShow" style="display:none;padding-left:4px;"> + <img src="{$piwikUrl}plugins/CoreHome/templates/images/more.png" /> + </span> + {if $properties.show_table_all_columns} + <span id="tableAllColumnsSwitch" style="display:none;float:right;padding-right:4px;border-right:1px solid #82A1D2;"> + {if $javascriptVariablesToSet.viewDataTable != 'table'} + <img title="{'General_DisplayNormalTable'|translate}" src="{$piwikUrl}themes/default/images/table.png" /> + {else} + <img title="{'General_DisplayMoreData'|translate}" src="{$piwikUrl}themes/default/images/table_more.png" /> + {/if} + </span> + {/if} + {if $properties.show_goals} + <span id="tableGoals" style="display:none;float:right;padding-right:4px;"> + {if $javascriptVariablesToSet.viewDataTable != 'tableGoals'} + <img title="View Goals" src="{$piwikUrl}themes/default/images/goal.png" /> + {/if} + </span> + {/if} + </span> + </div> +{/if} + +<span id="loadingDataTable"><img src="{$piwikUrl}themes/default/images/loading-blue.gif" /> {'General_LoadingData'|translate}</span> +</div> + +<div class="dataTableSpacer" /> diff --git a/plugins/CoreHome/templates/date.js b/plugins/CoreHome/templates/date.js index 957820f659..7ca90166a6 100644 --- a/plugins/CoreHome/templates/date.js +++ b/plugins/CoreHome/templates/date.js @@ -85,4 +85,4 @@ $(document).ready(function(){ .click(function(){ $("#calendar").toggle(); }); -} );
\ No newline at end of file +} ); diff --git a/plugins/CoreHome/templates/graph.tpl b/plugins/CoreHome/templates/graph.tpl index 4e2bd9cda4..097090bc78 100644 --- a/plugins/CoreHome/templates/graph.tpl +++ b/plugins/CoreHome/templates/graph.tpl @@ -1,10 +1,10 @@ -<div id="{$properties.uniqueId}">
- <div class="{if $graphType=='evolution'}dataTableGraphEvolutionWrapper{else}dataTableGraphWrapper{/if}">
- {$jsInvocationTag}
-
- {if $properties.show_footer}
- {include file="CoreHome/templates/datatable_footer.tpl"}
- {include file="CoreHome/templates/datatable_js.tpl"}
- {/if}
- </div>
-</div>
+<div id="{$properties.uniqueId}"> + <div class="{if $graphType=='evolution'}dataTableGraphEvolutionWrapper{else}dataTableGraphWrapper{/if}"> + {$jsInvocationTag} + + {if $properties.show_footer} + {include file="CoreHome/templates/datatable_footer.tpl"} + {include file="CoreHome/templates/datatable_js.tpl"} + {/if} + </div> +</div> diff --git a/plugins/CoreHome/templates/header.tpl b/plugins/CoreHome/templates/header.tpl index e6ff443c25..d88d17ac95 100644 --- a/plugins/CoreHome/templates/header.tpl +++ b/plugins/CoreHome/templates/header.tpl @@ -4,4 +4,4 @@ {include file="CoreHome/templates/period_select.tpl"} {include file="CoreHome/templates/js_disabled_notice.tpl"} </div> -<br />
\ No newline at end of file +<br /> diff --git a/plugins/CoreHome/templates/index.tpl b/plugins/CoreHome/templates/index.tpl index bb0dbae334..c9f16fe742 100644 --- a/plugins/CoreHome/templates/index.tpl +++ b/plugins/CoreHome/templates/index.tpl @@ -1,28 +1,28 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>Piwik › Web Analytics Reports</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Piwik {$piwik_version}" />
-<link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico">
-{loadJavascriptTranslations plugins='CoreHome'}
-{include file="CoreHome/templates/js_css_includes.tpl"}
-</head>
-
-<body>
-{include file="CoreHome/templates/js_global_variables.tpl"}
-
-{assign var=showSitesSelection value=true}
-{include file="CoreHome/templates/top_bar.tpl"}
-{include file="CoreHome/templates/header.tpl"}
-{include file="CoreHome/templates/menu.tpl"}
-<div style='clear:both'></div>
-{include file="CoreHome/templates/loading.tpl"}
-
-<div id='content'>
-{if $content}{$content}{/if}
-</div>
-
-{include file="CoreHome/templates/piwik_tag.tpl"}
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Piwik › Web Analytics Reports</title> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Piwik {$piwik_version}" /> +<link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico"> +{loadJavascriptTranslations plugins='CoreHome'} +{include file="CoreHome/templates/js_css_includes.tpl"} +</head> + +<body> +{include file="CoreHome/templates/js_global_variables.tpl"} + +{assign var=showSitesSelection value=true} +{include file="CoreHome/templates/top_bar.tpl"} +{include file="CoreHome/templates/header.tpl"} +{include file="CoreHome/templates/menu.tpl"} +<div style='clear:both'></div> +{include file="CoreHome/templates/loading.tpl"} + +<div id='content'> +{if $content}{$content}{/if} +</div> + +{include file="CoreHome/templates/piwik_tag.tpl"} +</body> +</html> diff --git a/plugins/CoreHome/templates/logo.tpl b/plugins/CoreHome/templates/logo.tpl index ebdc45e3cb..9c50908926 100644 --- a/plugins/CoreHome/templates/logo.tpl +++ b/plugins/CoreHome/templates/logo.tpl @@ -3,4 +3,4 @@ <span style="color: rgb(245, 223, 114);">P</span><span style="color: rgb(241, 175, 108);">i</span><span style="color: rgb(241, 117, 117);">w</span><span style="color: rgb(155, 106, 58);">i</span><span style="color: rgb(107, 50, 11);">k</span> {if $currentModule != 'CoreHome'}<span style="padding-left:1em;font-size: 20pt; letter-spacing: -1pt; color: rgb(107, 50, 11);">› {$currentPluginName}</span>{/if} </a> -</span>
\ No newline at end of file +</span> diff --git a/plugins/CoreHome/templates/menu.css b/plugins/CoreHome/templates/menu.css index 53ed20ee40..199a163020 100644 --- a/plugins/CoreHome/templates/menu.css +++ b/plugins/CoreHome/templates/menu.css @@ -109,4 +109,4 @@ so submenu remains hidden and JS controls when and how it appears*/ .superfish li:hover ul,.superfish li li:hover ul { top: -999em; -}
\ No newline at end of file +} diff --git a/plugins/CoreHome/templates/menu.js b/plugins/CoreHome/templates/menu.js index 665d78b011..5f0603c55f 100644 --- a/plugins/CoreHome/templates/menu.js +++ b/plugins/CoreHome/templates/menu.js @@ -110,4 +110,4 @@ $(document).ready( function(){ piwikMenu = new menu(); piwikMenu.init(); piwikMenu.loadFirstSection(); -});
\ No newline at end of file +}); diff --git a/plugins/CoreHome/templates/period_select.tpl b/plugins/CoreHome/templates/period_select.tpl index 4b2e13a568..42896afc49 100644 --- a/plugins/CoreHome/templates/period_select.tpl +++ b/plugins/CoreHome/templates/period_select.tpl @@ -1,18 +1,18 @@ -{loadJavascriptTranslations plugins='CoreHome'}
-<script type="text/javascript" src="libs/jquery/jquery-calendar.js"></script>
-<script type="text/javascript" src="plugins/CoreHome/templates/calendar.js"></script>
-<script type="text/javascript" src="plugins/CoreHome/templates/date.js"></script>
-
-<span id="periodString">
- <span id="date"><img src='plugins/CoreHome/templates/images/more_date.gif' style="vertical-align:middle" alt="" /> {$prettyDate}</span> -
- <span id="periods">
- <span id="currentPeriod">{$periodsNames.$period}</span>
- <span id="otherPeriods">
- {foreach from=$otherPeriods item=thisPeriod} | <a href='{url period=$thisPeriod}'>{$periodsNames.$thisPeriod}</a>{/foreach}
- </span>
- </span>
- <br/>
- <span id="calendar"></span>
-</span>
-<div style="clear:both"></div>
-
+{loadJavascriptTranslations plugins='CoreHome'} +<script type="text/javascript" src="libs/jquery/jquery-calendar.js"></script> +<script type="text/javascript" src="plugins/CoreHome/templates/calendar.js"></script> +<script type="text/javascript" src="plugins/CoreHome/templates/date.js"></script> + +<span id="periodString"> + <span id="date"><img src='plugins/CoreHome/templates/images/more_date.gif' style="vertical-align:middle" alt="" /> {$prettyDate}</span> - + <span id="periods"> + <span id="currentPeriod">{$periodsNames.$period}</span> + <span id="otherPeriods"> + {foreach from=$otherPeriods item=thisPeriod} | <a href='{url period=$thisPeriod}'>{$periodsNames.$thisPeriod}</a>{/foreach} + </span> + </span> + <br/> + <span id="calendar"></span> +</span> +<div style="clear:both"></div> + diff --git a/plugins/CoreHome/templates/sites_selection.tpl b/plugins/CoreHome/templates/sites_selection.tpl index 94bf5832d4..cb7c2ec88a 100644 --- a/plugins/CoreHome/templates/sites_selection.tpl +++ b/plugins/CoreHome/templates/sites_selection.tpl @@ -26,4 +26,4 @@ $("#sitesSelection").fdd2div({CssClassName:"formDiv"}); });</script> {/literal} -</span>
\ No newline at end of file +</span> diff --git a/plugins/CoreHome/templates/top_bar.tpl b/plugins/CoreHome/templates/top_bar.tpl index 3e941786d1..e176da537d 100644 --- a/plugins/CoreHome/templates/top_bar.tpl +++ b/plugins/CoreHome/templates/top_bar.tpl @@ -1,22 +1,22 @@ -{assignTopBar}
-
-<div id="topLeftBar">
-{foreach from=$topBarElements item=element}
- <span class="topBarElem">{if $element.0 == $currentModule}<b>{else}<a href="{$element.2|@urlRewriteWithParameters}" {if isset($element.3)}{$element.3}{/if}>{/if}{$element.1}{if $element.0 == $currentModule}</b>{else}</a>{/if}</span>
-{/foreach}
-{postEvent name="template_topBar"}
-</div>
-
-<div id="topRightBar">
-<nobr>
-<small>
-{'General_HelloUser'|translate:"<strong>$userLogin</strong>"}
-{if isset($userHasSomeAdminAccess) && $userHasSomeAdminAccess}| <a href='?module=CoreAdminHome'>{'General_Settings'|translate}</a>{/if}
- {if $showSitesSelection}| {include file=CoreHome/templates/sites_selection.tpl}{/if}
-| {if $userLogin == 'anonymous'}<a href='?module=Login'>{'Login_LogIn'|translate}</a>{else}<a href='?module=Login&action=logout'>{'Login_Logout'|translate}</a>{/if}
-</small>
-
-</nobr>
-</div>
-
-<br clear="all" />
\ No newline at end of file +{assignTopBar} + +<div id="topLeftBar"> +{foreach from=$topBarElements item=element} + <span class="topBarElem">{if $element.0 == $currentModule}<b>{else}<a href="{$element.2|@urlRewriteWithParameters}" {if isset($element.3)}{$element.3}{/if}>{/if}{$element.1}{if $element.0 == $currentModule}</b>{else}</a>{/if}</span> +{/foreach} +{postEvent name="template_topBar"} +</div> + +<div id="topRightBar"> +<nobr> +<small> +{'General_HelloUser'|translate:"<strong>$userLogin</strong>"} +{if isset($userHasSomeAdminAccess) && $userHasSomeAdminAccess}| <a href='?module=CoreAdminHome'>{'General_Settings'|translate}</a>{/if} + {if $showSitesSelection}| {include file=CoreHome/templates/sites_selection.tpl}{/if} +| {if $userLogin == 'anonymous'}<a href='?module=Login'>{'Login_LogIn'|translate}</a>{else}<a href='?module=Login&action=logout'>{'Login_Logout'|translate}</a>{/if} +</small> + +</nobr> +</div> + +<br clear="all" /> diff --git a/plugins/CorePluginsAdmin/templates/manage.tpl b/plugins/CorePluginsAdmin/templates/manage.tpl index 05ec6da16c..7b2e73a93b 100644 --- a/plugins/CorePluginsAdmin/templates/manage.tpl +++ b/plugins/CorePluginsAdmin/templates/manage.tpl @@ -1,54 +1,54 @@ -{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{include file="CoreAdminHome/templates/menu.tpl"}
-
-<div style="max-width:980px;">
-
-<h2>{'CorePluginsAdmin_PluginsManagement'|translate}</h2>
-<p>{'CorePluginsAdmin_MainDescription'|translate}</p>
-<table class="adminTable">
- <thead>
- <tr>
- <th>{'CorePluginsAdmin_Plugin'|translate}</th>
- <th class="num">{'CorePluginsAdmin_Version'|translate}</th>
- <th>{'CorePluginsAdmin_Description'|translate}</th>
- <th class="status">{'CorePluginsAdmin_Status'|translate}</th>
- <th class="action-links">{'CorePluginsAdmin_Action'|translate}</th>
- </tr>
- </thead>
- <tbody id="plugins">
- {foreach from=$pluginsName key=name item=plugin}
- {if !$plugin.alwaysActivated}
- <tr class={if $plugin.activated}"active"{else}class="deactivate"{/if}>
- <td class="name">
- {if isset($plugin.info.homepage)}<a title="{'CorePluginsAdmin_PluginHomepage'|translate}" href="{$plugin.info.homepage}">{/if}
- {$name}
- {if isset($plugin.info.homepage)}</a>{/if}
- </td>
- <td class="vers">{$plugin.info.version}</td>
- <td class="desc">
- {$plugin.info.description}
- <cite>By
- {if isset($plugin.info.author_homepage)}<a title="Author Homepage" href="{$plugin.info.author_homepage}">{/if}
- {$plugin.info.author}{if isset($plugin.info.author_homepage)}</a>{/if}.</cite>
- </td>
- <td class="status">
- {if $plugin.alwaysActivated}<span title="{'CorePluginsAdmin_ActivatedHelp'|translate}" class="active">{'CorePluginsAdmin_Active'|translate}</span>
- {elseif $plugin.activated}{'CorePluginsAdmin_Active'|translate}
- {else}{'CorePluginsAdmin_Inactive'|translate}{/if}
- </td>
-
- <td class="togl action-links" {if $plugin.alwaysActivated}title="{'CorePluginsAdmin_ActivatedHelp'|translate}"{/if}>
- {if $plugin.alwaysActivated} <center>-</center>
- {elseif $plugin.activated}<a href=?module=CorePluginsAdmin&action=deactivate&pluginName={$name}>{'CorePluginsAdmin_Deactivate'|translate}</a>
- {else}<a href=?module=CorePluginsAdmin&action=activate&pluginName={$name}>{'CorePluginsAdmin_Activate'|translate}</a>{/if}
- </td>
- </tr>
- {/if}
-{/foreach}
-</tbody>
-</table>
-
-</div>
-{include file="CoreAdminHome/templates/footer.tpl"}
\ No newline at end of file +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{include file="CoreAdminHome/templates/menu.tpl"} + +<div style="max-width:980px;"> + +<h2>{'CorePluginsAdmin_PluginsManagement'|translate}</h2> +<p>{'CorePluginsAdmin_MainDescription'|translate}</p> +<table class="adminTable"> + <thead> + <tr> + <th>{'CorePluginsAdmin_Plugin'|translate}</th> + <th class="num">{'CorePluginsAdmin_Version'|translate}</th> + <th>{'CorePluginsAdmin_Description'|translate}</th> + <th class="status">{'CorePluginsAdmin_Status'|translate}</th> + <th class="action-links">{'CorePluginsAdmin_Action'|translate}</th> + </tr> + </thead> + <tbody id="plugins"> + {foreach from=$pluginsName key=name item=plugin} + {if !$plugin.alwaysActivated} + <tr class={if $plugin.activated}"active"{else}class="deactivate"{/if}> + <td class="name"> + {if isset($plugin.info.homepage)}<a title="{'CorePluginsAdmin_PluginHomepage'|translate}" href="{$plugin.info.homepage}">{/if} + {$name} + {if isset($plugin.info.homepage)}</a>{/if} + </td> + <td class="vers">{$plugin.info.version}</td> + <td class="desc"> + {$plugin.info.description} + <cite>By + {if isset($plugin.info.author_homepage)}<a title="Author Homepage" href="{$plugin.info.author_homepage}">{/if} + {$plugin.info.author}{if isset($plugin.info.author_homepage)}</a>{/if}.</cite> + </td> + <td class="status"> + {if $plugin.alwaysActivated}<span title="{'CorePluginsAdmin_ActivatedHelp'|translate}" class="active">{'CorePluginsAdmin_Active'|translate}</span> + {elseif $plugin.activated}{'CorePluginsAdmin_Active'|translate} + {else}{'CorePluginsAdmin_Inactive'|translate}{/if} + </td> + + <td class="togl action-links" {if $plugin.alwaysActivated}title="{'CorePluginsAdmin_ActivatedHelp'|translate}"{/if}> + {if $plugin.alwaysActivated} <center>-</center> + {elseif $plugin.activated}<a href=?module=CorePluginsAdmin&action=deactivate&pluginName={$name}>{'CorePluginsAdmin_Deactivate'|translate}</a> + {else}<a href=?module=CorePluginsAdmin&action=activate&pluginName={$name}>{'CorePluginsAdmin_Activate'|translate}</a>{/if} + </td> + </tr> + {/if} +{/foreach} +</tbody> +</table> + +</div> +{include file="CoreAdminHome/templates/footer.tpl"} diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php index cf6773d7ac..8dab230982 100644 --- a/plugins/CoreUpdater/Controller.php +++ b/plugins/CoreUpdater/Controller.php @@ -104,4 +104,4 @@ class Piwik_CoreUpdater_Controller } } } -}
\ No newline at end of file +} diff --git a/plugins/CoreUpdater/templates/update_welcome.tpl b/plugins/CoreUpdater/templates/update_welcome.tpl index f607b66fb5..53d04240e2 100644 --- a/plugins/CoreUpdater/templates/update_welcome.tpl +++ b/plugins/CoreUpdater/templates/update_welcome.tpl @@ -20,4 +20,4 @@ <input type="submit" class="submit" value="{'CoreUpdater_UpgradePiwik'|translate}"/> </form> -{include file="CoreUpdater/templates/footer.tpl"}
\ No newline at end of file +{include file="CoreUpdater/templates/footer.tpl"} diff --git a/plugins/DBStats/DBStats.php b/plugins/DBStats/DBStats.php index 1b19b90c02..2c0b6832e1 100644 --- a/plugins/DBStats/DBStats.php +++ b/plugins/DBStats/DBStats.php @@ -35,4 +35,4 @@ class Piwik_DBStats extends Piwik_Plugin Piwik_AddAdminMenu("Database usage", array('module' => 'DBStats', 'action' => 'index')); } } -
\ No newline at end of file + diff --git a/plugins/DBStats/templates/DBStats.tpl b/plugins/DBStats/templates/DBStats.tpl index e82e095683..2a65c22fc7 100644 --- a/plugins/DBStats/templates/DBStats.tpl +++ b/plugins/DBStats/templates/DBStats.tpl @@ -1,43 +1,43 @@ -{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{include file="CoreAdminHome/templates/menu.tpl"}
-<div style="max-width:980px;">
-
-<h2>{'DBStats_DatabaseUsage'|translate}</h2>
-{assign var=totalSize value=$tablesStatus.Total.Total_length}
-<p>{'DBStats_MainDescription'|translate:$totalSize}</p>
-<table class="adminTable">
- <thead>
- <th>{'DBStats_Table'|translate}</th>
- <th>{'DBStats_RowNumber'|translate}</th>
- <th>{'DBStats_DataSize'|translate}</th>
- <th>{'DBStats_IndexSize'|translate}</th>
- <th>{'DBStats_TotalSize'|translate}</th>
- </thead>
- <tbody id="tables">
- {foreach from=$tablesStatus key=index item=table}
- <tr {if $table.Name == 'Total'}class="active" style="font-weight:bold;"{/if}>
- <td>
- {$table.Name}
- </td>
- <td>
- {$table.Rows}
- </td>
- <td>
- {$table.Data_length}b
- </td>
- <td>
- {$table.Index_length}b
- </td>
- <td>
- {$table.Total_length}b
- </td>
- </tr>
- {/foreach}
- </tbody>
-</table>
-
-</div>
-
-{include file="CoreAdminHome/templates/footer.tpl"}
\ No newline at end of file +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{include file="CoreAdminHome/templates/menu.tpl"} +<div style="max-width:980px;"> + +<h2>{'DBStats_DatabaseUsage'|translate}</h2> +{assign var=totalSize value=$tablesStatus.Total.Total_length} +<p>{'DBStats_MainDescription'|translate:$totalSize}</p> +<table class="adminTable"> + <thead> + <th>{'DBStats_Table'|translate}</th> + <th>{'DBStats_RowNumber'|translate}</th> + <th>{'DBStats_DataSize'|translate}</th> + <th>{'DBStats_IndexSize'|translate}</th> + <th>{'DBStats_TotalSize'|translate}</th> + </thead> + <tbody id="tables"> + {foreach from=$tablesStatus key=index item=table} + <tr {if $table.Name == 'Total'}class="active" style="font-weight:bold;"{/if}> + <td> + {$table.Name} + </td> + <td> + {$table.Rows} + </td> + <td> + {$table.Data_length}b + </td> + <td> + {$table.Index_length}b + </td> + <td> + {$table.Total_length}b + </td> + </tr> + {/foreach} + </tbody> +</table> + +</div> + +{include file="CoreAdminHome/templates/footer.tpl"} diff --git a/plugins/Dashboard/templates/dashboard.css b/plugins/Dashboard/templates/dashboard.css index 2a034ba4ab..a13cd6867f 100644 --- a/plugins/Dashboard/templates/dashboard.css +++ b/plugins/Dashboard/templates/dashboard.css @@ -184,4 +184,4 @@ ul#widgetList { #widgetChooser { z-index:100; -}
\ No newline at end of file +} diff --git a/plugins/ExampleAPI/ExampleAPI.php b/plugins/ExampleAPI/ExampleAPI.php index 782e1ac02e..fe32fb9dc4 100644 --- a/plugins/ExampleAPI/ExampleAPI.php +++ b/plugins/ExampleAPI/ExampleAPI.php @@ -11,4 +11,4 @@ class Piwik_ExampleAPI extends Piwik_Plugin 'version' => '0.1', ); } -}
\ No newline at end of file +} diff --git a/plugins/ExampleFeedburner/ExampleFeedburner.php b/plugins/ExampleFeedburner/ExampleFeedburner.php index 498c6ec222..7a50ec59c6 100644 --- a/plugins/ExampleFeedburner/ExampleFeedburner.php +++ b/plugins/ExampleFeedburner/ExampleFeedburner.php @@ -72,4 +72,4 @@ class Piwik_ExampleFeedburner_Controller extends Piwik_Controller ); } } -}
\ No newline at end of file +} diff --git a/plugins/ExampleFeedburner/feedburner.tpl b/plugins/ExampleFeedburner/feedburner.tpl index dd59dd0379..95ea984c98 100644 --- a/plugins/ExampleFeedburner/feedburner.tpl +++ b/plugins/ExampleFeedburner/feedburner.tpl @@ -1,37 +1,37 @@ -
-<script type="text/javascript">
- var idSite = {$idSite};
-
-{literal}
- $(document).ready(function(){
-
- function getName()
- {
- return $("#feedburnerName").val();
- }
- function loadIframe()
- {
- var feedburnerName = getName();
- $("#feedburnerIframe").html(
- '<iframe height=100px frameborder="0" marginheight="10" marginwidth="10" \
- src="http://www.feedburner.com/fb/ticker/api-ticker2.jsp?uris='+feedburnerName+'"></iframe>');
- }
-
- $("#feedburnerSubmit").click( function(){
- var feedburnerName = getName();
- $.get('?module=ExampleFeedburner&action=saveFeedburnerName&idSite='+idSite+'&name='+feedburnerName);
- loadIframe();
-
- });
-
- loadIframe();
-});
-</script>
-{/literal}
-<span id="feedburnerIframe"></span>
-
-<center>
-<input id="feedburnerName" type="text" value="{$feedburnerFeedName}">
-<input id="feedburnerSubmit" type="submit" value="ok">
-</center>
-
+ +<script type="text/javascript"> + var idSite = {$idSite}; + +{literal} + $(document).ready(function(){ + + function getName() + { + return $("#feedburnerName").val(); + } + function loadIframe() + { + var feedburnerName = getName(); + $("#feedburnerIframe").html( + '<iframe height=100px frameborder="0" marginheight="10" marginwidth="10" \ + src="http://www.feedburner.com/fb/ticker/api-ticker2.jsp?uris='+feedburnerName+'"></iframe>'); + } + + $("#feedburnerSubmit").click( function(){ + var feedburnerName = getName(); + $.get('?module=ExampleFeedburner&action=saveFeedburnerName&idSite='+idSite+'&name='+feedburnerName); + loadIframe(); + + }); + + loadIframe(); +}); +</script> +{/literal} +<span id="feedburnerIframe"></span> + +<center> +<input id="feedburnerName" type="text" value="{$feedburnerFeedName}"> +<input id="feedburnerSubmit" type="submit" value="ok"> +</center> + diff --git a/plugins/ExampleRssWidget/ExampleRssWidget.php b/plugins/ExampleRssWidget/ExampleRssWidget.php index da3745ce41..43c11691e9 100644 --- a/plugins/ExampleRssWidget/ExampleRssWidget.php +++ b/plugins/ExampleRssWidget/ExampleRssWidget.php @@ -59,4 +59,4 @@ class Piwik_ExampleRssWidget_Controller extends Piwik_Controller echo '</ul></div>'; } -}
\ No newline at end of file +} diff --git a/plugins/ExampleRssWidget/styles.css b/plugins/ExampleRssWidget/styles.css index c0c284c60b..82521c7045 100644 --- a/plugins/ExampleRssWidget/styles.css +++ b/plugins/ExampleRssWidget/styles.css @@ -28,4 +28,4 @@ line-height:1.5em; font-size:11px; color:#333333; -}
\ No newline at end of file +} diff --git a/plugins/Feedback/index.tpl b/plugins/Feedback/index.tpl index 36cc795a6d..62f1d16c2f 100644 --- a/plugins/Feedback/index.tpl +++ b/plugins/Feedback/index.tpl @@ -1,23 +1,24 @@ -{literal}
-<style>
-input, textarea, p {
- font-family: Georgia,"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
- font-size:0.9em;
- padding:0.2em;
-}
-input {
- margin-top:0.8em;
-}
-</style>
-{/literal}
-
-<form method="post" action="?module=Feedback&action=sendFeedback">
-
-<p><strong>your email :</strong>
-<br /><input type="text" name="email" size="40" /></p>
-<p><strong>your feedback:</strong><br/>
-<i>please be precise if you request for a feature or report a bug</i></p>
-<textarea name="body" cols="37" rows="10"></textarea>
-<br/>
-<input type="submit" value="Send feedback" />
-</form>
+{literal} +<style> +input, textarea, p { + font-family: Georgia,"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + font-size:0.9em; + padding:0.2em; +} +input { + margin-top:0.8em; +} +</style> +{/literal} + +<form method="post" action="?module=Feedback&action=sendFeedback"> + +<p><strong>your email :</strong> +<br /><input type="text" name="email" size="40" /></p> + +<p><strong>your feedback:</strong><br/> +<i>please be precise if you request for a feature or report a bug</i></p> +<textarea name="body" cols="37" rows="10"></textarea> +<br/> +<input type="submit" value="Send feedback" /> +</form> diff --git a/plugins/Feedback/sent.tpl b/plugins/Feedback/sent.tpl index 1b32a9ff47..65495497bf 100644 --- a/plugins/Feedback/sent.tpl +++ b/plugins/Feedback/sent.tpl @@ -1,33 +1,33 @@ -{literal}
-<style>
-body {
- font-family: Georgia,"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
- font-size:0.9em;
- padding:0.2em;
-}
-#error {
- color: red;
- text-align: center;
- border: 2px solid red;
- background-color:#FFFBFB;
- margin: 10px;
- padding: 10px;
-}
-#success {
- color: #38D73B;
- text-align: center;
- border: 2px solid red;
- margin: 10px;
- padding: 10px;
-}
-</style>
-{/literal}
-
-{if isset($ErrorString)}
- <div id="error"><strong>{'General_Error'|translate}:</strong> {$ErrorString}</div>
- <p>Please manually send your message at <a href='mailto:hello@piwik.org'>hello@piwik.org</a></p>
- <p>{$message}</p>
-{else}
- <div id="success">Your message was sent to Piwik.</div>
- <p><strong>Thank you for your helping us making Piwik better!</strong><br /> The Piwik Team</p>
-{/if}
+{literal} +<style> +body { + font-family: Georgia,"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + font-size:0.9em; + padding:0.2em; +} +#error { + color: red; + text-align: center; + border: 2px solid red; + background-color:#FFFBFB; + margin: 10px; + padding: 10px; +} +#success { + color: #38D73B; + text-align: center; + border: 2px solid red; + margin: 10px; + padding: 10px; +} +</style> +{/literal} + +{if isset($ErrorString)} + <div id="error"><strong>{'General_Error'|translate}:</strong> {$ErrorString}</div> + <p>Please manually send your message at <a href='mailto:hello@piwik.org'>hello@piwik.org</a></p> + <p>{$message}</p> +{else} + <div id="success">Your message was sent to Piwik.</div> + <p><strong>Thank you for your helping us making Piwik better!</strong><br /> The Piwik Team</p> +{/if} diff --git a/plugins/Goals/templates/GoalForm.js b/plugins/Goals/templates/GoalForm.js index 4345bc8958..a3f82154c5 100644 --- a/plugins/Goals/templates/GoalForm.js +++ b/plugins/Goals/templates/GoalForm.js @@ -121,4 +121,4 @@ function getAjaxAddGoal() ajaxRequest.data = parameters; return ajaxRequest; -}
\ No newline at end of file +} diff --git a/plugins/Goals/templates/form_add_goal.tpl b/plugins/Goals/templates/form_add_goal.tpl index 95c4f6d3d9..00629801b8 100644 --- a/plugins/Goals/templates/form_add_goal.tpl +++ b/plugins/Goals/templates/form_add_goal.tpl @@ -64,4 +64,4 @@ color:#9B9B9B; </tr> </table> </form> -</span>
\ No newline at end of file +</span> diff --git a/plugins/Goals/templates/list_goal_edit.tpl b/plugins/Goals/templates/list_goal_edit.tpl index 081497cade..615c9f9174 100644 --- a/plugins/Goals/templates/list_goal_edit.tpl +++ b/plugins/Goals/templates/list_goal_edit.tpl @@ -19,4 +19,4 @@ </tr> {/foreach} </table> -</span>
\ No newline at end of file +</span> diff --git a/plugins/Goals/templates/overview.tpl b/plugins/Goals/templates/overview.tpl index 04bf1af90d..c5e27cb546 100644 --- a/plugins/Goals/templates/overview.tpl +++ b/plugins/Goals/templates/overview.tpl @@ -24,4 +24,4 @@ {include file=Goals/templates/add_edit_goal.tpl} {/if} -{include file="Goals/templates/release_notes.tpl}
\ No newline at end of file +{include file="Goals/templates/release_notes.tpl} diff --git a/plugins/Goals/templates/release_notes.tpl b/plugins/Goals/templates/release_notes.tpl index dce9ec63b2..8e8c73dfa4 100644 --- a/plugins/Goals/templates/release_notes.tpl +++ b/plugins/Goals/templates/release_notes.tpl @@ -17,4 +17,4 @@ Known bugs Give us Feedback! If you find any other bug, or if you have suggestions, please send us a message using the "Give us feedback" link at the top of the Piwik pages. -</pre>
\ No newline at end of file +</pre> diff --git a/plugins/Goals/templates/single_goal.tpl b/plugins/Goals/templates/single_goal.tpl index b605c17490..2cb3ddde27 100644 --- a/plugins/Goals/templates/single_goal.tpl +++ b/plugins/Goals/templates/single_goal.tpl @@ -34,4 +34,4 @@ $(document).ready( function() { ; }); </script> -{/literal}
\ No newline at end of file +{/literal} diff --git a/plugins/Installation/View.php b/plugins/Installation/View.php index ecbcd51aac..cc623d2f45 100644 --- a/plugins/Installation/View.php +++ b/plugins/Installation/View.php @@ -45,4 +45,4 @@ class Piwik_Install_View extends Piwik_View return parent::render(); } -}
\ No newline at end of file +} diff --git a/plugins/Installation/templates/allSteps.tpl b/plugins/Installation/templates/allSteps.tpl index 6bf66d0f9c..5d73449c24 100644 --- a/plugins/Installation/templates/allSteps.tpl +++ b/plugins/Installation/templates/allSteps.tpl @@ -8,4 +8,4 @@ <li class="futureStep">{$stepName}</li> {/if} {/foreach} -</ul>
\ No newline at end of file +</ul> diff --git a/plugins/Installation/templates/databaseSetup.tpl b/plugins/Installation/templates/databaseSetup.tpl index da94a91143..95487358b7 100644 --- a/plugins/Installation/templates/databaseSetup.tpl +++ b/plugins/Installation/templates/databaseSetup.tpl @@ -1,14 +1,14 @@ -<h1>{'Installation_MysqlSetup'|translate}</h1>
-
-{if isset($errorMessage)}
- <div class="error">
- <img src="themes/default/images/error_medium.png">
- {'Installation_MysqlErrorConnect'|translate}:
- <br />{$errorMessage}
-
- </div>
-{/if}
-
-{if isset($form_data)}
- {include file=default/genericForm.tpl}
-{/if}
+<h1>{'Installation_MysqlSetup'|translate}</h1> + +{if isset($errorMessage)} + <div class="error"> + <img src="themes/default/images/error_medium.png"> + {'Installation_MysqlErrorConnect'|translate}: + <br />{$errorMessage} + + </div> +{/if} + +{if isset($form_data)} + {include file=default/genericForm.tpl} +{/if} diff --git a/plugins/Installation/templates/displayJavascriptCode.tpl b/plugins/Installation/templates/displayJavascriptCode.tpl index c030b7a514..1d856ab65d 100644 --- a/plugins/Installation/templates/displayJavascriptCode.tpl +++ b/plugins/Installation/templates/displayJavascriptCode.tpl @@ -1,46 +1,46 @@ -
-{literal}
-<style>
-code {
- background-color:#F0F7FF;
- border-color:#00008B;
- border-style:dashed dashed dashed solid;
- border-width:1px 1px 1px 5px;
- direction:ltr;
- display:block;
- font-size:80%;
- margin:2px 2px 20px;
- padding:4px;
- text-align:left;
-}
-</style>
-
-<script>
-$(document).ready( function(){
- $('code').click( function(){ $(this).select(); });
-});
-</script>
-
-{/literal}
-
-{if isset($displayfirstWebsiteSetupSuccess)}
-
-<span id="toFade" class="success">
- Website {$websiteName} created with success!
- <img src="themes/default/images/success_medium.png">
-</span>
-{/if}
-<h1>{'Installation_JsTag'|translate}</h1>
-{'Installation_JsTagHelp'|translate}
-<code>
-{$javascriptTag}
-</code>
-
-<h1>Quick help:</h1>
-<ul>
-<li>The best is to add the tag just before your </body> at the bottom of your pages</li>
-<li>You can generally edit your website templates and add this code in a "footer" file.</li>
-<li><a target="_blank" href="http://piwik.org/docs/javascript-tracking/">More information about the Javascript Tracking</a>.</li>
-<li>For medium and high traffic websites, check out the <a target="_blank" href="http://piwik.org/docs/setup-auto-archiving/">How to setup auto archiving page</a> to make Piwik run really fast!</li>
-<!-- <li>Link to help with the main blog engines wordpress/drupal/myspace/blogspot</li> -->
-</ul>
+ +{literal} +<style> +code { + background-color:#F0F7FF; + border-color:#00008B; + border-style:dashed dashed dashed solid; + border-width:1px 1px 1px 5px; + direction:ltr; + display:block; + font-size:80%; + margin:2px 2px 20px; + padding:4px; + text-align:left; +} +</style> + +<script> +$(document).ready( function(){ + $('code').click( function(){ $(this).select(); }); +}); +</script> + +{/literal} + +{if isset($displayfirstWebsiteSetupSuccess)} + +<span id="toFade" class="success"> + Website {$websiteName} created with success! + <img src="themes/default/images/success_medium.png"> +</span> +{/if} +<h1>{'Installation_JsTag'|translate}</h1> +{'Installation_JsTagHelp'|translate} +<code> +{$javascriptTag} +</code> + +<h1>Quick help:</h1> +<ul> +<li>The best is to add the tag just before your </body> at the bottom of your pages</li> +<li>You can generally edit your website templates and add this code in a "footer" file.</li> +<li><a target="_blank" href="http://piwik.org/docs/javascript-tracking/">More information about the Javascript Tracking</a>.</li> +<li>For medium and high traffic websites, check out the <a target="_blank" href="http://piwik.org/docs/setup-auto-archiving/">How to setup auto archiving page</a> to make Piwik run really fast!</li> +<!-- <li>Link to help with the main blog engines wordpress/drupal/myspace/blogspot</li> --> +</ul> diff --git a/plugins/Installation/templates/finished.tpl b/plugins/Installation/templates/finished.tpl index 92fa772f15..4dd50d6820 100644 --- a/plugins/Installation/templates/finished.tpl +++ b/plugins/Installation/templates/finished.tpl @@ -1,8 +1,8 @@ -<h1>{'Installation_Congratulations'|translate}</h1>
-
-{'Installation_CongratulationsHelp'|translate}
-
-
-<p class="nextStep">
- <a href="{url module='' action=''}">{'Installation_ContinueToPiwik'|translate} »</a>
-</p>
+<h1>{'Installation_Congratulations'|translate}</h1> + +{'Installation_CongratulationsHelp'|translate} + + +<p class="nextStep"> + <a href="{url module='' action=''}">{'Installation_ContinueToPiwik'|translate} »</a> +</p> diff --git a/plugins/Installation/templates/firstWebsiteSetup.tpl b/plugins/Installation/templates/firstWebsiteSetup.tpl index 3c0446bc3c..2e97223be7 100644 --- a/plugins/Installation/templates/firstWebsiteSetup.tpl +++ b/plugins/Installation/templates/firstWebsiteSetup.tpl @@ -1,23 +1,23 @@ -
-
-{if isset($displayGeneralSetupSuccess)}
-<span id="toFade" class="success">
- {'Installation_GeneralSetupSuccess'|translate}
- <img src="themes/default/images/success_medium.png">
-</span>
-{/if}
-
-<h1>{'Installation_SetupWebsite'|translate}</h1>
-
-{if isset($errorMessage)}
- <div class="error">
- <img src="themes/default/images/error_medium.png">
- {'Installation_SetupWebsiteError'|translate}:
- <br />- {$errorMessage}
-
- </div>
-{/if}
-
-{if isset($form_data)}
- {include file=default/genericForm.tpl}
-{/if}
+ + +{if isset($displayGeneralSetupSuccess)} +<span id="toFade" class="success"> + {'Installation_GeneralSetupSuccess'|translate} + <img src="themes/default/images/success_medium.png"> +</span> +{/if} + +<h1>{'Installation_SetupWebsite'|translate}</h1> + +{if isset($errorMessage)} + <div class="error"> + <img src="themes/default/images/error_medium.png"> + {'Installation_SetupWebsiteError'|translate}: + <br />- {$errorMessage} + + </div> +{/if} + +{if isset($form_data)} + {include file=default/genericForm.tpl} +{/if} diff --git a/plugins/Installation/templates/generalSetup.tpl b/plugins/Installation/templates/generalSetup.tpl index 221b30261b..869addbf25 100644 --- a/plugins/Installation/templates/generalSetup.tpl +++ b/plugins/Installation/templates/generalSetup.tpl @@ -1,5 +1,5 @@ -<h1>{'Installation_GeneralSetup'|translate}</h1>
-
-{if isset($form_data)}
- {include file=default/genericForm.tpl}
-{/if}
\ No newline at end of file +<h1>{'Installation_GeneralSetup'|translate}</h1> + +{if isset($form_data)} + {include file=default/genericForm.tpl} +{/if} diff --git a/plugins/Installation/templates/structure.tpl b/plugins/Installation/templates/structure.tpl index d4e4309970..55c19990d2 100644 --- a/plugins/Installation/templates/structure.tpl +++ b/plugins/Installation/templates/structure.tpl @@ -1,226 +1,226 @@ -
-<html>
-<head>
-<title>Piwik » {'Installation_Installation'|translate}</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-</head>
-<body>
-
-{literal}
-<script type="text/javascript" src="libs/jquery/jquery.js"></script>
-<script>
-$(document).ready( function(){
- $('#toFade').fadeOut(4000, function(){ $(this).css('display', 'hidden'); } );
- $('input:first').focus();
- });
-</script>
-{/literal}
-
-{literal}
-<style>
-div.both {
- clear: both;
-}
-
-body {
- background-color: #F9F9F9;
- text-align: center;
- font-family:Georgia,"Times New Roman",Times,serif;
- font-size:19px;
-}
-
-#title{
- font-size:50px;
- color:#284F92;
-}
-
-#subtitle{
- font-size:30px;
- color:#C7D8D2;
-}
-
-#logo {
- padding:30;
-}
-
-h1 {
- font-size:20px;
- color:#666666;
- border-bottom:1px solid #DADADA;
- padding:0 0 7px;
-}
-
-h3 {
- margin-top:10px;
- font-size:17px;
- color:#3F5163;
-}
-
-.error {
- color:red;
- font-size:100%;
- font-weight:bold;
- border: 1px solid red;
- width: 550px;
- padding:20;
-}
-.error img {
- border:0;
- float:right;
- margin:10;
-}
-.success {
- color:#26981C;
- font-size:130%;
- font-weight:bold;
- padding:10;
-}
-.warning {
- color:#ff5502;
- font-size:130%;
- font-weight:bold;
- padding:10;
- border: 1px solid #ff5502;
-}
-
-.success img, .warning img {
- border:0;
- vertical-align:bottom;
-}
-
-#detailInstall {
- width:70%;
- float: right;
-}
-
-/* Cadre general */
-#main {
- margin: 5px;
- margin-top:30px;
- text-align: left;
-}
-
-#content {
- font-size: 90%;
- line-height: 1.4em;
- width: 860px;
- border: 1px solid #3B62AF;
- text-align: $rightouleft;
- margin: auto;
- background: #FFFFFF;
- padding: 0.2em 2em 2em 2em;
-
- -moz-border-radius: 8px;
- -khtml-border-radius: 8px;
- -webkit-border-radius: 8px;
-}
-/* form errors */
-#adminErrors {
- color:#FF6E46;
- font-size:120%;
-}
-/* listing all the steps */
-#generalInstall {
- width: 30%;
- float: left;
- font-size:90%;
-}
-
-#generalInstall UL {
- list-style-type: decimal;
-}
-LI.futureStep {
- color: #d3d3d3;
-}
-LI.actualStep {
- font-weight: bold;
-}
-LI.pastStep {
- color: #008000;
-}
-
-P.nextStep A {
- font-weight: bold;
- padding: 0.5em;
- color: #ae0000;
- text-decoration: underline;
- float:right;
- font-size:35px;
-}
-
-#installPercent {
- width: 100%;
- height: 1.5em;
- margin: 0;
- padding: 0;
- background-color: #eee;
- border: 1px solid #ddd;
-}
-#installPercent P {
- height: 1.5em;
- background-color: #8aaecc;
- margin: 0;
- padding: 0;
-}
-
-td {
- border-color:#FFFFFF rgb(198, 205, 216) rgb(198, 205, 216) rgb(198, 205, 216) ;
- border-style:solid;
- border-width:1px;
- color:#203276;
- padding:0.5em 0.5em 0.5em 0.8em;
-}
-
-.submit {
- text-align:center;
-}
-.submit input{
- margin-top:15px;
- background:transparent url(./themes/default/images/background-submit.png) repeat scroll 0%;
- font-size:1.4em;
- border-color:#CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204);
- border-style:double;
- border-width:3px;
- color:#333333;
- padding:0.15em;
-}
-
-input {
- font-size:1.1em;
- border-color:#CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204);
- border-width:1px;
- color:#3A2B16;
- padding:0.15em;
-}
-</style>
-{/literal}
-<div id="main">
- <div id="content">
- <div id="logo">
- <span id="title">Piwik</span> <span id="subtitle"># {'General_OpenSourceWebAnalytics'|translate}</span>
- </div>
- <div class="both"></div>
-
- <div id="generalInstall">
- {include file="Installation/templates/allSteps.tpl"}
- </div>
-
- <div id="detailInstall">
- {include file="$subTemplateToLoad"}
- {if $showNextStep}
- <p class="nextStep">
- <a href="{url action=$nextModuleName}">{'General_Next'|translate} »</a>
- </p>
- {/if}
- </div>
-
- <div class="both"></div>
-
- <h3>{'Installation_InstallationStatus'|translate}</h3>
-
- <div id="installPercent">
- <p style="width: {$percentDone}%;"></p>
- </div>
-
- {'Installation_PercentDone'|translate:$percentDone}
-</div>
+ +<html> +<head> +<title>Piwik » {'Installation_Installation'|translate}</title> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +</head> +<body> + +{literal} +<script type="text/javascript" src="libs/jquery/jquery.js"></script> +<script> +$(document).ready( function(){ + $('#toFade').fadeOut(4000, function(){ $(this).css('display', 'hidden'); } ); + $('input:first').focus(); + }); +</script> +{/literal} + +{literal} +<style> +div.both { + clear: both; +} + +body { + background-color: #F9F9F9; + text-align: center; + font-family:Georgia,"Times New Roman",Times,serif; + font-size:19px; +} + +#title{ + font-size:50px; + color:#284F92; +} + +#subtitle{ + font-size:30px; + color:#C7D8D2; +} + +#logo { + padding:30; +} + +h1 { + font-size:20px; + color:#666666; + border-bottom:1px solid #DADADA; + padding:0 0 7px; +} + +h3 { + margin-top:10px; + font-size:17px; + color:#3F5163; +} + +.error { + color:red; + font-size:100%; + font-weight:bold; + border: 1px solid red; + width: 550px; + padding:20; +} +.error img { + border:0; + float:right; + margin:10; +} +.success { + color:#26981C; + font-size:130%; + font-weight:bold; + padding:10; +} +.warning { + color:#ff5502; + font-size:130%; + font-weight:bold; + padding:10; + border: 1px solid #ff5502; +} + +.success img, .warning img { + border:0; + vertical-align:bottom; +} + +#detailInstall { + width:70%; + float: right; +} + +/* Cadre general */ +#main { + margin: 5px; + margin-top:30px; + text-align: left; +} + +#content { + font-size: 90%; + line-height: 1.4em; + width: 860px; + border: 1px solid #3B62AF; + text-align: $rightouleft; + margin: auto; + background: #FFFFFF; + padding: 0.2em 2em 2em 2em; + + -moz-border-radius: 8px; + -khtml-border-radius: 8px; + -webkit-border-radius: 8px; +} +/* form errors */ +#adminErrors { + color:#FF6E46; + font-size:120%; +} +/* listing all the steps */ +#generalInstall { + width: 30%; + float: left; + font-size:90%; +} + +#generalInstall UL { + list-style-type: decimal; +} +LI.futureStep { + color: #d3d3d3; +} +LI.actualStep { + font-weight: bold; +} +LI.pastStep { + color: #008000; +} + +P.nextStep A { + font-weight: bold; + padding: 0.5em; + color: #ae0000; + text-decoration: underline; + float:right; + font-size:35px; +} + +#installPercent { + width: 100%; + height: 1.5em; + margin: 0; + padding: 0; + background-color: #eee; + border: 1px solid #ddd; +} +#installPercent P { + height: 1.5em; + background-color: #8aaecc; + margin: 0; + padding: 0; +} + +td { + border-color:#FFFFFF rgb(198, 205, 216) rgb(198, 205, 216) rgb(198, 205, 216) ; + border-style:solid; + border-width:1px; + color:#203276; + padding:0.5em 0.5em 0.5em 0.8em; +} + +.submit { + text-align:center; +} +.submit input{ + margin-top:15px; + background:transparent url(./themes/default/images/background-submit.png) repeat scroll 0%; + font-size:1.4em; + border-color:#CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204); + border-style:double; + border-width:3px; + color:#333333; + padding:0.15em; +} + +input { + font-size:1.1em; + border-color:#CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204); + border-width:1px; + color:#3A2B16; + padding:0.15em; +} +</style> +{/literal} +<div id="main"> + <div id="content"> + <div id="logo"> + <span id="title">Piwik</span> <span id="subtitle"># {'General_OpenSourceWebAnalytics'|translate}</span> + </div> + <div class="both"></div> + + <div id="generalInstall"> + {include file="Installation/templates/allSteps.tpl"} + </div> + + <div id="detailInstall"> + {include file="$subTemplateToLoad"} + {if $showNextStep} + <p class="nextStep"> + <a href="{url action=$nextModuleName}">{'General_Next'|translate} »</a> + </p> + {/if} + </div> + + <div class="both"></div> + + <h3>{'Installation_InstallationStatus'|translate}</h3> + + <div id="installPercent"> + <p style="width: {$percentDone}%;"></p> + </div> + + {'Installation_PercentDone'|translate:$percentDone} +</div> diff --git a/plugins/Installation/templates/systemCheck.tpl b/plugins/Installation/templates/systemCheck.tpl index 72d80e4dd2..84cd688429 100644 --- a/plugins/Installation/templates/systemCheck.tpl +++ b/plugins/Installation/templates/systemCheck.tpl @@ -1,114 +1,114 @@ -{assign var=ok value="<img src='themes/default/images/ok.png' />"}
-{assign var=error value="<img src='themes/default/images/error.png' />"}
-{assign var=warning value="<img src='themes/default/images/warning.png' />"}
-
-<h1>{'Installation_SystemCheck'|translate}</h1>
-
-
-<table class="infosServer">
- <tr>
- <td class="label">{'Installation_SystemCheckPhp'|translate} > {$infos.phpVersion_minimum}</td>
- <td>{if $infos.phpVersion_ok}{$ok}{else}{$error}{/if}</td>
- </tr><tr>
- <td class="label">{'Installation_SystemCheckPdo'|translate}</td>
- <td>{if $infos.pdo_ok}{$ok}
- {else}{$error}{/if}
- </td>
- </tr>
- <tr>
- <td class="label">{'Installation_SystemCheckPdoMysql'|translate}</td>
- <td>{if $infos.pdo_mysql_ok}{$ok}
- {else}{$error}
- {/if}
-
- {if !$infos.pdo_mysql_ok || !$infos.pdo_ok}
- <p class="error" style="width:80%">{'Installation_SystemCheckPdoError'|translate}
- <small>
- <br /><br />
- {'Installation_SystemCheckPdoHelp'|translate:"<br/><code>extension=php_pdo.dll</code><br /><code>extension=php_pdo_mysql.dll</code><br />":"<code>--with-pdo-mysql </code>":"<br/><code>extension=pdo.so</code><br /><code>extension=pdo_mysql.so</code><br />"}
- </small>
- </p>
- {/if}
-
- </td>
- </tr>
- <tr>
- <td valign="top">
- {'Installation_SystemCheckWriteDirs'|translate}
- </td>
- <td>
- {foreach from=$infos.directories key=dir item=bool}
- {if $bool}{$ok}{else}
- <span style="color:red">{$error}</span>{/if}
- {$dir}
- <br />
- {/foreach}
- </td>
- </tr>
-</table>
-
-{if $problemWithSomeDirectories}
- <br />
- <div class="error">
- {'Installation_SystemCheckWriteDirsHelp'|translate}:
- {foreach from=$infos.directories key=dir item=bool}
- <ul>{if !$bool}
- <li><pre>chmod a+w {$dir}</pre></li>
- {/if}
- </ul>
- {/foreach}
- </div>
- <br />
-{/if}
-<h1>Optional</h1>
-<table class="infos">
- <tr>
- <td class="label">{'Installation_SystemCheckMemoryLimit'|translate}</td>
- <td>
- {$infos.memoryCurrent}
- {if $infos.memory_ok}{$ok}{else}{$warning}
- <br /><i>{'Installation_SystemCheckMemoryLimitHelp'|translate}</i>{/if}
- </td>
- </tr>
- <tr>
- <td class="label">{'Installation_SystemCheckGD'|translate}</td>
- <td>
- {if $infos.gd_ok}{$ok}{else}{$warning} <br /><i>{'Installation_SystemCheckGDHelp'|translate}</i>{/if}
- </td>
- </tr>
- <tr>
- <td class="label">{'Installation_SystemCheckTimeLimit'|translate}</td>
- <td>{if $infos.setTimeLimit_ok}{$ok}{else}{$warning}
- <br /><i>{'Installation_SystemCheckTimeLimitHelp'|translate}</i>{/if}</td>
- </tr>
- <tr>
- <td class="label">{'Installation_SystemCheckMail'|translate}</td>
- <td>{if $infos.mail_ok}{$ok}{else}{$warning}{/if}</td>
- </tr>
-</table>
-
-
-{if !$showNextStep}
-{literal}
-<style>
-#legend {
- border:1px solid #A5A5A5;
- padding:5px;
- color:#727272;
- margin-top:30px;
-}
-</style>
-{/literal}
-<div id="legend"><small>
-<b>Legend</b>
-<br />
-{$ok} {'General_Ok'|translate}<br />
-{$error} {'General_Error'|translate}: {'Installation_SystemCheckError'|translate} <br />
-{$warning} {'General_Warning'|translate}: {'Installation_SystemCheckWarning'|translate} <br />
-</small></div>
-
-
-<p class="nextStep">
- <a href="{url}">{'General_Refresh'|translate} »</a>
-</p>
-{/if}
+{assign var=ok value="<img src='themes/default/images/ok.png' />"} +{assign var=error value="<img src='themes/default/images/error.png' />"} +{assign var=warning value="<img src='themes/default/images/warning.png' />"} + +<h1>{'Installation_SystemCheck'|translate}</h1> + + +<table class="infosServer"> + <tr> + <td class="label">{'Installation_SystemCheckPhp'|translate} > {$infos.phpVersion_minimum}</td> + <td>{if $infos.phpVersion_ok}{$ok}{else}{$error}{/if}</td> + </tr><tr> + <td class="label">{'Installation_SystemCheckPdo'|translate}</td> + <td>{if $infos.pdo_ok}{$ok} + {else}{$error}{/if} + </td> + </tr> + <tr> + <td class="label">{'Installation_SystemCheckPdoMysql'|translate}</td> + <td>{if $infos.pdo_mysql_ok}{$ok} + {else}{$error} + {/if} + + {if !$infos.pdo_mysql_ok || !$infos.pdo_ok} + <p class="error" style="width:80%">{'Installation_SystemCheckPdoError'|translate} + <small> + <br /><br /> + {'Installation_SystemCheckPdoHelp'|translate:"<br/><code>extension=php_pdo.dll</code><br /><code>extension=php_pdo_mysql.dll</code><br />":"<code>--with-pdo-mysql </code>":"<br/><code>extension=pdo.so</code><br /><code>extension=pdo_mysql.so</code><br />"} + </small> + </p> + {/if} + + </td> + </tr> + <tr> + <td valign="top"> + {'Installation_SystemCheckWriteDirs'|translate} + </td> + <td> + {foreach from=$infos.directories key=dir item=bool} + {if $bool}{$ok}{else} + <span style="color:red">{$error}</span>{/if} + {$dir} + <br /> + {/foreach} + </td> + </tr> +</table> + +{if $problemWithSomeDirectories} + <br /> + <div class="error"> + {'Installation_SystemCheckWriteDirsHelp'|translate}: + {foreach from=$infos.directories key=dir item=bool} + <ul>{if !$bool} + <li><pre>chmod a+w {$dir}</pre></li> + {/if} + </ul> + {/foreach} + </div> + <br /> +{/if} +<h1>Optional</h1> +<table class="infos"> + <tr> + <td class="label">{'Installation_SystemCheckMemoryLimit'|translate}</td> + <td> + {$infos.memoryCurrent} + {if $infos.memory_ok}{$ok}{else}{$warning} + <br /><i>{'Installation_SystemCheckMemoryLimitHelp'|translate}</i>{/if} + </td> + </tr> + <tr> + <td class="label">{'Installation_SystemCheckGD'|translate}</td> + <td> + {if $infos.gd_ok}{$ok}{else}{$warning} <br /><i>{'Installation_SystemCheckGDHelp'|translate}</i>{/if} + </td> + </tr> + <tr> + <td class="label">{'Installation_SystemCheckTimeLimit'|translate}</td> + <td>{if $infos.setTimeLimit_ok}{$ok}{else}{$warning} + <br /><i>{'Installation_SystemCheckTimeLimitHelp'|translate}</i>{/if}</td> + </tr> + <tr> + <td class="label">{'Installation_SystemCheckMail'|translate}</td> + <td>{if $infos.mail_ok}{$ok}{else}{$warning}{/if}</td> + </tr> +</table> + + +{if !$showNextStep} +{literal} +<style> +#legend { + border:1px solid #A5A5A5; + padding:5px; + color:#727272; + margin-top:30px; +} +</style> +{/literal} +<div id="legend"><small> +<b>Legend</b> +<br /> +{$ok} {'General_Ok'|translate}<br /> +{$error} {'General_Error'|translate}: {'Installation_SystemCheckError'|translate} <br /> +{$warning} {'General_Warning'|translate}: {'Installation_SystemCheckWarning'|translate} <br /> +</small></div> + + +<p class="nextStep"> + <a href="{url}">{'General_Refresh'|translate} »</a> +</p> +{/if} diff --git a/plugins/Installation/templates/tablesCreation.tpl b/plugins/Installation/templates/tablesCreation.tpl index 32cf736b84..c54571ed76 100644 --- a/plugins/Installation/templates/tablesCreation.tpl +++ b/plugins/Installation/templates/tablesCreation.tpl @@ -1,69 +1,69 @@ -<h1>{'Installation_Tables'|translate}</h1>
-{if isset($someTablesInstalled)}
- <div class="warning">{'Installation_TablesWarning'|translate}
- <img src="themes/default/images/warning_medium.png">
- </div>
- <div id="toggle" style="display:none;color:#4F2410"><small><i>{'Installation_TablesFound'|translate}:
- <br />{$tablesInstalled} </i></small></div>
-
- <p>{'Installation_TablesWarningHelp'|translate}</p>
-
- <p class="nextStep"><a href="{url action=$nextModuleName}">{'Installation_TablesReuse'|translate} »</a></p>
- <p class="nextStep" id="eraseAllTables"><a href="{url deleteTables=1}">{'Installation_TablesDelete'|translate} »</a></p>
-{/if}
-
-{if isset($existingTablesDeleted)}
- <div class="success"> {'Installation_TablesDeletedSuccess'|translate}
- <img src="themes/default/images/success_medium.png"></div>
-{/if}
-
-
-{if isset($databaseCreated)}
- <div class="success"> {'Installation_DatabaseCreatedSuccess'|translate:"'$databaseName'"}
- <img src="themes/default/images/success_medium.png"></div>
-{/if}
-
-{if isset($tablesCreated)}
- <div class="success"> {'Installation_TablesCreatedSuccess'|translate}
- <img src="themes/default/images/success_medium.png"></div>
-{/if}
-
-
-{literal}
-<script>
-$(document).ready( function(){
- {/literal}
- var strConfirmEraseTables = "{'Installation_TablesDeleteConfirm'|translate} ";
- {literal}
-
- // toggle the display of the tables detected during the installation when clicking
- // on the span "linkToggle"
- $("#linkToggle")
- .css("border-bottom","thin dotted #ff5502")
-
- .hover( function() {
- $(this).css({ cursor: "pointer"});
- },
- function() {
- $(this).css({ cursor: "auto"});
- })
- .css("border-bottom","thin dotted #ff5502")
- .click(function(){
- $("#toggle").toggle();} );
-
- $("#eraseAllTables")
- .click( function(){
- if(confirm( strConfirmEraseTables ) )
- {
- window.location.href = $(this).attr('href');
- }
- else
- {
- return false;
- }
- });
-
- ;
-});
-</script>
-{/literal}
+<h1>{'Installation_Tables'|translate}</h1> +{if isset($someTablesInstalled)} + <div class="warning">{'Installation_TablesWarning'|translate} + <img src="themes/default/images/warning_medium.png"> + </div> + <div id="toggle" style="display:none;color:#4F2410"><small><i>{'Installation_TablesFound'|translate}: + <br />{$tablesInstalled} </i></small></div> + + <p>{'Installation_TablesWarningHelp'|translate}</p> + + <p class="nextStep"><a href="{url action=$nextModuleName}">{'Installation_TablesReuse'|translate} »</a></p> + <p class="nextStep" id="eraseAllTables"><a href="{url deleteTables=1}">{'Installation_TablesDelete'|translate} »</a></p> +{/if} + +{if isset($existingTablesDeleted)} + <div class="success"> {'Installation_TablesDeletedSuccess'|translate} + <img src="themes/default/images/success_medium.png"></div> +{/if} + + +{if isset($databaseCreated)} + <div class="success"> {'Installation_DatabaseCreatedSuccess'|translate:"'$databaseName'"} + <img src="themes/default/images/success_medium.png"></div> +{/if} + +{if isset($tablesCreated)} + <div class="success"> {'Installation_TablesCreatedSuccess'|translate} + <img src="themes/default/images/success_medium.png"></div> +{/if} + + +{literal} +<script> +$(document).ready( function(){ + {/literal} + var strConfirmEraseTables = "{'Installation_TablesDeleteConfirm'|translate} "; + {literal} + + // toggle the display of the tables detected during the installation when clicking + // on the span "linkToggle" + $("#linkToggle") + .css("border-bottom","thin dotted #ff5502") + + .hover( function() { + $(this).css({ cursor: "pointer"}); + }, + function() { + $(this).css({ cursor: "auto"}); + }) + .css("border-bottom","thin dotted #ff5502") + .click(function(){ + $("#toggle").toggle();} ); + + $("#eraseAllTables") + .click( function(){ + if(confirm( strConfirmEraseTables ) ) + { + window.location.href = $(this).attr('href'); + } + else + { + return false; + } + }); + + ; +}); +</script> +{/literal} diff --git a/plugins/Installation/templates/welcome.tpl b/plugins/Installation/templates/welcome.tpl index 7abe79222f..c2985c3c36 100644 --- a/plugins/Installation/templates/welcome.tpl +++ b/plugins/Installation/templates/welcome.tpl @@ -1,4 +1,4 @@ -<h1>{'Installation_Welcome'|translate}</h1>
-
-{'Installation_WelcomeHelp'|translate:$totalNumberOfSteps}
-
+<h1>{'Installation_Welcome'|translate}</h1> + +{'Installation_WelcomeHelp'|translate:$totalNumberOfSteps} + diff --git a/plugins/Login/templates/header.tpl b/plugins/Login/templates/header.tpl index 4d81aef3ea..fc472a31d6 100644 --- a/plugins/Login/templates/header.tpl +++ b/plugins/Login/templates/header.tpl @@ -1,28 +1,28 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
-<head>
- <title>Piwik › Login</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-
- {literal}
- <script type="text/javascript">
- function focusit() {
- var formLogin = document.getElementById('form_login');
- if(formLogin)
- {
- formLogin.focus();
- }
- }
- window.onload = focusit;
- </script>
- {/literal}
- <link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico">
- <link rel="stylesheet" href="plugins/Login/templates/login.css" type="text/css" media="screen" />
-</head>
-
-<body class="login">
-<!-- shamelessly taken from wordpress 2.5 - thank you guys!!! -->
-
-<div id="logo">
- <a href="http://piwik.org" title="{$linkTitle}"><span class="h1"><span style="color: rgb(245, 223, 114);">P</span><span style="color: rgb(241, 175, 108);">i</span><span style="color: rgb(241, 117, 117);">w</span><span style="color: rgb(155, 106, 58);">i</span><span style="color: rgb(107, 50, 11);">k</span> <span class="description"># {'General_OpenSourceWebAnalytics'|translate}</span></span></a>
-</div>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> +<head> + <title>Piwik › Login</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + + {literal} + <script type="text/javascript"> + function focusit() { + var formLogin = document.getElementById('form_login'); + if(formLogin) + { + formLogin.focus(); + } + } + window.onload = focusit; + </script> + {/literal} + <link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico"> + <link rel="stylesheet" href="plugins/Login/templates/login.css" type="text/css" media="screen" /> +</head> + +<body class="login"> +<!-- shamelessly taken from wordpress 2.5 - thank you guys!!! --> + +<div id="logo"> + <a href="http://piwik.org" title="{$linkTitle}"><span class="h1"><span style="color: rgb(245, 223, 114);">P</span><span style="color: rgb(241, 175, 108);">i</span><span style="color: rgb(241, 117, 117);">w</span><span style="color: rgb(155, 106, 58);">i</span><span style="color: rgb(107, 50, 11);">k</span> <span class="description"># {'General_OpenSourceWebAnalytics'|translate}</span></span></a> +</div> diff --git a/plugins/Login/templates/login.css b/plugins/Login/templates/login.css index d6b3b0f93c..e49561fa2d 100644 --- a/plugins/Login/templates/login.css +++ b/plugins/Login/templates/login.css @@ -150,4 +150,4 @@ a { font-weight: normal; color: #879dbd; font-size: 19pt; -}
\ No newline at end of file +} diff --git a/plugins/Login/templates/login.tpl b/plugins/Login/templates/login.tpl index 0484425181..3ec3f76e2c 100644 --- a/plugins/Login/templates/login.tpl +++ b/plugins/Login/templates/login.tpl @@ -1,47 +1,47 @@ -{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if $form_data.errors}
-<div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</div>
-{/if}
-
-{if $AccessErrorString}
-<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
-{/if}
-
-<form {$form_data.attributes}>
- <p>
- <label>{'Login_Login'|translate}:<br />
- <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label>
- </p>
-
- <p>
- <label>{'Login_Password'|translate}:<br />
- <input type="password" name="form_password" id="form_password" class="input" value="" size="20" tabindex="20" /></label>
- </p>
- {*
- <p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90" /> Remember Me</label></p>
- *}
- {$form_data.form_url.html}
- <p class="submit">
- <input type="submit" value="{'Login_LogIn'|translate}" tabindex="100" />
- </p>
-</form>
-
-
-<p id="nav">
-<a href="?module=Login&action=lostPassword&form_url={$urlToRedirect|escape:url}" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
-
-
-
+{include file="Login/templates/header.tpl"} + +<div id="login"> + +{if $form_data.errors} +<div id="login_error"> + {foreach from=$form_data.errors item=data} + <strong>{'General_Error'|translate}</strong>: {$data}<br /> + {/foreach} +</div> +{/if} + +{if $AccessErrorString} +<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div> +{/if} + +<form {$form_data.attributes}> + <p> + <label>{'Login_Login'|translate}:<br /> + <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label> + </p> + + <p> + <label>{'Login_Password'|translate}:<br /> + <input type="password" name="form_password" id="form_password" class="input" value="" size="20" tabindex="20" /></label> + </p> + {* + <p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90" /> Remember Me</label></p> + *} + {$form_data.form_url.html} + <p class="submit"> + <input type="submit" value="{'Login_LogIn'|translate}" tabindex="100" /> + </p> +</form> + + +<p id="nav"> +<a href="?module=Login&action=lostPassword&form_url={$urlToRedirect|escape:url}" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a> +</p> + +</div> + +</body> +</html> + + + diff --git a/plugins/Login/templates/lostPassword.tpl b/plugins/Login/templates/lostPassword.tpl index d114918c89..3da5ebdec2 100644 --- a/plugins/Login/templates/lostPassword.tpl +++ b/plugins/Login/templates/lostPassword.tpl @@ -1,44 +1,44 @@ -{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if $form_data.errors}
-<div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</div>
-{/if}
-
-{if $AccessErrorString}
-<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
-{/if}
-
-<p class="message">
-{'Login_PasswordReminder'|translate}
-</p>
-
-<form {$form_data.attributes}>
-
- <p>
- <label>{'Login_LoginOrEmail'|translate}:<br />
- <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label>
- </p>
- {$form_data.form_url.html}
- <p class="submit">
- <input type="submit" value="{'Login_RemindPassword'|translate}" tabindex="100" />
- </p>
-</form>
-
-
-<p id="nav">
-<a href="?module=Login&form_url={$urlToRedirect}" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
-
-
-
+{include file="Login/templates/header.tpl"} + +<div id="login"> + +{if $form_data.errors} +<div id="login_error"> + {foreach from=$form_data.errors item=data} + <strong>{'General_Error'|translate}</strong>: {$data}<br /> + {/foreach} +</div> +{/if} + +{if $AccessErrorString} +<div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div> +{/if} + +<p class="message"> +{'Login_PasswordReminder'|translate} +</p> + +<form {$form_data.attributes}> + + <p> + <label>{'Login_LoginOrEmail'|translate}:<br /> + <input type="text" name="form_login" id="form_login" class="input" value="" size="20" tabindex="10" /></label> + </p> + {$form_data.form_url.html} + <p class="submit"> + <input type="submit" value="{'Login_RemindPassword'|translate}" tabindex="100" /> + </p> +</form> + + +<p id="nav"> +<a href="?module=Login&form_url={$urlToRedirect}" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a> +</p> + +</div> + +</body> +</html> + + + diff --git a/plugins/Login/templates/passwordsent.tpl b/plugins/Login/templates/passwordsent.tpl index 1355c2781a..b45f928f0d 100644 --- a/plugins/Login/templates/passwordsent.tpl +++ b/plugins/Login/templates/passwordsent.tpl @@ -1,25 +1,25 @@ -{include file="Login/templates/header.tpl"}
-
-<div id="login">
-
-{if isset($ErrorString)}
- <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$ErrorString}<br />
- {'Login_ContactAdmin'|translate}
- </div>
-{else}
- <p class="message">
- {'Login_PasswordSent'|translate}
- </p>
-{/if}
-
-<p id="nav">
-<a href="?module=Login&form_url={$urlToRedirect}" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-</p>
-
-</div>
-
-</body>
-</html>
-
-
-
+{include file="Login/templates/header.tpl"} + +<div id="login"> + +{if isset($ErrorString)} + <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$ErrorString}<br /> + {'Login_ContactAdmin'|translate} + </div> +{else} + <p class="message"> + {'Login_PasswordSent'|translate} + </p> +{/if} + +<p id="nav"> +<a href="?module=Login&form_url={$urlToRedirect}" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a> +</p> + +</div> + +</body> +</html> + + + diff --git a/plugins/Referers/templates/index.tpl b/plugins/Referers/templates/index.tpl index df1995c81e..c5e25f8698 100644 --- a/plugins/Referers/templates/index.tpl +++ b/plugins/Referers/templates/index.tpl @@ -1,39 +1,39 @@ -<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script>
-
- <a name="evolutionGraph" graphId="{$nameGraphEvolutionReferers}"></a>
- <h2>{'Referers_Evolution'|translate}</h2>
- {$graphEvolutionReferers}
-
- <h2>{'Referers_Type'|translate}</h2>
- <table>
- <tr><td>
- <p>{sparkline src=$urlSparklineDirectEntry}<span>
- {'Referers_TypeDirectEntries'|translate:"<strong>$visitorsFromDirectEntry</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineSearchEngines}<span>
- {'Referers_TypeSearchEngines'|translate:"<strong>$visitorsFromSearchEngines</strong>"}</span></p>
- </td><td>
- <p>{sparkline src=$urlSparklineWebsites}<span>
- {'Referers_TypeWebsites'|translate:"<strong>$visitorsFromWebsites</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineCampaigns}<span>
- {'Referers_TypeCampaigns'|translate:"<strong>$visitorsFromCampaigns</strong>"}</span></p>
- </td></tr>
- </table>
-
- <h2>{'Referers_Other'|translate}</h2>
- <table>
- <tr><td>
- <p>{sparkline src=$urlSparklineDistinctSearchEngines}<span>
- {'Referers_OtherDistinctSearchEngines'|translate:"<strong>$numberDistinctSearchEngines</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineDistinctKeywords}<span>
- {'Referers_OtherDistinctKeywords'|translate:"<strong>$numberDistinctKeywords</strong>"}</span></p>
- </td><td>
- <p>{sparkline src=$urlSparklineDistinctWebsites}<span>
- {'Referers_OtherDistinctWebsites'|translate:"<strong>$numberDistinctWebsites</strong>":"<strong>$numberDistinctWebsitesUrls</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineDistinctCampaigns}<span>
- {'Referers_OtherDistinctCampaigns'|translate:"<strong>$numberDistinctCampaigns</strong>"}</span></p>
- </td></tr>
- </table>
-
- <p>{'Referers_TagCloud'|translate}</p>
- {$dataTableRefererType}
-
+<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script> + + <a name="evolutionGraph" graphId="{$nameGraphEvolutionReferers}"></a> + <h2>{'Referers_Evolution'|translate}</h2> + {$graphEvolutionReferers} + + <h2>{'Referers_Type'|translate}</h2> + <table> + <tr><td> + <p>{sparkline src=$urlSparklineDirectEntry}<span> + {'Referers_TypeDirectEntries'|translate:"<strong>$visitorsFromDirectEntry</strong>"}</span></p> + <p>{sparkline src=$urlSparklineSearchEngines}<span> + {'Referers_TypeSearchEngines'|translate:"<strong>$visitorsFromSearchEngines</strong>"}</span></p> + </td><td> + <p>{sparkline src=$urlSparklineWebsites}<span> + {'Referers_TypeWebsites'|translate:"<strong>$visitorsFromWebsites</strong>"}</span></p> + <p>{sparkline src=$urlSparklineCampaigns}<span> + {'Referers_TypeCampaigns'|translate:"<strong>$visitorsFromCampaigns</strong>"}</span></p> + </td></tr> + </table> + + <h2>{'Referers_Other'|translate}</h2> + <table> + <tr><td> + <p>{sparkline src=$urlSparklineDistinctSearchEngines}<span> + {'Referers_OtherDistinctSearchEngines'|translate:"<strong>$numberDistinctSearchEngines</strong>"}</span></p> + <p>{sparkline src=$urlSparklineDistinctKeywords}<span> + {'Referers_OtherDistinctKeywords'|translate:"<strong>$numberDistinctKeywords</strong>"}</span></p> + </td><td> + <p>{sparkline src=$urlSparklineDistinctWebsites}<span> + {'Referers_OtherDistinctWebsites'|translate:"<strong>$numberDistinctWebsites</strong>":"<strong>$numberDistinctWebsitesUrls</strong>"}</span></p> + <p>{sparkline src=$urlSparklineDistinctCampaigns}<span> + {'Referers_OtherDistinctCampaigns'|translate:"<strong>$numberDistinctCampaigns</strong>"}</span></p> + </td></tr> + </table> + + <p>{'Referers_TagCloud'|translate}</p> + {$dataTableRefererType} + diff --git a/plugins/Referers/templates/searchEngines_Keywords.tpl b/plugins/Referers/templates/searchEngines_Keywords.tpl index a664aefb50..c60a841e23 100644 --- a/plugins/Referers/templates/searchEngines_Keywords.tpl +++ b/plugins/Referers/templates/searchEngines_Keywords.tpl @@ -1,9 +1,9 @@ -<div id='leftcolumn'>
- <h2>{'Referers_SearchEngines'|translate}</h2>
- {$searchEngines}
-</div>
-
-<div id='rightcolumn'>
- <h2>{'Referers_Keywords'|translate}</h2>
- {$keywords}
-</div>
+<div id='leftcolumn'> + <h2>{'Referers_SearchEngines'|translate}</h2> + {$searchEngines} +</div> + +<div id='rightcolumn'> + <h2>{'Referers_Keywords'|translate}</h2> + {$keywords} +</div> diff --git a/plugins/SitesManager/Controller.php b/plugins/SitesManager/Controller.php index 7858d9a829..0ac9cbfe3d 100644 --- a/plugins/SitesManager/Controller.php +++ b/plugins/SitesManager/Controller.php @@ -36,4 +36,4 @@ class Piwik_SitesManager_Controller extends Piwik_Controller $view->jsTag = $jsTag; echo $view->render(); } -}
\ No newline at end of file +} diff --git a/plugins/SitesManager/templates/DisplayJavascriptCode.tpl b/plugins/SitesManager/templates/DisplayJavascriptCode.tpl index 784557308c..e601c8dc58 100644 --- a/plugins/SitesManager/templates/DisplayJavascriptCode.tpl +++ b/plugins/SitesManager/templates/DisplayJavascriptCode.tpl @@ -1,27 +1,27 @@ -{loadJavascriptTranslations plugins='SitesManager'}
-{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{include file="CoreAdminHome/templates/menu.tpl"}
-
-{literal}
-<style>
-code {
- background-color:#F0F7FF;
- border-color:#00008B;
- border-style:dashed dashed dashed solid;
- border-width:1px 1px 1px 5px;
- direction:ltr;
- display:block;
- font-size:80%;
- margin:2px 2px 20px;
- padding:4px;
- text-align:left;
- font-family: "Courier New" Courier monospace;
-}
-</style>
-{/literal}
-
-<p>{'SitesManager_JsCodeHelp'|translate}:</p>
-
-<code>{$jsTag}</code>
+{loadJavascriptTranslations plugins='SitesManager'} +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{include file="CoreAdminHome/templates/menu.tpl"} + +{literal} +<style> +code { + background-color:#F0F7FF; + border-color:#00008B; + border-style:dashed dashed dashed solid; + border-width:1px 1px 1px 5px; + direction:ltr; + display:block; + font-size:80%; + margin:2px 2px 20px; + padding:4px; + text-align:left; + font-family: "Courier New" Courier monospace; +} +</style> +{/literal} + +<p>{'SitesManager_JsCodeHelp'|translate}:</p> + +<code>{$jsTag}</code> diff --git a/plugins/SitesManager/templates/SitesManager.tpl b/plugins/SitesManager/templates/SitesManager.tpl index e9cec2405a..d90a27c29f 100644 --- a/plugins/SitesManager/templates/SitesManager.tpl +++ b/plugins/SitesManager/templates/SitesManager.tpl @@ -1,64 +1,64 @@ -{loadJavascriptTranslations plugins='SitesManager'}
-{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{include file="CoreAdminHome/templates/menu.tpl"}
-
-<script type="text/javascript" src="plugins/SitesManager/templates/SitesManager.js"></script>
-{literal}
-<style>
-.addRowSite:hover, .editableSite:hover, .addsite:hover, .cancel:hover, .deleteSite:hover, .editSite:hover, .updateSite:hover{
- cursor: pointer;
-}
-.addRowSite a {
- text-decoration: none;
-}
-.addRowSite {
- padding:1em;
- font-color:#3A477B;
- padding:1em;
- font-weight:bold;
-}
-#editSites {
- valign: top;
-}
-</style>
-{/literal}
-<h2>{'SitesManager_WebsitesManagement'|translate}</h2>
-<p>{'SitesManager_MainDescription'|translate}</p>
-
-<div id="ajaxError" style="display:none"></div>
-<div id="ajaxLoading" style="display:none"><div id="loadingPiwik"><img src="themes/default/images/loading-blue.gif" alt="" /> {'General_LoadingData'|translate} </div></div>
-
-{if $adminSites|@count == 0}
- {'SitesManager_NoWebsites'|translate}
-{else}
- <table class="admin" id="editSites" border=1 cellpadding="10">
- <thead>
- <tr>
- <th>{'SitesManager_Id'|translate}</th>
- <th>{'SitesManager_Name'|translate}</th>
- <th>{'SitesManager_Urls'|translate}</th>
- <th> </th>
- <th> </th>
- <th> {'SitesManager_JsCode'|translate} </th>
- </tr>
- </thead>
- <tbody>
- {foreach from=$adminSites key=i item=site}
- <tr id="row{$i}">
- <td id="idSite">{$site.idsite}</td>
- <td id="siteName" class="editableSite">{$site.name}</td>
- <td id="urls" class="editableSite">{foreach from=$site.alias_urls item=url}{$url}<br />{/foreach}</td>
- <td><img src='plugins/UsersManager/images/edit.png' class="editSite" id="row{$i}" href='#' alt="" /></td>
- <td><img src='plugins/UsersManager/images/remove.png' class="deleteSite" id="row{$i}" value="{'General_Delete'|translate}" alt="" /></td>
- <td><a href='{url action=displayJavascriptCode idsite=$site.idsite}'>{'SitesManager_ShowJsCode'|translate}</a></td>
- </tr>
- {/foreach}
-
- </tbody>
- </table>
- <div class="addRowSite"><a href="#"><img src='plugins/UsersManager/images/add.png' alt="" /> {'SitesManager_AddSite'|translate}</a></div>
-{/if}
-
-{include file="CoreAdminHome/templates/footer.tpl"}
+{loadJavascriptTranslations plugins='SitesManager'} +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{include file="CoreAdminHome/templates/menu.tpl"} + +<script type="text/javascript" src="plugins/SitesManager/templates/SitesManager.js"></script> +{literal} +<style> +.addRowSite:hover, .editableSite:hover, .addsite:hover, .cancel:hover, .deleteSite:hover, .editSite:hover, .updateSite:hover{ + cursor: pointer; +} +.addRowSite a { + text-decoration: none; +} +.addRowSite { + padding:1em; + font-color:#3A477B; + padding:1em; + font-weight:bold; +} +#editSites { + valign: top; +} +</style> +{/literal} +<h2>{'SitesManager_WebsitesManagement'|translate}</h2> +<p>{'SitesManager_MainDescription'|translate}</p> + +<div id="ajaxError" style="display:none"></div> +<div id="ajaxLoading" style="display:none"><div id="loadingPiwik"><img src="themes/default/images/loading-blue.gif" alt="" /> {'General_LoadingData'|translate} </div></div> + +{if $adminSites|@count == 0} + {'SitesManager_NoWebsites'|translate} +{else} + <table class="admin" id="editSites" border=1 cellpadding="10"> + <thead> + <tr> + <th>{'SitesManager_Id'|translate}</th> + <th>{'SitesManager_Name'|translate}</th> + <th>{'SitesManager_Urls'|translate}</th> + <th> </th> + <th> </th> + <th> {'SitesManager_JsCode'|translate} </th> + </tr> + </thead> + <tbody> + {foreach from=$adminSites key=i item=site} + <tr id="row{$i}"> + <td id="idSite">{$site.idsite}</td> + <td id="siteName" class="editableSite">{$site.name}</td> + <td id="urls" class="editableSite">{foreach from=$site.alias_urls item=url}{$url}<br />{/foreach}</td> + <td><img src='plugins/UsersManager/images/edit.png' class="editSite" id="row{$i}" href='#' alt="" /></td> + <td><img src='plugins/UsersManager/images/remove.png' class="deleteSite" id="row{$i}" value="{'General_Delete'|translate}" alt="" /></td> + <td><a href='{url action=displayJavascriptCode idsite=$site.idsite}'>{'SitesManager_ShowJsCode'|translate}</a></td> + </tr> + {/foreach} + + </tbody> + </table> + <div class="addRowSite"><a href="#"><img src='plugins/UsersManager/images/add.png' alt="" /> {'SitesManager_AddSite'|translate}</a></div> +{/if} + +{include file="CoreAdminHome/templates/footer.tpl"} diff --git a/plugins/UserCountry/functions.php b/plugins/UserCountry/functions.php index e6bc371649..61c3be4f54 100644 --- a/plugins/UserCountry/functions.php +++ b/plugins/UserCountry/functions.php @@ -31,4 +31,4 @@ function Piwik_CountryTranslate($label) return Piwik_Translate('General_Unknown'); } return Piwik_Translate('UserCountry_country_'. $label); -}
\ No newline at end of file +} diff --git a/plugins/UserCountry/index.tpl b/plugins/UserCountry/index.tpl index a6ffb1345f..efea18c986 100644 --- a/plugins/UserCountry/index.tpl +++ b/plugins/UserCountry/index.tpl @@ -1,14 +1,14 @@ -{postEvent name="template_headerUserCountry"}
-
-<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script>
-
-<h2>{'UserCountry_Country'|translate}</h2>
-{$dataTableCountry}
-
-<h2>{'UserCountry_Continent'|translate}</h2>
-{$dataTableContinent}
-
-<p>{sparkline src=$urlSparklineCountries}<span>
-{'UserCountry_DistinctCountries'|translate:"<strong>$numberDistinctCountries</strong>"} </span></p>
-
-{postEvent name="template_footerUserCountry"}
+{postEvent name="template_headerUserCountry"} + +<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script> + +<h2>{'UserCountry_Country'|translate}</h2> +{$dataTableCountry} + +<h2>{'UserCountry_Continent'|translate}</h2> +{$dataTableContinent} + +<p>{sparkline src=$urlSparklineCountries}<span> +{'UserCountry_DistinctCountries'|translate:"<strong>$numberDistinctCountries</strong>"} </span></p> + +{postEvent name="template_footerUserCountry"} diff --git a/plugins/UserSettings/index.tpl b/plugins/UserSettings/index.tpl index d8bb0efa92..91400a6e7c 100644 --- a/plugins/UserSettings/index.tpl +++ b/plugins/UserSettings/index.tpl @@ -1,29 +1,29 @@ -<div id='leftcolumn'>
- <h2>{'UserSettings_BrowserFamilies'|translate}</h2>
- {$dataTableBrowserType}
-
- <h2>{'UserSettings_Browsers'|translate}</h2>
- {$dataTableBrowser}
-
- <h2>{'UserSettings_Plugins'|translate}</h2>
- {$dataTablePlugin}
-</div>
-
-<div id='rightcolumn'>
- <h2>{'UserSettings_Configurations'|translate}</h2>
- {$dataTableConfiguration}
-
- <h2>{'UserSettings_OperatinsSystems'|translate}</h2>
- {$dataTableOS}
-
- <h2>{'UserSettings_Resolutions'|translate}</h2>
- {$dataTableResolution}
-
- <h2>{'UserSettings_WideScreen'|translate}</h2>
- {$dataTableWideScreen}
-</div>
-
-
-
-
-
+<div id='leftcolumn'> + <h2>{'UserSettings_BrowserFamilies'|translate}</h2> + {$dataTableBrowserType} + + <h2>{'UserSettings_Browsers'|translate}</h2> + {$dataTableBrowser} + + <h2>{'UserSettings_Plugins'|translate}</h2> + {$dataTablePlugin} +</div> + +<div id='rightcolumn'> + <h2>{'UserSettings_Configurations'|translate}</h2> + {$dataTableConfiguration} + + <h2>{'UserSettings_OperatinsSystems'|translate}</h2> + {$dataTableOS} + + <h2>{'UserSettings_Resolutions'|translate}</h2> + {$dataTableResolution} + + <h2>{'UserSettings_WideScreen'|translate}</h2> + {$dataTableWideScreen} +</div> + + + + + diff --git a/plugins/UsersManager/templates/UsersManager.tpl b/plugins/UsersManager/templates/UsersManager.tpl index 587938344e..07b066c6b0 100644 --- a/plugins/UsersManager/templates/UsersManager.tpl +++ b/plugins/UsersManager/templates/UsersManager.tpl @@ -1,144 +1,144 @@ -{assign var=showSitesSelection value=false}
-{assign var=showPeriodSelection value=false}
-{include file="CoreAdminHome/templates/header.tpl"}
-{loadJavascriptTranslations plugins='UsersManager'}
-{include file="CoreAdminHome/templates/menu.tpl"}
-
-{literal}
-<style>
-.dialog {
- display: none;
- padding:20px 10px;
- color:#7A0101;
- cursor:wait;
- font-size:1.2em;
- font-weight:bold;
- text-align:center;
-}
-
-#accessUpdated {
- color: red;
- text-align: center;
- font-weight: bold;
- width: 350px;
- margin: 10px;
- padding: 10px;
- display: none;
- border: 3px solid green;
- color: green;
-}
-#access td, #users td {
- spacing: 0px;
- padding: 2px 5px 5px 4px;
- border: 1px solid #660000;
- width: 100px;
-}
-.editable:hover, .addrow:hover, .updateAccess:hover, .accessGranted:hover, .adduser:hover, .edituser:hover, .deleteuser:hover, .updateuser:hover, .cancel:hover{
- cursor: pointer;
-}
-
-.addrow {
- font-color:#3A477B;
- padding:1em;
- font-weight:bold;
-}
-.addrow a {
- text-decoration: none;
-}
-.addrow img {
- vertical-align: middle;
-}
-</style>
-{/literal}
-
-<h2>{'UsersManager_ManageAccess'|translate}</h2>
-<p>{'UsersManager_MainDescription'|translate}</p>
-<div id="sites">
-<form method="post" action="{url action=index}" id="accessSites">
- <p>{'UsersManager_Sites'|translate}: <select id="selectIdsite" name="idsite" onchange="this.form.submit()">
-
- <optgroup label="{'UsersManager_AllWebsites'|translate}">
- <option label="{'UsersManager_AllWebsites'|translate}" value="all" {if $idSiteSelected=='all'} selected="selected"{/if}>{'UsersManager_ApplyToAllWebsites'|translate}</option>
- </optgroup>
-
- <optgroup label="{'UsersManager_Sites'|translate}">
- {foreach from=$websites item=info}
- <option value="{$info.idsite}" {if $idSiteSelected==$info.idsite} selected="selected"{/if}>{$info.name}</option>
- {/foreach}
- </optgroup>
-
- </select></p>
-</form>
-</div>
-
-<table class="admin" id="access">
-<thead>
-<tr>
- <th>{'UsersManager_User'|translate}</th>
- <th>{'UsersManager_PrivNone'|translate}</th>
- <th>{'UsersManager_PrivView'|translate}</th>
- <th>{'UsersManager_PrivAdmin'|translate}</th>
-</tr>
-</thead>
-
-<tbody>
-{foreach from=$usersAccessByWebsite key=login item=access}
-{assign var=accesValid value="<img src='plugins/UsersManager/images/ok.png' class='accessGranted'>"}
-{assign var=accesInvalid value="<img src='plugins/UsersManager/images/no-access.png' class='updateAccess'>"}
-<tr>
- <td id='login'>{$login}</td>
- <td id='noaccess'>{if $access=='noaccess' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td>
- <td id='view'>{if $access=='view' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td>
- <td id='admin'>{if $access=='admin' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td>
-</tr>
-{/foreach}
-</tbody>
-</table>
-
-<div id="accessUpdated">{'General_Done'|translate}!</div>
-
-<div class="dialog" id="confirm">
- <p>{'UsersManager_ChangeAllConfirm'|translate:"<span id='login'></span>"}</p>
- <input id="yes" type="button" value="{'General_Yes'|translate}"/>
- <input id="no" type="button" value="{'General_No'|translate}"/>
-</div>
-
-<br/>
-<h2>{'UsersManager_UsersManagement'|translate}</h2>
-<p>{'UsersManager_UsersManagementMainDescription'|translate}</p>
-<div id="ajaxError" style="display:none"></div>
-<div id="ajaxLoading" style="display:none"><div id="loadingPiwik"><img src="themes/default/images/loading-blue.gif" alt="" /> {'General_LoadingData'|translate}</div></div>
-<table class="admin" id="users">
- <thead>
- <tr>
- <th>{'UsersManager_Login'|translate}</th>
- <th>{'UsersManager_Password'|translate}</th>
- <th>{'UsersManager_Email'|translate}</th>
- <th>{'UsersManager_Alias'|translate}</th>
- <th>{'UsersManager_Token'|translate}</th>
- <th>{'General_Edit'|translate}</th>
- <th>{'General_Delete'|translate}</th>
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$users item=user key=i}
- {if $user.login != 'anonymous'}
- <tr class="editable" id="row{$i}">
- <td id="userLogin" class="editable">{$user.login}</td>
- <td id="password" class="editable">-</td>
- <td id="email" class="editable">{$user.email}</td>
- <td id="alias" class="editable">{$user.alias}</td>
- <td id="alias">{$user.token_auth}</td>
- <td><img src='plugins/UsersManager/images/edit.png' class="edituser" id="row{$i}" href='#'></td>
- <td><img src='plugins/UsersManager/images/remove.png' class="deleteuser" id="row{$i}" value="Delete"></td>
- </tr>
- {/if}
- {/foreach}
- </tbody>
-</table>
-
-<div class="addrow"><a href="#"><img src='plugins/UsersManager/images/add.png'> {'UsersManager_AddUser'|translate}</a></div>
-<script type="text/javascript" src="plugins/UsersManager/templates/UsersManager.js"></script>
-
-{include file="CoreAdminHome/templates/footer.tpl"}
\ No newline at end of file +{assign var=showSitesSelection value=false} +{assign var=showPeriodSelection value=false} +{include file="CoreAdminHome/templates/header.tpl"} +{loadJavascriptTranslations plugins='UsersManager'} +{include file="CoreAdminHome/templates/menu.tpl"} + +{literal} +<style> +.dialog { + display: none; + padding:20px 10px; + color:#7A0101; + cursor:wait; + font-size:1.2em; + font-weight:bold; + text-align:center; +} + +#accessUpdated { + color: red; + text-align: center; + font-weight: bold; + width: 350px; + margin: 10px; + padding: 10px; + display: none; + border: 3px solid green; + color: green; +} +#access td, #users td { + spacing: 0px; + padding: 2px 5px 5px 4px; + border: 1px solid #660000; + width: 100px; +} +.editable:hover, .addrow:hover, .updateAccess:hover, .accessGranted:hover, .adduser:hover, .edituser:hover, .deleteuser:hover, .updateuser:hover, .cancel:hover{ + cursor: pointer; +} + +.addrow { + font-color:#3A477B; + padding:1em; + font-weight:bold; +} +.addrow a { + text-decoration: none; +} +.addrow img { + vertical-align: middle; +} +</style> +{/literal} + +<h2>{'UsersManager_ManageAccess'|translate}</h2> +<p>{'UsersManager_MainDescription'|translate}</p> +<div id="sites"> +<form method="post" action="{url action=index}" id="accessSites"> + <p>{'UsersManager_Sites'|translate}: <select id="selectIdsite" name="idsite" onchange="this.form.submit()"> + + <optgroup label="{'UsersManager_AllWebsites'|translate}"> + <option label="{'UsersManager_AllWebsites'|translate}" value="all" {if $idSiteSelected=='all'} selected="selected"{/if}>{'UsersManager_ApplyToAllWebsites'|translate}</option> + </optgroup> + + <optgroup label="{'UsersManager_Sites'|translate}"> + {foreach from=$websites item=info} + <option value="{$info.idsite}" {if $idSiteSelected==$info.idsite} selected="selected"{/if}>{$info.name}</option> + {/foreach} + </optgroup> + + </select></p> +</form> +</div> + +<table class="admin" id="access"> +<thead> +<tr> + <th>{'UsersManager_User'|translate}</th> + <th>{'UsersManager_PrivNone'|translate}</th> + <th>{'UsersManager_PrivView'|translate}</th> + <th>{'UsersManager_PrivAdmin'|translate}</th> +</tr> +</thead> + +<tbody> +{foreach from=$usersAccessByWebsite key=login item=access} +{assign var=accesValid value="<img src='plugins/UsersManager/images/ok.png' class='accessGranted'>"} +{assign var=accesInvalid value="<img src='plugins/UsersManager/images/no-access.png' class='updateAccess'>"} +<tr> + <td id='login'>{$login}</td> + <td id='noaccess'>{if $access=='noaccess' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td> + <td id='view'>{if $access=='view' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td> + <td id='admin'>{if $access=='admin' and $idSiteSelected!='all'}{$accesValid}{else}{$accesInvalid}{/if} </td> +</tr> +{/foreach} +</tbody> +</table> + +<div id="accessUpdated">{'General_Done'|translate}!</div> + +<div class="dialog" id="confirm"> + <p>{'UsersManager_ChangeAllConfirm'|translate:"<span id='login'></span>"}</p> + <input id="yes" type="button" value="{'General_Yes'|translate}"/> + <input id="no" type="button" value="{'General_No'|translate}"/> +</div> + +<br/> +<h2>{'UsersManager_UsersManagement'|translate}</h2> +<p>{'UsersManager_UsersManagementMainDescription'|translate}</p> +<div id="ajaxError" style="display:none"></div> +<div id="ajaxLoading" style="display:none"><div id="loadingPiwik"><img src="themes/default/images/loading-blue.gif" alt="" /> {'General_LoadingData'|translate}</div></div> +<table class="admin" id="users"> + <thead> + <tr> + <th>{'UsersManager_Login'|translate}</th> + <th>{'UsersManager_Password'|translate}</th> + <th>{'UsersManager_Email'|translate}</th> + <th>{'UsersManager_Alias'|translate}</th> + <th>{'UsersManager_Token'|translate}</th> + <th>{'General_Edit'|translate}</th> + <th>{'General_Delete'|translate}</th> + </tr> + </thead> + + <tbody> + {foreach from=$users item=user key=i} + {if $user.login != 'anonymous'} + <tr class="editable" id="row{$i}"> + <td id="userLogin" class="editable">{$user.login}</td> + <td id="password" class="editable">-</td> + <td id="email" class="editable">{$user.email}</td> + <td id="alias" class="editable">{$user.alias}</td> + <td id="alias">{$user.token_auth}</td> + <td><img src='plugins/UsersManager/images/edit.png' class="edituser" id="row{$i}" href='#'></td> + <td><img src='plugins/UsersManager/images/remove.png' class="deleteuser" id="row{$i}" value="Delete"></td> + </tr> + {/if} + {/foreach} + </tbody> +</table> + +<div class="addrow"><a href="#"><img src='plugins/UsersManager/images/add.png'> {'UsersManager_AddUser'|translate}</a></div> +<script type="text/javascript" src="plugins/UsersManager/templates/UsersManager.js"></script> + +{include file="CoreAdminHome/templates/footer.tpl"} diff --git a/plugins/VisitFrequency/index.tpl b/plugins/VisitFrequency/index.tpl index 87b32ce599..069a56d4df 100644 --- a/plugins/VisitFrequency/index.tpl +++ b/plugins/VisitFrequency/index.tpl @@ -1,11 +1,11 @@ -{postEvent name="template_headerVisitsFrequency"}
-<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script>
-
-<a name="evolutionGraph" graphId="VisitFrequencygetLastVisitsReturningGraph"></a>
-<h2>{'VisitFrequency_Evolution'|translate}</h2>
-{$graphEvolutionVisitFrequency}
-<br />
-
-{include file=VisitFrequency/sparklines.tpl}
-
-{postEvent name="template_footerVisitsFrequency"}
\ No newline at end of file +{postEvent name="template_headerVisitsFrequency"} +<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script> + +<a name="evolutionGraph" graphId="VisitFrequencygetLastVisitsReturningGraph"></a> +<h2>{'VisitFrequency_Evolution'|translate}</h2> +{$graphEvolutionVisitFrequency} +<br /> + +{include file=VisitFrequency/sparklines.tpl} + +{postEvent name="template_footerVisitsFrequency"} diff --git a/plugins/VisitFrequency/sparklines.tpl b/plugins/VisitFrequency/sparklines.tpl index 32f9cbfc84..bccbd06ea4 100644 --- a/plugins/VisitFrequency/sparklines.tpl +++ b/plugins/VisitFrequency/sparklines.tpl @@ -1,13 +1,13 @@ -
- <p>{sparkline src=$urlSparklineNbVisitsReturning}<span>
- {'VisitFrequency_ReturnVisits'|translate:"<strong>$nbVisitsReturning</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineNbActionsReturning}<span>
- {'VisitFrequency_ReturnActions'|translate:"<strong>$nbActionsReturning</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineMaxActionsReturning}<span>
- {'VisitFrequency_ReturnMaxActions'|translate:"<strong>$maxActionsReturning</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineSumVisitLengthReturning}<span>
- {assign var=sumtimeVisitLengthReturning value=$sumVisitLengthReturning|sumtime}
- {'VisitFrequency_ReturnTotalTime'|translate:"<strong>$sumtimeVisitLengthReturning</strong>"}</span></p>
- <p>{sparkline src=$urlSparklineBounceCountReturning}<span>
- {'VisitFrequency_ReturnBounces'|translate:"<strong>$bounceCountReturning</strong>"} </span></p>
-
\ No newline at end of file + + <p>{sparkline src=$urlSparklineNbVisitsReturning}<span> + {'VisitFrequency_ReturnVisits'|translate:"<strong>$nbVisitsReturning</strong>"}</span></p> + <p>{sparkline src=$urlSparklineNbActionsReturning}<span> + {'VisitFrequency_ReturnActions'|translate:"<strong>$nbActionsReturning</strong>"}</span></p> + <p>{sparkline src=$urlSparklineMaxActionsReturning}<span> + {'VisitFrequency_ReturnMaxActions'|translate:"<strong>$maxActionsReturning</strong>"}</span></p> + <p>{sparkline src=$urlSparklineSumVisitLengthReturning}<span> + {assign var=sumtimeVisitLengthReturning value=$sumVisitLengthReturning|sumtime} + {'VisitFrequency_ReturnTotalTime'|translate:"<strong>$sumtimeVisitLengthReturning</strong>"}</span></p> + <p>{sparkline src=$urlSparklineBounceCountReturning}<span> + {'VisitFrequency_ReturnBounces'|translate:"<strong>$bounceCountReturning</strong>"} </span></p> + diff --git a/plugins/VisitTime/API.php b/plugins/VisitTime/API.php index 47dc678216..96f88a7c2b 100644 --- a/plugins/VisitTime/API.php +++ b/plugins/VisitTime/API.php @@ -55,4 +55,4 @@ class Piwik_VisitTime_API function Piwik_getTimeLabel($label) { return sprintf(Piwik_Translate('VisitTime_NHour'), $label); -}
\ No newline at end of file +} diff --git a/plugins/VisitTime/index.tpl b/plugins/VisitTime/index.tpl index 0f9379adac..82af946c7a 100644 --- a/plugins/VisitTime/index.tpl +++ b/plugins/VisitTime/index.tpl @@ -1,9 +1,9 @@ -<div id='leftcolumn'>
-<h2>{'VisitTime_LocalTime'|translate}</h2>
-{$dataTableVisitInformationPerLocalTime}
-</div>
-
-<div id='rightcolumn'>
-<h2>{'VisitTime_ServerTime'|translate}</h2>
-{$dataTableVisitInformationPerServerTime}
-</div>
+<div id='leftcolumn'> +<h2>{'VisitTime_LocalTime'|translate}</h2> +{$dataTableVisitInformationPerLocalTime} +</div> + +<div id='rightcolumn'> +<h2>{'VisitTime_ServerTime'|translate}</h2> +{$dataTableVisitInformationPerServerTime} +</div> diff --git a/plugins/VisitorInterest/index.tpl b/plugins/VisitorInterest/index.tpl index a9a0785822..f3855a44dc 100644 --- a/plugins/VisitorInterest/index.tpl +++ b/plugins/VisitorInterest/index.tpl @@ -1,7 +1,7 @@ -
-<h2>{'VisitorInterest_VisitsPerDuration'|translate}</h2>
-{$dataTableNumberOfVisitsPerVisitDuration}
-
-<h2>{'VisitorInterest_VisitsPerNbOfPages'|translate}</h2>
-{$dataTableNumberOfVisitsPerPage}
-
+ +<h2>{'VisitorInterest_VisitsPerDuration'|translate}</h2> +{$dataTableNumberOfVisitsPerVisitDuration} + +<h2>{'VisitorInterest_VisitsPerNbOfPages'|translate}</h2> +{$dataTableNumberOfVisitsPerPage} + diff --git a/plugins/VisitsSummary/index.tpl b/plugins/VisitsSummary/index.tpl index bacb8d761e..320efabea0 100644 --- a/plugins/VisitsSummary/index.tpl +++ b/plugins/VisitsSummary/index.tpl @@ -1,15 +1,15 @@ -<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script>
-
-<a name="evolutionGraph" graphId="VisitsSummarygetLastVisitsGraph"></a>
-<h2>{'VisitsSummary_Evolution'|translate:$period}</h2>
-{$graphEvolutionVisitsSummary}
-
-<h2>{'VisitsSummary_Report'|translate}</h2>
-{include file=VisitsSummary/sparklines.tpl}
-
-
-<br /><br /><br />
-<p style='color:lightgrey; size:0.8em;'>
-{'VisitsSummary_GenerateTime'|translate:$totalTimeGeneration:$totalNumberOfQueries}
-{if $totalNumberOfQueries != 0}, {'VisitsSummary_GenerateQueries'|translate:$totalNumberOfQueries}{/if}
-</p>
+<script type="text/javascript" src="plugins/CoreHome/templates/sparkline.js"></script> + +<a name="evolutionGraph" graphId="VisitsSummarygetLastVisitsGraph"></a> +<h2>{'VisitsSummary_Evolution'|translate:$period}</h2> +{$graphEvolutionVisitsSummary} + +<h2>{'VisitsSummary_Report'|translate}</h2> +{include file=VisitsSummary/sparklines.tpl} + + +<br /><br /><br /> +<p style='color:lightgrey; size:0.8em;'> +{'VisitsSummary_GenerateTime'|translate:$totalTimeGeneration:$totalNumberOfQueries} +{if $totalNumberOfQueries != 0}, {'VisitsSummary_GenerateQueries'|translate:$totalNumberOfQueries}{/if} +</p> diff --git a/plugins/VisitsSummary/sparklines.tpl b/plugins/VisitsSummary/sparklines.tpl index dcf779cb56..f3e5919a75 100644 --- a/plugins/VisitsSummary/sparklines.tpl +++ b/plugins/VisitsSummary/sparklines.tpl @@ -1,8 +1,8 @@ -<div>
-<p>{sparkline src=$urlSparklineNbVisits} <span>{'VisitsSummary_NbVisits'|translate:"<strong>$nbVisits</strong>"}</span></p>
-<p>{sparkline src=$urlSparklineNbUniqVisitors} <span>{'VisitsSummary_NbUniqueVisitors'|translate:"<strong>$nbUniqVisitors</strong>"}</span></p>
-<p>{sparkline src=$urlSparklineNbActions} <span>{'VisitsSummary_NbActions'|translate:"<strong>$nbActions</strong>"}</span></p>
-<p>{sparkline src=$urlSparklineSumVisitLength} <span>{assign var=sumtimeVisitLength value=$sumVisitLength|sumtime} {'VisitsSummary_TotalTime'|translate:"<strong>$sumtimeVisitLength</strong>"}</span></p>
-<p>{sparkline src=$urlSparklineMaxActions} <span>{'VisitsSummary_MaxNbActions'|translate:"<strong>$maxActions</strong>"}</span></p>
-<p>{sparkline src=$urlSparklineBounceCount} <span>{'VisitsSummary_NbBounced'|translate:"<strong>$bounceCount</strong>"}</span></p>
-</div>
+<div> +<p>{sparkline src=$urlSparklineNbVisits} <span>{'VisitsSummary_NbVisits'|translate:"<strong>$nbVisits</strong>"}</span></p> +<p>{sparkline src=$urlSparklineNbUniqVisitors} <span>{'VisitsSummary_NbUniqueVisitors'|translate:"<strong>$nbUniqVisitors</strong>"}</span></p> +<p>{sparkline src=$urlSparklineNbActions} <span>{'VisitsSummary_NbActions'|translate:"<strong>$nbActions</strong>"}</span></p> +<p>{sparkline src=$urlSparklineSumVisitLength} <span>{assign var=sumtimeVisitLength value=$sumVisitLength|sumtime} {'VisitsSummary_TotalTime'|translate:"<strong>$sumtimeVisitLength</strong>"}</span></p> +<p>{sparkline src=$urlSparklineMaxActions} <span>{'VisitsSummary_MaxNbActions'|translate:"<strong>$maxActions</strong>"}</span></p> +<p>{sparkline src=$urlSparklineBounceCount} <span>{'VisitsSummary_NbBounced'|translate:"<strong>$bounceCount</strong>"}</span></p> +</div> diff --git a/plugins/Widgetize/Controller.php b/plugins/Widgetize/Controller.php index 1905dd1a1c..bfc0738adc 100644 --- a/plugins/Widgetize/Controller.php +++ b/plugins/Widgetize/Controller.php @@ -74,4 +74,4 @@ class Piwik_Widgetize_Controller extends Piwik_Dashboard_Controller $view->content = $outputDataTable; echo $view->render(); } -}
\ No newline at end of file +} diff --git a/plugins/Widgetize/templates/iframe.tpl b/plugins/Widgetize/templates/iframe.tpl index c008a3701e..0cb5f23cf9 100644 --- a/plugins/Widgetize/templates/iframe.tpl +++ b/plugins/Widgetize/templates/iframe.tpl @@ -1,25 +1,25 @@ -<html>
-<body>
-
-{loadJavascriptTranslations plugins='CoreHome'}
-
-{include file="CoreHome/templates/js_global_variables.tpl"}
-<script type="text/javascript" src="libs/jquery/jquery.js"></script>
-<script type="text/javascript" src="libs/javascript/sprintf.js"></script>
-<script type="text/javascript" src="themes/default/common.js"></script>
-<script type="text/javascript" src="libs/jquery/jquery.dimensions.js"></script>
-<script type="text/javascript" src="libs/jquery/tooltip/jquery.tooltip.js"></script>
-<script type="text/javascript" src="libs/jquery/truncate/jquery.truncate.js"></script>
-<script type="text/javascript" src="libs/jquery/jquery.scrollTo.js"></script>
-
-<script type="text/javascript" src="libs/swfobject/swfobject.js"></script>
-
-<script type="text/javascript" src="plugins/CoreHome/templates/datatable.js"></script>
-<link rel="stylesheet" href="plugins/CoreHome/templates/datatable.css">
-
-<div class="widgetDiv">
-{$content}
-</div>
-
-</body>
-</html>
+<html> +<body> + +{loadJavascriptTranslations plugins='CoreHome'} + +{include file="CoreHome/templates/js_global_variables.tpl"} +<script type="text/javascript" src="libs/jquery/jquery.js"></script> +<script type="text/javascript" src="libs/javascript/sprintf.js"></script> +<script type="text/javascript" src="themes/default/common.js"></script> +<script type="text/javascript" src="libs/jquery/jquery.dimensions.js"></script> +<script type="text/javascript" src="libs/jquery/tooltip/jquery.tooltip.js"></script> +<script type="text/javascript" src="libs/jquery/truncate/jquery.truncate.js"></script> +<script type="text/javascript" src="libs/jquery/jquery.scrollTo.js"></script> + +<script type="text/javascript" src="libs/swfobject/swfobject.js"></script> + +<script type="text/javascript" src="plugins/CoreHome/templates/datatable.js"></script> +<link rel="stylesheet" href="plugins/CoreHome/templates/datatable.css"> + +<div class="widgetDiv"> +{$content} +</div> + +</body> +</html> diff --git a/plugins/Widgetize/templates/index.tpl b/plugins/Widgetize/templates/index.tpl index 8ffabb6dfb..8254bf9fef 100644 --- a/plugins/Widgetize/templates/index.tpl +++ b/plugins/Widgetize/templates/index.tpl @@ -114,4 +114,4 @@ If you want your widgets to be viewable by everybody, you first have to set the <div class="menuClear"> </div> </div> <div id='iframeDivToExport' style='display:none;'></div> -</div>
\ No newline at end of file +</div> diff --git a/plugins/Widgetize/templates/js.tpl b/plugins/Widgetize/templates/js.tpl index dc43825377..50284a9591 100644 --- a/plugins/Widgetize/templates/js.tpl +++ b/plugins/Widgetize/templates/js.tpl @@ -1,19 +1,19 @@ -{loadJavascriptTranslations noHtml=1 plugins='CoreHome'}
-
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/swfobject/swfobject.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/javascript/sprintf.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/jquery.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}themes/default/common.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/jquery.dimensions.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/tooltip/jquery.tooltip.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/truncate/jquery.truncate.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}plugins/CoreHome/templates/datatable.js"></scr'+'ipt>');
-document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/ui.mouse.js"></scr'+'ipt>');
-
-document.write('<link rel="stylesheet" href="{$piwikUrl}themes/default/common.css">');
-document.write('<link rel="stylesheet" href="{$piwikUrl}plugins/CoreHome/templates/styles.css">');
-document.write('<link rel="stylesheet" href="{$piwikUrl}plugins/CoreHome/templates/datatable.css">');
-
-var content = '{$content|escape:'javascript'}';
-document.write('<scr'+'ipt language="javascript">document.write(content)</scr'+'ipt>');
-
+{loadJavascriptTranslations noHtml=1 plugins='CoreHome'} + +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/swfobject/swfobject.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/javascript/sprintf.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/jquery.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}themes/default/common.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/jquery.dimensions.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/tooltip/jquery.tooltip.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/truncate/jquery.truncate.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}plugins/CoreHome/templates/datatable.js"></scr'+'ipt>'); +document.write('<scr'+'ipt language="javascript" src="{$piwikUrl}libs/jquery/ui.mouse.js"></scr'+'ipt>'); + +document.write('<link rel="stylesheet" href="{$piwikUrl}themes/default/common.css">'); +document.write('<link rel="stylesheet" href="{$piwikUrl}plugins/CoreHome/templates/styles.css">'); +document.write('<link rel="stylesheet" href="{$piwikUrl}plugins/CoreHome/templates/datatable.css">'); + +var content = '{$content|escape:'javascript'}'; +document.write('<scr'+'ipt language="javascript">document.write(content)</scr'+'ipt>'); + diff --git a/plugins/Widgetize/templates/test_jsinclude.tpl b/plugins/Widgetize/templates/test_jsinclude.tpl index 111893fe3f..b2416acee3 100644 --- a/plugins/Widgetize/templates/test_jsinclude.tpl +++ b/plugins/Widgetize/templates/test_jsinclude.tpl @@ -17,4 +17,4 @@ <noscript>Powered by <a href="http://piwik.org">Piwik</a></div></noscript> <p>This text is after the JS INCLUDE 2</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/plugins/Widgetize/templates/test_jsinclude2.tpl b/plugins/Widgetize/templates/test_jsinclude2.tpl index 01220310fc..fb5d288e59 100644 --- a/plugins/Widgetize/templates/test_jsinclude2.tpl +++ b/plugins/Widgetize/templates/test_jsinclude2.tpl @@ -24,4 +24,4 @@ <p>This text is after the JS INCLUDE</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/robots.txt b/robots.txt index e69de29bb2..8b13789179 100644 --- a/robots.txt +++ b/robots.txt @@ -0,0 +1 @@ + diff --git a/tests/README.txt b/tests/README.txt index 0abc66b16f..1003593aa9 100644 --- a/tests/README.txt +++ b/tests/README.txt @@ -11,4 +11,4 @@ Piwik tests use the Simpletest Unit Testing framework. If you want to help, we are always looking to improve the Piwik code coverage! Please contact us at hello@piwik.org -
\ No newline at end of file + diff --git a/tests/TestFrameworkConfig/classes/PiwikTestEnv.php b/tests/TestFrameworkConfig/classes/PiwikTestEnv.php index 4bdd89235e..800be0ebfd 100644 --- a/tests/TestFrameworkConfig/classes/PiwikTestEnv.php +++ b/tests/TestFrameworkConfig/classes/PiwikTestEnv.php @@ -1,84 +1,84 @@ -<?php
-
-require_once dirname(__FILE__) . '/../../../application/config.php';
-require_once dirname(__FILE__) . '/../../TestFramework/classes/AbstractTestEnv.php';
-require_once dirname(__FILE__) . '/../../../library/doctrine/Doctrine.php';
-require_once dirname(__FILE__) . '/../../../library/OX/Doctrine/cfg/doctrine-init.php';
-require_once dirname(__FILE__) . '/../../../library/OX/Common/zend-init.php';
-require_once dirname(__FILE__) . '/../../../library/OX/Doctrine/DB.php';
-require_once dirname(__FILE__) . '/../../../library/OX/Common/Config.php';
-require_once dirname(__FILE__) . '/../../../application/model-utils/SampleDataGenerator.php';
-
-class PiwikTestEnv extends AbstractTestEnv
-{
- public function ensureTestDatabaseConnection()
- {
- $connection = Doctrine_Manager::connection();
- $dsn = OX_Doctrine_DB::getDsn(OX_DSN_STRING,
- OX_Common_Config::instance('database',
- $this->getConfigFilename())->toArray());
- $newConnection = Doctrine_Manager::connection($dsn);
- if (0 != strcmp($newConnection->getOption('dsn'),
- $connection->getOption('dsn'))) {
-
- Doctrine_Manager::getInstance()->closeConnection(
- $connection);
- $connection = Doctrine_Manager::getInstance(
- )->openConnection($dsn, null, TRUE);
- global $conn;
- $conn = $connection;
- }
- Doctrine_Manager::getInstance()->closeConnection(
- $newConnection);
- }
-
- public function setupDB($ignore_errors = false)
- {
- $this->ensureTestDatabaseConnection();
- $connection = Doctrine_Manager::connection();
-
- if (isset($connection)) {
- $result = $connection->createDatabase();
-
- if (!$ignore_errors) {
- if (!is_string($result)) {
- throw new TestFrameworkException(
- $result->errorMessage());
- }
- }
- }
- }
-
- public function setupCoreTables()
- {
- Doctrine::createTablesFromModels();
- }
-
- public function setupDefaultData()
- {
- SampleDataGenerator::generateData(false);
- }
-
- public function teardownDB()
- {
- $this->ensureTestDatabaseConnection();
- $connection = Doctrine_Manager::connection();
- $connection->dropDatabase();
- }
-
- public function getConfigFilename()
- {
- return dirname(__FILE__) . '/../../../config/config.ini.php';
-
- }
-
- public function getApplicationVersion()
- {
- return '0.2';
- }
-
- public function getApplicationName()
- {
- return 'Piwik';
- }
-}
+<?php + +require_once dirname(__FILE__) . '/../../../application/config.php'; +require_once dirname(__FILE__) . '/../../TestFramework/classes/AbstractTestEnv.php'; +require_once dirname(__FILE__) . '/../../../library/doctrine/Doctrine.php'; +require_once dirname(__FILE__) . '/../../../library/OX/Doctrine/cfg/doctrine-init.php'; +require_once dirname(__FILE__) . '/../../../library/OX/Common/zend-init.php'; +require_once dirname(__FILE__) . '/../../../library/OX/Doctrine/DB.php'; +require_once dirname(__FILE__) . '/../../../library/OX/Common/Config.php'; +require_once dirname(__FILE__) . '/../../../application/model-utils/SampleDataGenerator.php'; + +class PiwikTestEnv extends AbstractTestEnv +{ + public function ensureTestDatabaseConnection() + { + $connection = Doctrine_Manager::connection(); + $dsn = OX_Doctrine_DB::getDsn(OX_DSN_STRING, + OX_Common_Config::instance('database', + $this->getConfigFilename())->toArray()); + $newConnection = Doctrine_Manager::connection($dsn); + if (0 != strcmp($newConnection->getOption('dsn'), + $connection->getOption('dsn'))) { + + Doctrine_Manager::getInstance()->closeConnection( + $connection); + $connection = Doctrine_Manager::getInstance( + )->openConnection($dsn, null, TRUE); + global $conn; + $conn = $connection; + } + Doctrine_Manager::getInstance()->closeConnection( + $newConnection); + } + + public function setupDB($ignore_errors = false) + { + $this->ensureTestDatabaseConnection(); + $connection = Doctrine_Manager::connection(); + + if (isset($connection)) { + $result = $connection->createDatabase(); + + if (!$ignore_errors) { + if (!is_string($result)) { + throw new TestFrameworkException( + $result->errorMessage()); + } + } + } + } + + public function setupCoreTables() + { + Doctrine::createTablesFromModels(); + } + + public function setupDefaultData() + { + SampleDataGenerator::generateData(false); + } + + public function teardownDB() + { + $this->ensureTestDatabaseConnection(); + $connection = Doctrine_Manager::connection(); + $connection->dropDatabase(); + } + + public function getConfigFilename() + { + return dirname(__FILE__) . '/../../../config/config.ini.php'; + + } + + public function getApplicationVersion() + { + return '0.2'; + } + + public function getApplicationName() + { + return 'Piwik'; + } +} diff --git a/tests/TestFrameworkConfig/config.php b/tests/TestFrameworkConfig/config.php index 8678ed8c2c..342897f5ce 100644 --- a/tests/TestFrameworkConfig/config.php +++ b/tests/TestFrameworkConfig/config.php @@ -1,26 +1,26 @@ -<?php
-
-// Advertiser Console specific config file
-require_once dirname(__FILE__) . '/../TestFramework/classes/TestEnvFactory.php';
-require_once dirname(__FILE__) . '/../TestFramework/classes/TestConfig.php';
-require_once dirname(__FILE__) . '/classes/PiwikTestEnv.php';
-
-define('PEAR_LIBRARY_PATH', dirname(__FILE__) . '/../pear/');
-define('PROJECT_PATH', dirname(__FILE__) . '/../../');
-define('SIMPLETEST_PATH', dirname(__FILE__) . '/../simpletest/');
-
-TestEnvFactory::setTestEnv(new PiwikTestEnv());
-
-TestConfig::getInstance()->addDirectory('core');
-TestConfig::getInstance()->addDirectory('plugins');
-
-TestConfig::getInstance()->addTestType('unit', 'tests/unit');
-TestConfig::getInstance()->addLayer('unit', 'cor', 'Core Classes', EnvType::NO_DB);
-TestConfig::getInstance()->addLayer('unit', 'dal', 'Data Abstraction Layer (DB)', EnvType::DB_WITH_TABLES);
-TestConfig::getInstance()->addLayer('unit', 'extdb', 'Extensions to the system (DB)', EnvType::DB_WITH_TABLES);
-TestConfig::getInstance()->addLayer('unit', 'db', 'DB utils', EnvType::DB_WITH_TABLES);
-TestConfig::getInstance()->addLayer('unit', 'util', 'Commonly used utilities', EnvType::NO_DB);
-TestConfig::getInstance()->addLayer('unit', 'mt', 'Maintenance', EnvType::DB_WITH_TABLES);
-
-TestConfig::getInstance()->addTestType('integration', 'tests/integration');
-TestConfig::getInstance()->addLayer('integration', 'cor', 'Integration tests', EnvType::NO_DB);
+<?php + +// Advertiser Console specific config file +require_once dirname(__FILE__) . '/../TestFramework/classes/TestEnvFactory.php'; +require_once dirname(__FILE__) . '/../TestFramework/classes/TestConfig.php'; +require_once dirname(__FILE__) . '/classes/PiwikTestEnv.php'; + +define('PEAR_LIBRARY_PATH', dirname(__FILE__) . '/../pear/'); +define('PROJECT_PATH', dirname(__FILE__) . '/../../'); +define('SIMPLETEST_PATH', dirname(__FILE__) . '/../simpletest/'); + +TestEnvFactory::setTestEnv(new PiwikTestEnv()); + +TestConfig::getInstance()->addDirectory('core'); +TestConfig::getInstance()->addDirectory('plugins'); + +TestConfig::getInstance()->addTestType('unit', 'tests/unit'); +TestConfig::getInstance()->addLayer('unit', 'cor', 'Core Classes', EnvType::NO_DB); +TestConfig::getInstance()->addLayer('unit', 'dal', 'Data Abstraction Layer (DB)', EnvType::DB_WITH_TABLES); +TestConfig::getInstance()->addLayer('unit', 'extdb', 'Extensions to the system (DB)', EnvType::DB_WITH_TABLES); +TestConfig::getInstance()->addLayer('unit', 'db', 'DB utils', EnvType::DB_WITH_TABLES); +TestConfig::getInstance()->addLayer('unit', 'util', 'Commonly used utilities', EnvType::NO_DB); +TestConfig::getInstance()->addLayer('unit', 'mt', 'Maintenance', EnvType::DB_WITH_TABLES); + +TestConfig::getInstance()->addTestType('integration', 'tests/integration'); +TestConfig::getInstance()->addLayer('integration', 'cor', 'Integration tests', EnvType::NO_DB); diff --git a/tests/build-canoo.xml b/tests/build-canoo.xml index 72f8dc7c2c..b49fe2bad0 100644 --- a/tests/build-canoo.xml +++ b/tests/build-canoo.xml @@ -1,7 +1,7 @@ <project name="canoo" default="webtest" basedir="."> -
+ <property file="webtest/config/webtest.properties"/> - <echo>${wt.home}</echo>
+ <echo>${wt.home}</echo> <import file="${wt.home}/webtest.xml" optional="true" description="Import all functionalities for a full build"/> <property name="wt.testInWork" value="webtest/test_suite"/> @@ -12,4 +12,4 @@ <target name="webtest" depends="wt.full"/> -</project>
\ No newline at end of file +</project> diff --git a/tests/build.xml b/tests/build.xml index 17a272be24..f4bf171f51 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -118,4 +118,4 @@ <antcall target="schemaspy"/> </target> -</project>
\ No newline at end of file +</project> diff --git a/tests/core/ArchiveProcessing/Day.test.php b/tests/core/ArchiveProcessing/Day.test.php index 5adbf0b7e2..cb62d233ca 100644 --- a/tests/core/ArchiveProcessing/Day.test.php +++ b/tests/core/ArchiveProcessing/Day.test.php @@ -299,4 +299,4 @@ class Test_Piwik_ArchiveProcessing_Day extends UnitTestCase ); }*/ -}
\ No newline at end of file +} diff --git a/tests/core/DataTable.test.php b/tests/core/DataTable.test.php index 092fb7e7d3..7ebd90332c 100644 --- a/tests/core/DataTable.test.php +++ b/tests/core/DataTable.test.php @@ -900,4 +900,4 @@ class Test_Piwik_DataTable extends UnitTestCase } -}
\ No newline at end of file +} diff --git a/tests/core/DataTable/Filter/AddSummaryRow.test.php b/tests/core/DataTable/Filter/AddSummaryRow.test.php index 38ce617017..edf56dd842 100644 --- a/tests/core/DataTable/Filter/AddSummaryRow.test.php +++ b/tests/core/DataTable/Filter/AddSummaryRow.test.php @@ -139,4 +139,4 @@ class Test_Piwik_DataTable_Filter_AddSummaryRow extends UnitTestCase { return new Piwik_DataTable_Row(array( Piwik_DataTable_Row::COLUMNS => array('label'=>'google', 'nb' => 1))); } -}
\ No newline at end of file +} diff --git a/tests/core/DataTable/Filter/Limit.test.php b/tests/core/DataTable/Filter/Limit.test.php index dff63cc56f..198352bb47 100644 --- a/tests/core/DataTable/Filter/Limit.test.php +++ b/tests/core/DataTable/Filter/Limit.test.php @@ -139,4 +139,4 @@ class Test_Piwik_DataTable_Filter_Limit extends UnitTestCase $filter = new Piwik_DataTable_Filter_Limit($table, $offset, $limit); $this->assertEqual($table->getRowsCount(), 0); } -}
\ No newline at end of file +} diff --git a/tests/core/DataTable/Filter/Sort.test.php b/tests/core/DataTable/Filter/Sort.test.php index 9f7fafaa19..fb360bc245 100644 --- a/tests/core/DataTable/Filter/Sort.test.php +++ b/tests/core/DataTable/Filter/Sort.test.php @@ -77,4 +77,4 @@ class Test_Piwik_DataTable_Filter_Sort extends UnitTestCase $expectedOrder = array('ask', 'nintendo', 'amazing', 'summary'); $this->assertEqual($table->getColumn('label'), $expectedOrder); } -}
\ No newline at end of file +} diff --git a/tests/core/DataTable/Renderer.test.php b/tests/core/DataTable/Renderer.test.php index 182eec74b9..2ee9079af1 100644 --- a/tests/core/DataTable/Renderer.test.php +++ b/tests/core/DataTable/Renderer.test.php @@ -1059,4 +1059,4 @@ idSite,row2,15"; $this->assertEqual($expected,$rendered); } -}
\ No newline at end of file +} diff --git a/tests/core/Updater/core/0.3.php b/tests/core/Updater/core/0.3.php index e69de29bb2..8b13789179 100644 --- a/tests/core/Updater/core/0.3.php +++ b/tests/core/Updater/core/0.3.php @@ -0,0 +1 @@ + diff --git a/tests/core/Updater/testpluginUpdates/0.0.1.php b/tests/core/Updater/testpluginUpdates/0.0.1.php index 988e82214e..f585d95c4e 100644 --- a/tests/core/Updater/testpluginUpdates/0.0.1.php +++ b/tests/core/Updater/testpluginUpdates/0.0.1.php @@ -1 +1 @@ -should not be loaded
\ No newline at end of file +should not be loaded diff --git a/tests/core/Updater/testpluginUpdates/0.1.php b/tests/core/Updater/testpluginUpdates/0.1.php index e69de29bb2..8b13789179 100644 --- a/tests/core/Updater/testpluginUpdates/0.1.php +++ b/tests/core/Updater/testpluginUpdates/0.1.php @@ -0,0 +1 @@ + diff --git a/tests/core/Updater/testpluginUpdates/0.1beta2.php b/tests/core/Updater/testpluginUpdates/0.1beta2.php index e69de29bb2..8b13789179 100644 --- a/tests/core/Updater/testpluginUpdates/0.1beta2.php +++ b/tests/core/Updater/testpluginUpdates/0.1beta2.php @@ -0,0 +1 @@ + diff --git a/tests/core/UsersManager.test.php b/tests/core/UsersManager.test.php index 193a585828..1c92551917 100644 --- a/tests/core/UsersManager.test.php +++ b/tests/core/UsersManager.test.php @@ -893,4 +893,4 @@ class Test_Piwik_UsersManager extends Test_Database $this->_checkUserHasNotChanged($user, "passowordOK", "email@geaga.com", "NEW ALIAS"); } -}
\ No newline at end of file +} diff --git a/tests/core/piwik.php.test.php b/tests/core/piwik.php.test.php index 305b9e9fed..18a0c9cf78 100644 --- a/tests/core/piwik.php.test.php +++ b/tests/core/piwik.php.test.php @@ -54,4 +54,4 @@ class Test_PiwikPhp extends UnitTestCase $this->assertTrue( ereg($ereg, $GLOBALS['content']) !== false, 'The $GLOBALS[\'DEBUGPIWIK\'] MUST BE SET TO false IN A PRODUCTION ENVIRONMENT !!!'); } -}
\ No newline at end of file +} diff --git a/tests/simpletest/VERSION b/tests/simpletest/VERSION index 5f05a2a0d6..353f5a4540 100755 --- a/tests/simpletest/VERSION +++ b/tests/simpletest/VERSION @@ -1 +1 @@ -1.0.1beta2
\ No newline at end of file +1.0.1beta2 diff --git a/tests/simpletest/authentication.php b/tests/simpletest/authentication.php index 98fe4118d3..31aabc6e47 100755 --- a/tests/simpletest/authentication.php +++ b/tests/simpletest/authentication.php @@ -235,4 +235,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/autorun.php b/tests/simpletest/autorun.php index 72571a6495..67aab96792 100755 --- a/tests/simpletest/autorun.php +++ b/tests/simpletest/autorun.php @@ -60,4 +60,4 @@ $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ? $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array())); } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/browser.php b/tests/simpletest/browser.php index f50b4df1f1..07277c4c8d 100755 --- a/tests/simpletest/browser.php +++ b/tests/simpletest/browser.php @@ -1094,4 +1094,4 @@ return $this->isSubmit($label) || ($this->getLink($label) !== false) || $this->isImage($label); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/collector.php b/tests/simpletest/collector.php index 40b9eac0fc..d5eb393bf8 100755 --- a/tests/simpletest/collector.php +++ b/tests/simpletest/collector.php @@ -119,4 +119,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/compatibility.php b/tests/simpletest/compatibility.php index eefb6029b8..c1a8158799 100755 --- a/tests/simpletest/compatibility.php +++ b/tests/simpletest/compatibility.php @@ -170,4 +170,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/cookies.php b/tests/simpletest/cookies.php index b346a7962e..f15b025089 100755 --- a/tests/simpletest/cookies.php +++ b/tests/simpletest/cookies.php @@ -377,4 +377,4 @@ return $pairs; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/default_reporter.php b/tests/simpletest/default_reporter.php index 2dd597fd81..53984ec233 100755 --- a/tests/simpletest/default_reporter.php +++ b/tests/simpletest/default_reporter.php @@ -93,4 +93,4 @@ $this->SimpleReporterDecorator($reporter); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/detached.php b/tests/simpletest/detached.php index 35ac1331c4..365349a2a6 100755 --- a/tests/simpletest/detached.php +++ b/tests/simpletest/detached.php @@ -93,4 +93,4 @@ return new SimpleTestXmlParser($reporter); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/dumper.php b/tests/simpletest/dumper.php index ea21e6455d..2956790f38 100755 --- a/tests/simpletest/dumper.php +++ b/tests/simpletest/dumper.php @@ -357,4 +357,4 @@ return $formatted; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/eclipse.php b/tests/simpletest/eclipse.php index 86ee9a68b9..bfb98b62b8 100755 --- a/tests/simpletest/eclipse.php +++ b/tests/simpletest/eclipse.php @@ -180,4 +180,4 @@ class EclipseInvoker extends SimpleInvokerDecorator{ } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/encoding.php b/tests/simpletest/encoding.php index bffa071319..6a68aad31c 100755 --- a/tests/simpletest/encoding.php +++ b/tests/simpletest/encoding.php @@ -518,4 +518,4 @@ return $stream; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/errors.php b/tests/simpletest/errors.php index 801f251d73..3033ca6f7c 100755 --- a/tests/simpletest/errors.php +++ b/tests/simpletest/errors.php @@ -285,4 +285,4 @@ function SimpleTestErrorHandler($severity, $message, $filename = null, $line = n return true; } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/exceptions.php b/tests/simpletest/exceptions.php index eb4bd00632..ebbcfd6515 100755 --- a/tests/simpletest/exceptions.php +++ b/tests/simpletest/exceptions.php @@ -189,4 +189,4 @@ class SimpleExceptionTrap { $this->message = false; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/expectation.php b/tests/simpletest/expectation.php index 1ac616b5e5..71b5704542 100755 --- a/tests/simpletest/expectation.php +++ b/tests/simpletest/expectation.php @@ -892,4 +892,4 @@ "] should contain method [$method]"; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/extensions/testdox/test.php b/tests/simpletest/extensions/testdox/test.php index 0c37327dd2..4b805994ef 100755 --- a/tests/simpletest/extensions/testdox/test.php +++ b/tests/simpletest/extensions/testdox/test.php @@ -103,4 +103,4 @@ class TestOfTestDoxReporter extends UnitTestCase { ); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/form.php b/tests/simpletest/form.php index 105268f3ae..77438d6bd5 100755 --- a/tests/simpletest/form.php +++ b/tests/simpletest/form.php @@ -348,4 +348,4 @@ class SimpleForm { return $this->_encode(); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/frames.php b/tests/simpletest/frames.php index cd5b49c046..a094e84aae 100755 --- a/tests/simpletest/frames.php +++ b/tests/simpletest/frames.php @@ -593,4 +593,4 @@ class SimpleFrameset { return null; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/http.php b/tests/simpletest/http.php index 120d74c276..09baeb8645 100755 --- a/tests/simpletest/http.php +++ b/tests/simpletest/http.php @@ -621,4 +621,4 @@ return ! $packet; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/page.php b/tests/simpletest/page.php index de5aba71ac..6b1e438907 100755 --- a/tests/simpletest/page.php +++ b/tests/simpletest/page.php @@ -980,4 +980,4 @@ class SimplePage { return null; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/parser.php b/tests/simpletest/parser.php index c8c3f585e4..7498db0cad 100755 --- a/tests/simpletest/parser.php +++ b/tests/simpletest/parser.php @@ -764,4 +764,4 @@ class SimpleSaxListener { function addContent($text) { } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/reflection_php4.php b/tests/simpletest/reflection_php4.php index 6bb44b7b34..5da333a0c1 100755 --- a/tests/simpletest/reflection_php4.php +++ b/tests/simpletest/reflection_php4.php @@ -133,4 +133,4 @@ class SimpleReflection { return "function &$method()"; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/reflection_php5.php b/tests/simpletest/reflection_php5.php index 5c6224961b..0544c51296 100755 --- a/tests/simpletest/reflection_php5.php +++ b/tests/simpletest/reflection_php5.php @@ -363,4 +363,4 @@ class SimpleReflection { return false; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/remote.php b/tests/simpletest/remote.php index c7e02b124e..aa09ac3fee 100755 --- a/tests/simpletest/remote.php +++ b/tests/simpletest/remote.php @@ -114,4 +114,4 @@ return $this->_size; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/reporter.php b/tests/simpletest/reporter.php index 01fbaf9dd3..b9c6193c09 100755 --- a/tests/simpletest/reporter.php +++ b/tests/simpletest/reporter.php @@ -429,4 +429,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/scorer.php b/tests/simpletest/scorer.php index 279d714dbf..fea80d6ca0 100755 --- a/tests/simpletest/scorer.php +++ b/tests/simpletest/scorer.php @@ -860,4 +860,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/selector.php b/tests/simpletest/selector.php index ec8f354f1e..f8399c1054 100755 --- a/tests/simpletest/selector.php +++ b/tests/simpletest/selector.php @@ -130,4 +130,4 @@ return ($widget->getName() == $this->_label); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/socket.php b/tests/simpletest/socket.php index 4205482080..19e2f33b77 100755 --- a/tests/simpletest/socket.php +++ b/tests/simpletest/socket.php @@ -213,4 +213,4 @@ return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/tag.php b/tests/simpletest/tag.php index b0c49577fe..02abc113f2 100755 --- a/tests/simpletest/tag.php +++ b/tests/simpletest/tag.php @@ -1415,4 +1415,4 @@ return false; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/test_case.php b/tests/simpletest/test_case.php index f729d8f063..40c5cfb019 100755 --- a/tests/simpletest/test_case.php +++ b/tests/simpletest/test_case.php @@ -666,4 +666,4 @@ * @deprecated */ class BadGroupTest extends BadTestSuite { } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/unit_tester.php b/tests/simpletest/unit_tester.php index d690874f28..290d12410d 100755 --- a/tests/simpletest/unit_tester.php +++ b/tests/simpletest/unit_tester.php @@ -414,4 +414,4 @@ return $this->assertError(new PatternExpectation($pattern), $message); } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/url.php b/tests/simpletest/url.php index 87359cb5f7..8bbed36443 100755 --- a/tests/simpletest/url.php +++ b/tests/simpletest/url.php @@ -523,4 +523,4 @@ return 'com|edu|net|org|gov|mil|int|biz|info|name|pro|aero|coop|museum'; } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/user_agent.php b/tests/simpletest/user_agent.php index a5a6fd2087..1459a0c010 100755 --- a/tests/simpletest/user_agent.php +++ b/tests/simpletest/user_agent.php @@ -330,4 +330,4 @@ } } } -?>
\ No newline at end of file +?> diff --git a/tests/simpletest/web_tester.php b/tests/simpletest/web_tester.php index be424bb175..fc45eba628 100755 --- a/tests/simpletest/web_tester.php +++ b/tests/simpletest/web_tester.php @@ -1538,4 +1538,4 @@ return $trace->traceMethod(); } } -?>
\ No newline at end of file +?> diff --git a/tests/webtest/config/webtest.example.properties b/tests/webtest/config/webtest.example.properties index 470688723c..bc852706aa 100644 --- a/tests/webtest/config/webtest.example.properties +++ b/tests/webtest/config/webtest.example.properties @@ -1,44 +1,44 @@ -################################################
-# Test suite configuration file
-################################################
-
-### WebTests config
-wt.home=/usr/local/canoo
-wt.config.host=127.0.0.1
-wt.config.port=80
-wt.config.protocol=http
-wt.config.basepath=/piwik
-
-wt.config.failOnError=true
-wt.config.haltOnError=true
-wt.config.haltOnFailure=true
-wt.config.enableJS=true
-wt.config.throwExceptionOnScriptError=true
-wt.config.browser=Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
-wt.config.verifyLinks=true
-wt.config.verifyImages=true
-wt.config.headless=false
-#wt.openResultFile.skip=true
-
-## General settings
-testcase.dir=./testcases
-
-# patterns for each level
-testcase.level0.pattern=*.xml
-testcase.level1.pattern=*.xml
-testcase.level2.pattern=*.xml
-testcase.level3.pattern=*.xml
-screens=manual_results
-
-## To turn on/off specific level of tests just uncomment/comment appropriate line below
-test.level0=true
-test.level1=true
-#test.level2=true
-#test.level3=true
-
-## db settings
-db.username=username
-db.password=password
-db.port=3306
-db.name=piwik
-db.host=127.0.0.1
+################################################ +# Test suite configuration file +################################################ + +### WebTests config +wt.home=/usr/local/canoo +wt.config.host=127.0.0.1 +wt.config.port=80 +wt.config.protocol=http +wt.config.basepath=/piwik + +wt.config.failOnError=true +wt.config.haltOnError=true +wt.config.haltOnFailure=true +wt.config.enableJS=true +wt.config.throwExceptionOnScriptError=true +wt.config.browser=Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12 +wt.config.verifyLinks=true +wt.config.verifyImages=true +wt.config.headless=false +#wt.openResultFile.skip=true + +## General settings +testcase.dir=./testcases + +# patterns for each level +testcase.level0.pattern=*.xml +testcase.level1.pattern=*.xml +testcase.level2.pattern=*.xml +testcase.level3.pattern=*.xml +screens=manual_results + +## To turn on/off specific level of tests just uncomment/comment appropriate line below +test.level0=true +test.level1=true +#test.level2=true +#test.level3=true + +## db settings +db.username=username +db.password=password +db.port=3306 +db.name=piwik +db.host=127.0.0.1 diff --git a/tests/webtest/test_suite.xml b/tests/webtest/test_suite.xml index e2d86279f5..7efe10ed71 100644 --- a/tests/webtest/test_suite.xml +++ b/tests/webtest/test_suite.xml @@ -1,50 +1,50 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="Piwik" default="Level3" basedir=".">
-
- <target name="setup">
- <mkdir dir="${screens}" />
- </target>
-
- <target name="Level0" if="test.level0" depends="setup">
- <echo>Starting smoke tests...</echo>
- <subant failonerror="${wt.config.failOnError}" inheritall="true">
- <fileset dir="${testcase.dir}/level0" includes="${testcase.level0.pattern}"/>
- </subant>
- <echo>##################################</echo>
- <echo># 0 level smoke tests - FINISHED!#</echo>
- <echo>##################################</echo>
- </target>
-
- <target name="Level1" if="test.level1" depends="Level0">
- <echo>Starting setup tests...</echo>
- <subant failonerror="${wt.config.failOnError}" inheritall="true">
- <fileset dir="${testcase.dir}/level1" includes="${testcase.level1.pattern}"/>
- </subant>
- <echo>#################################</echo>
- <echo># 1st level tests - FINISHED! #</echo>
- <echo>#################################</echo>
- </target>
-
- <target name="Level2" if="test.level2" depends="Level1">
- <echo>Starting setup tests...</echo>
- <subant failonerror="${wt.config.failOnError}" inheritall="true">
- <fileset dir="${testcase.dir}/level2" includes="${testcase.level2.pattern}"/>
- </subant>
- <echo>###################################</echo>
- <echo># 2nd level test - FINISHED! #</echo>
- <echo>###################################</echo>
- </target>
-
- <target name="Level3" if="test.level3" depends="Level2">
- <echo>Starting UI tests - 3rd level...</echo>
- <echo>+-----------------------------------------+</echo>
- <echo>| WARNING! 3rd Level tests are optional |</echo>
- <echo>| and could fail without BUILD FAILED! |</echo>
- <echo>+-----------------------------------------+</echo>
- <subant failonerror="${wt.config.failOnError}" inheritall="true">
- <fileset dir="${testcase.dir}/level3" includes="${testcase.level3.pattern}"/>
- </subant>
- <echo>3rd level smoke tests finished - check for potential errors!</echo>
- </target>
-
+<project name="Piwik" default="Level3" basedir="."> + + <target name="setup"> + <mkdir dir="${screens}" /> + </target> + + <target name="Level0" if="test.level0" depends="setup"> + <echo>Starting smoke tests...</echo> + <subant failonerror="${wt.config.failOnError}" inheritall="true"> + <fileset dir="${testcase.dir}/level0" includes="${testcase.level0.pattern}"/> + </subant> + <echo>##################################</echo> + <echo># 0 level smoke tests - FINISHED!#</echo> + <echo>##################################</echo> + </target> + + <target name="Level1" if="test.level1" depends="Level0"> + <echo>Starting setup tests...</echo> + <subant failonerror="${wt.config.failOnError}" inheritall="true"> + <fileset dir="${testcase.dir}/level1" includes="${testcase.level1.pattern}"/> + </subant> + <echo>#################################</echo> + <echo># 1st level tests - FINISHED! #</echo> + <echo>#################################</echo> + </target> + + <target name="Level2" if="test.level2" depends="Level1"> + <echo>Starting setup tests...</echo> + <subant failonerror="${wt.config.failOnError}" inheritall="true"> + <fileset dir="${testcase.dir}/level2" includes="${testcase.level2.pattern}"/> + </subant> + <echo>###################################</echo> + <echo># 2nd level test - FINISHED! #</echo> + <echo>###################################</echo> + </target> + + <target name="Level3" if="test.level3" depends="Level2"> + <echo>Starting UI tests - 3rd level...</echo> + <echo>+-----------------------------------------+</echo> + <echo>| WARNING! 3rd Level tests are optional |</echo> + <echo>| and could fail without BUILD FAILED! |</echo> + <echo>+-----------------------------------------+</echo> + <subant failonerror="${wt.config.failOnError}" inheritall="true"> + <fileset dir="${testcase.dir}/level3" includes="${testcase.level3.pattern}"/> + </subant> + <echo>3rd level smoke tests finished - check for potential errors!</echo> + </target> + </project> diff --git a/tests/webtest/testcases/level0/test.piwik.index.xml b/tests/webtest/testcases/level0/test.piwik.index.xml index 0752307202..eaff6d2cfb 100644 --- a/tests/webtest/testcases/level0/test.piwik.index.xml +++ b/tests/webtest/testcases/level0/test.piwik.index.xml @@ -1,194 +1,194 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE project [
- <!ENTITY time SYSTEM "../modules/time.xml">
- <!ENTITY checkForErrors SYSTEM "../modules/errors.xml">
- <!ENTITY verifyLinksAndImages SYSTEM "../modules/common_pages.xml">
- <!ENTITY raquo "»">
- <!ENTITY rsaquo "›" >
-]>
-
-<project name="Smoke test level0 - deploy test" basedir="." default="webtest">
- &time;
- <target name="webtest">
- <webtest name="install index">
- <steps>
-
- <echo>Piwik install - dbsetup: db.name: ${db.name}</echo>
- <sql
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://${db.host}:${db.port}/"
- userid="${db.username}"
- password="${db.password}"
- >
- <classpath>
- <pathelement location="${basedir}/../lib/java/mysql-connector-java-5.1.7.jar" />
- </classpath>
- <transaction>
- DROP DATABASE IF EXISTS ${db.name};
- </transaction>
- <transaction>
- CREATE DATABASE IF NOT EXISTS ${db.name};
- </transaction>
- </sql>
-
- <invoke description="get account index" url="/" />
-
- <!-- 1. welcome -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Welcome!" />
- <verifyText description="check page text" text="This process is split up into 8 easy steps and will take around 5 minutes" />
- &checkForErrors;
- &verifyLinksAndImages;
-
- <clickLink description="click 'Next'" label="Next »" />
-
- <!-- 2. systemCheck -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="System check" />
- <verifyText description="check page text" text="Optional" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <not description="check if system check passed">
- <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error.png']"/>
- </not>
-
- <verifyXPath description="looking for ok image" xpath="//img[@src='themes/default/images/ok.png']"/>
-
- <clickLink description="click 'Next'" label="Next »" />
-
- <!-- 3. databaseSetup -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Mysql database setup" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <setInputField description="set database host (and port)" name="host" value="${db.host}:${db.port}" />
- <setInputField description="set database username" name="username" value="${db.username}" />
- <setInputField description="set database password" name="password" value="${db.password}" />
- <setInputField description="set database name" name="dbname" value="${db.name}" />
- <setInputField description="set database port" name="tables_prefix" value="canoo_" />
-
- <clickButton description="click 'Go!' button" label="Go!"/>
-
- <!-- 4. tablesCreation -->
-
- <not description="check if no error">
- <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/>
- </not>
-
- <not description="check if no warning">
- <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/>
- </not>
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Tables created with success!" />
- <verifyXPath description="looking for success image" xpath="//img[@src='themes/default/images/success_medium.png']"/>
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <clickLink description="click 'Next'" label="Next »" />
-
- <!-- 5. generalSetup -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="General Setup" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <setInputField description="set Piwik login" name="login" value="piwik_login" />
- <setInputField description="set Piwik password" name="password" value="piwik_password" />
- <setInputField description="set repeated Piwik password" name="password_bis" value="piwik_password" />
- <setInputField description="set Piwik email" name="email" value="nobody@piwik.org" />
-
- <clickButton description="click 'Go!' button" label="Go!"/>
-
- <!-- 6. firstWebsiteSetup -->
-
- <not description="check if no error">
- <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/>
- </not>
-
- <not description="check if no warning">
- <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/>
- </not>
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Setup a website" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <setInputField description="set Piwik site name" name="siteName" value="Dummy Site Name" />
- <setInputField description="set Piwik URL" name="url" value="${wt.config.protocol}://${wt.config.host}:${wt.config.port}${wt.config.basepath}" />
-
- <clickButton description="click 'Go!' button" label="Go!"/>
-
- <!-- 7. displayJavascriptCode -->
-
- <not description="check if no error">
- <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/>
- </not>
-
- <not description="check if no warning">
- <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/>
- </not>
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Javascript tag" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <clickLink description="click 'Next'" label="Next »" />
-
- <!-- 8. finished -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Congratulations" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <clickLink description="click 'Continue to Piwik'" label="Continue to Piwik »" />
-
- <!-- logging in -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik › Login" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Lost your password?" />
-
- &checkForErrors;
- &verifyLinksAndImages;
-
- <setInputField description="set Piwik login" htmlId="form_login" value="piwik_login" />
- <setInputField description="set Piwik password" htmlId="form_password" value="piwik_password" />
- <clickButton description="click 'Sign in' button" label="Sign in"/>
-
- <!-- logged in -->
-
- <verifyTitle description="check the title is parsed correctly" text="Piwik › Web Analytics Reports" />
- <verifyText description="check page text" text="Piwik" />
- <verifyText description="check page text" text="Your Dashboard" />
- <verifyText description="check page text" text="Hello" />
-
- </steps>
- </webtest>
- </target>
-</project>
+<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE project [ + <!ENTITY time SYSTEM "../modules/time.xml"> + <!ENTITY checkForErrors SYSTEM "../modules/errors.xml"> + <!ENTITY verifyLinksAndImages SYSTEM "../modules/common_pages.xml"> + <!ENTITY raquo "»"> + <!ENTITY rsaquo "›" > +]> + +<project name="Smoke test level0 - deploy test" basedir="." default="webtest"> + &time; + <target name="webtest"> + <webtest name="install index"> + <steps> + + <echo>Piwik install - dbsetup: db.name: ${db.name}</echo> + <sql + driver="com.mysql.jdbc.Driver" + url="jdbc:mysql://${db.host}:${db.port}/" + userid="${db.username}" + password="${db.password}" + > + <classpath> + <pathelement location="${basedir}/../lib/java/mysql-connector-java-5.1.7.jar" /> + </classpath> + <transaction> + DROP DATABASE IF EXISTS ${db.name}; + </transaction> + <transaction> + CREATE DATABASE IF NOT EXISTS ${db.name}; + </transaction> + </sql> + + <invoke description="get account index" url="/" /> + + <!-- 1. welcome --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Welcome!" /> + <verifyText description="check page text" text="This process is split up into 8 easy steps and will take around 5 minutes" /> + &checkForErrors; + &verifyLinksAndImages; + + <clickLink description="click 'Next'" label="Next »" /> + + <!-- 2. systemCheck --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="System check" /> + <verifyText description="check page text" text="Optional" /> + + &checkForErrors; + &verifyLinksAndImages; + + <not description="check if system check passed"> + <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error.png']"/> + </not> + + <verifyXPath description="looking for ok image" xpath="//img[@src='themes/default/images/ok.png']"/> + + <clickLink description="click 'Next'" label="Next »" /> + + <!-- 3. databaseSetup --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Mysql database setup" /> + + &checkForErrors; + &verifyLinksAndImages; + + <setInputField description="set database host (and port)" name="host" value="${db.host}:${db.port}" /> + <setInputField description="set database username" name="username" value="${db.username}" /> + <setInputField description="set database password" name="password" value="${db.password}" /> + <setInputField description="set database name" name="dbname" value="${db.name}" /> + <setInputField description="set database port" name="tables_prefix" value="canoo_" /> + + <clickButton description="click 'Go!' button" label="Go!"/> + + <!-- 4. tablesCreation --> + + <not description="check if no error"> + <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/> + </not> + + <not description="check if no warning"> + <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/> + </not> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Tables created with success!" /> + <verifyXPath description="looking for success image" xpath="//img[@src='themes/default/images/success_medium.png']"/> + + &checkForErrors; + &verifyLinksAndImages; + + <clickLink description="click 'Next'" label="Next »" /> + + <!-- 5. generalSetup --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="General Setup" /> + + &checkForErrors; + &verifyLinksAndImages; + + <setInputField description="set Piwik login" name="login" value="piwik_login" /> + <setInputField description="set Piwik password" name="password" value="piwik_password" /> + <setInputField description="set repeated Piwik password" name="password_bis" value="piwik_password" /> + <setInputField description="set Piwik email" name="email" value="nobody@piwik.org" /> + + <clickButton description="click 'Go!' button" label="Go!"/> + + <!-- 6. firstWebsiteSetup --> + + <not description="check if no error"> + <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/> + </not> + + <not description="check if no warning"> + <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/> + </not> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Setup a website" /> + + &checkForErrors; + &verifyLinksAndImages; + + <setInputField description="set Piwik site name" name="siteName" value="Dummy Site Name" /> + <setInputField description="set Piwik URL" name="url" value="${wt.config.protocol}://${wt.config.host}:${wt.config.port}${wt.config.basepath}" /> + + <clickButton description="click 'Go!' button" label="Go!"/> + + <!-- 7. displayJavascriptCode --> + + <not description="check if no error"> + <verifyXPath description="looking for error image" xpath="//img[@src='themes/default/images/error_medium.png']"/> + </not> + + <not description="check if no warning"> + <verifyXPath description="looking for warning image" xpath="//img[@src='themes/default/images/warning_medium.png']"/> + </not> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Javascript tag" /> + + &checkForErrors; + &verifyLinksAndImages; + + <clickLink description="click 'Next'" label="Next »" /> + + <!-- 8. finished --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik » Installation" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Congratulations" /> + + &checkForErrors; + &verifyLinksAndImages; + + <clickLink description="click 'Continue to Piwik'" label="Continue to Piwik »" /> + + <!-- logging in --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik › Login" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Lost your password?" /> + + &checkForErrors; + &verifyLinksAndImages; + + <setInputField description="set Piwik login" htmlId="form_login" value="piwik_login" /> + <setInputField description="set Piwik password" htmlId="form_password" value="piwik_password" /> + <clickButton description="click 'Sign in' button" label="Sign in"/> + + <!-- logged in --> + + <verifyTitle description="check the title is parsed correctly" text="Piwik › Web Analytics Reports" /> + <verifyText description="check page text" text="Piwik" /> + <verifyText description="check page text" text="Your Dashboard" /> + <verifyText description="check page text" text="Hello" /> + + </steps> + </webtest> + </target> +</project> diff --git a/tests/webtest/testcases/modules/common_pages.xml b/tests/webtest/testcases/modules/common_pages.xml index 7ef4e4cbcb..bf888b61d8 100644 --- a/tests/webtest/testcases/modules/common_pages.xml +++ b/tests/webtest/testcases/modules/common_pages.xml @@ -1,8 +1,8 @@ - <enableJavaScript description="Disable JS verification for external resources" enable="false" />
- <ifStep description="production tests" test="${wt.config.verifyLinks}">
- <verifyLinks />
- </ifStep>
- <ifStep description="production tests" test="${wt.config.verifyImages}">
- <verifyImages />
- </ifStep>
- <enableJavaScript description="Turn back JS verification for further testing" enable="true" />
\ No newline at end of file + <enableJavaScript description="Disable JS verification for external resources" enable="false" /> + <ifStep description="production tests" test="${wt.config.verifyLinks}"> + <verifyLinks /> + </ifStep> + <ifStep description="production tests" test="${wt.config.verifyImages}"> + <verifyImages /> + </ifStep> + <enableJavaScript description="Turn back JS verification for further testing" enable="true" /> diff --git a/tests/webtest/testcases/modules/errors.xml b/tests/webtest/testcases/modules/errors.xml index b348cb3a4d..16ef77e1e2 100644 --- a/tests/webtest/testcases/modules/errors.xml +++ b/tests/webtest/testcases/modules/errors.xml @@ -1,6 +1,6 @@ <not description="There should be no errors and no notices on output page"> - <verifyText description="Check errors" text="error:" />
+ <verifyText description="Check errors" text="error:" /> <verifyText description="Check errors" text="Fatal error" /> <verifyText description="Check notices" text="Notice" /> <verifyText description="Check warnings" text="Warning" /> -</not>
\ No newline at end of file +</not> diff --git a/tests/webtest/testcases/modules/time.xml b/tests/webtest/testcases/modules/time.xml index 7374446eab..d910a565d2 100644 --- a/tests/webtest/testcases/modules/time.xml +++ b/tests/webtest/testcases/modules/time.xml @@ -1,15 +1,15 @@ - <tstamp>
- <format property="today.plus.one" pattern="yyyy-MM-dd"
- offset="1" unit="day" />
- </tstamp>
- <tstamp>
- <format property="today.plus.three" pattern="yyyy-MM-dd"
- offset="3" unit="day" />
- </tstamp>
- <tstamp>
- <format property="unique" pattern="yyMMddHHmmssS" />
- </tstamp>
- <tstamp>
- <format property="today.minus.two" pattern="yyyy-MM-dd"
- offset="-2" unit="day" />
- </tstamp>
\ No newline at end of file + <tstamp> + <format property="today.plus.one" pattern="yyyy-MM-dd" + offset="1" unit="day" /> + </tstamp> + <tstamp> + <format property="today.plus.three" pattern="yyyy-MM-dd" + offset="3" unit="day" /> + </tstamp> + <tstamp> + <format property="unique" pattern="yyMMddHHmmssS" /> + </tstamp> + <tstamp> + <format property="today.minus.two" pattern="yyyy-MM-dd" + offset="-2" unit="day" /> + </tstamp> diff --git a/themes/default/common.css b/themes/default/common.css index d2123e4753..ab63b172b5 100644 --- a/themes/default/common.css +++ b/themes/default/common.css @@ -193,4 +193,4 @@ a { border: 3px solid red; margin: 10px; padding: 10px; -}
\ No newline at end of file +} diff --git a/themes/default/simple_structure_footer.tpl b/themes/default/simple_structure_footer.tpl index 17c7245b64..9943ff0f85 100644 --- a/themes/default/simple_structure_footer.tpl +++ b/themes/default/simple_structure_footer.tpl @@ -1,3 +1,3 @@ </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/themes/default/simple_structure_header.tpl b/themes/default/simple_structure_header.tpl index 546db40bf9..7ef4006234 100644 --- a/themes/default/simple_structure_header.tpl +++ b/themes/default/simple_structure_header.tpl @@ -8,4 +8,4 @@ <body> <div id="content"> <div id="title"><span id="h1">Piwik </span><span id="subh1"> # open source web analytics</span></div> -
\ No newline at end of file + |