From bf3c09bec66ef05c06b6e8f3a17c2387b09bd90e Mon Sep 17 00:00:00 2001 From: Geoff Munn Date: Mon, 25 Feb 2008 01:06:39 +0000 Subject: [PATCH] First post git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@50105 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 5 +- api/RSSFeed.php | 23 +- api/RestfulService.php | 117 +- api/SapphireSoapServer.php | 10 - api/SimplePie.php | 72 +- api/Spyc.php | 1627 ++-- cli-script.php | 60 +- cli/CliController.php | 12 +- cli/DailyTask.php | 7 - cli/MonthlyTask.php | 10 +- cli/ScheduledTask.php | 10 - cli/WeeklyTask.php | 11 - core/ArrayData.php | 49 +- core/ArrayLib.php | 51 - core/ClassInfo.php | 37 +- core/Convert.php | 43 +- core/Cookie.php | 10 - core/Core.php | 7 - core/Debug.php | 129 +- core/Email.php | 59 +- core/Extension.php | 9 +- core/HTTP.php | 9 - core/ManifestBuilder.php | 287 +- core/Object.php | 129 +- core/Requirements.php | 51 +- core/SSViewer.php | 17 +- core/Session.php | 48 +- core/ViewableData.php | 68 +- core/control/ContentController.php | 29 +- core/control/ContentNegotiator.php | 37 +- core/control/Controller.php | 103 +- core/control/Director.php | 164 +- core/control/FormResponse.php | 17 +- core/control/HTTPResponse.php | 8 - core/control/ModelAsController.php | 7 - core/control/NestedController.php | 12 - core/control/RootURLController.php | 10 +- core/i18n.php | 36 +- core/model/ComponentSet.php | 14 +- core/model/CurrentPageIdentifier.php | 4 +- core/model/DB.php | 27 +- core/model/DataObject.php | 342 +- core/model/DataObjectDecorator.php | 4 +- core/model/DataObjectLog.php | 4 +- core/model/DataObjectSet.php | 60 +- core/model/Database.php | 54 +- core/model/DatabaseAdmin.php | 12 +- core/model/ErrorPage.php | 34 +- core/model/GhostPage.php | 6 +- core/model/HiddenClass.php | 4 +- core/model/Hierarchy.php | 10 +- core/model/Image.php | 64 +- core/model/MySQLDatabase.php | 16 +- core/model/PDODatabase.php | 77 +- core/model/PageView.php | 87 +- core/model/PostgreSQLDatabase.php | 497 + core/model/RedirectorPage.php | 16 +- core/model/SQLMap.php | 7 - core/model/SQLQuery.php | 7 - core/model/SiteTree.php | 86 +- core/model/Staged.php | 7 + core/model/Translatable.php | 20 +- core/model/Versioned.php | 28 +- core/model/VirtualPage.php | 9 +- core/model/fieldtypes/Boolean.php | 10 +- core/model/fieldtypes/Currency.php | 10 +- core/model/fieldtypes/DBField.php | 25 +- core/model/fieldtypes/Date.php | 52 +- core/model/fieldtypes/Datetime.php | 14 - core/model/fieldtypes/Decimal.php | 19 +- core/model/fieldtypes/Enum.php | 10 - core/model/fieldtypes/Float.php | 10 +- core/model/fieldtypes/HTMLText.php | 22 +- core/model/fieldtypes/HTMLVarchar.php | 12 +- core/model/fieldtypes/Int.php | 15 +- core/model/fieldtypes/Percentage.php | 10 - core/model/fieldtypes/SSDatetime.php | 11 - core/model/fieldtypes/Text.php | 71 - core/model/fieldtypes/Time.php | 9 +- core/model/fieldtypes/Varchar.php | 10 - css/ComplexTableField_popup.css | 11 - css/DropdownTimeField.css | 3 - css/TableListField.css | 4 - email/Notifications.php | 5 - email/QueuedEmail.php | 8 - email/QueuedEmailDispatchTask.php | 11 - filesystem/Archive.php | 14 - filesystem/File.php | 80 +- filesystem/Filesystem.php | 10 - filesystem/Folder.php | 107 +- filesystem/GD.php | 7 - filesystem/PostBackup.php | 8 - filesystem/TarballArchive.php | 10 - forms/editor/FieldEditor.php | 19 +- integration/XML.php | 7 - javascript/CalendarDateField.js | 4 - javascript/ComplexTableField_popup.js | 37 +- javascript/RelationComplexTableField.js | 21 +- javascript/TableListField.js | 6 +- javascript/Validator.js | 14 +- lang/bg_BG.php | 6 +- lang/cs_CZ.php | 6 +- lang/de_DE.php | 6 +- lang/en_US.php | 49 +- lang/es_ES.php | 6 +- lang/fr_FR.php | 8 +- lang/hr_HR.php | 17 +- lang/hu_HU.php | 6 +- lang/it_IT.php | 6 +- lang/nl_NL.php | 6 +- lang/pl_PL.php | 43 +- lang/pt_BR.php | 6 +- lang/pt_PT.php | 393 +- lang/ru_RU.php | 6 +- lang/sk_SK.php | 6 +- lang/sv_SE.php | 9 +- lang/tr_TR.php | 6 +- lang/zh_CN.php | 6 +- lang/zh_TW.php | 6 +- main.php | 71 +- main.php5 | 7 - misc/Browscap.php | 15 +- misc/GoogleSitemap.php | 9 +- misc/IPS.php | 7 - misc/Statistics.php | 56 +- misc/browscap.ini | 8601 ++++++++++++++++- parsers/HTML/BBCodeParser/Filter.php | 13 +- parsers/HTML/BBCodeParser/Filter/Basic.php | 15 +- .../HTML/BBCodeParser/Filter/EmailLinks.php | 13 +- parsers/HTML/BBCodeParser/Filter/Extended.php | 15 +- parsers/HTML/BBCodeParser/Filter/Images.php | 14 +- parsers/HTML/BBCodeParser/Filter/Links.php | 13 +- parsers/HTML/BBCodeParser/Filter/Lists.php | 12 +- parsers/HTML/HTMLBBCodeParser.php | 74 +- profiler/Profiler.php | 12 - search/AdvancedSearchForm.php | 36 +- search/SearchForm.php | 15 +- security/Authenticator.php | 8 - security/BasicAuth.php | 14 +- security/ChangePasswordForm.php | 8 +- security/Geoip.php | 38 +- security/Group.php | 36 - security/LoginForm.php | 8 +- security/Member.php | 119 +- security/MemberAuthenticator.php | 8 +- security/MemberLoginForm.php | 23 +- security/Permission.php | 21 +- security/PermissionDropdownField.php | 8 +- security/PermissionProvider.php | 7 - security/Security.php | 57 +- synchronise/Synchronise.php | 11 - synchronise/Synchronised.php | 8 - .../Includes/TableListField_PageControls.ss | 18 +- templates/email/ChangePasswordEmail.ss | 2 +- templates/email/ForgotPasswordEmail.ss | 2 +- tests/InstallerTest.php | 9 + tests/SapphireTest.php | 170 + tests/SiteTreeTest.php | 7 - tests/TestRunner.php | 68 + tools/importer.php | 11 +- widgets/Widget.php | 11 - widgets/WidgetArea.php | 10 - 162 files changed, 11107 insertions(+), 4752 deletions(-) create mode 100644 core/model/PostgreSQLDatabase.php create mode 100755 core/model/Staged.php create mode 100755 tests/InstallerTest.php create mode 100755 tests/SapphireTest.php create mode 100755 tests/TestRunner.php diff --git a/_config.php b/_config.php index 86dbfe158..211048e54 100644 --- a/_config.php +++ b/_config.php @@ -12,11 +12,10 @@ * * Authenticator::register_authenticator('OpenIDAuthenticator'); * - * - * @package sapphire - * @subpackage core */ + + /** * Add pear parser to include path */ diff --git a/api/RSSFeed.php b/api/RSSFeed.php index ecf05c942..8470e7304 100755 --- a/api/RSSFeed.php +++ b/api/RSSFeed.php @@ -1,26 +1,10 @@ "Varchar", - "Description" => "Varchar", - ); /** * Holds the feed entries @@ -65,7 +49,7 @@ class RSSFeed extends ViewableData { protected $descriptionField; /** - * Name of the author field of feed entries + Name of the author field of feed entries * * @var string */ @@ -201,10 +185,9 @@ class RSSFeed extends ViewableData { * This class is used for entries of an RSS feed. * * @see RSSFeed - * @package sapphire - * @subpackage integration */ class RSSFeed_Entry extends ViewableData { + /** * The object that represents the item, it contains all the data. * @@ -227,7 +210,7 @@ class RSSFeed_Entry extends ViewableData { protected $descriptionField; /** - * Name of the author field of feed entries + Name of the author field of feed entries * * @var string */ diff --git a/api/RestfulService.php b/api/RestfulService.php index c74308735..31d730fae 100644 --- a/api/RestfulService.php +++ b/api/RestfulService.php @@ -1,16 +1,8 @@ baseURL = $base; $this->cache_expire = $expiry; @@ -32,7 +19,7 @@ class RestfulService extends ViewableData { /** * Sets the Query string parameters to send a request. - * @param array $params An array passed with necessary parameters. + * @param params An array passed with necessary parameters. */ function setQueryString($params=NULL){ $this->queryString = http_build_query($params,'','&'); @@ -44,66 +31,59 @@ class RestfulService extends ViewableData { /** * Connects to the RESTful service and gets its response. - * @todo implement authentication via cURL for + * TODO implement authentication via cURL for */ function connect(){ - $url = $this->constructURL(); //url for the request + $url = $this->constructURL(); // url for the request - //check for file exists in cache - //set the cache directory - $cachedir=TEMP_FOLDER; //default silverstrip-cache + // check for file exists in cache + // set the cache directory + $cachedir = TEMP_FOLDER; // default silverstripe-cache - $cache_file = md5($url); //encoded name of cache file - $cache_path = $cachedir."/$cache_file"; + $cache_file = md5($url); // encoded name of cache file + $cache_path = $cachedir . "/$cache_file"; - if(( @file_exists("$cache_path") && ((@filemtime($cache_path) + $this->cache_expire) > ( time() )))){ + if((@file_exists("$cache_path") && ((@filemtime($cache_path) + $this->cache_expire) > (time())))){ $this->rawXML = file_get_contents($cache_path); - } - else {//not available in cache fetch from server - + } else { + // not available in cache fetch from server $ch = curl_init(); $timeout = 5; - $useragent = "SilverStripe/2.2"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_USERAGENT, $useragent); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); $this->rawXML = curl_exec($ch); curl_close($ch); - + // save the response in cache + $fp = @fopen($cache_path,"w+"); + @fwrite($fp,$this->rawXML); + @fclose($fp); } - //Try using file_get_contents if cURL is not installed in your system. - //$this->rawXML = file_get_contents($url); + // Try using file_get_contents if cURL is not installed in your system. + // $this->rawXML = file_get_contents($url); - //results returned - from cache / live + // results returned - from cache / live if($this->rawXML != ""){ - //save the response in cache - $fp = @fopen($cache_path,"w+"); - @fwrite($fp,$this->rawXML); - @fclose($fp); - if($this->checkErrors == true) { return $this->errorCatch($this->rawXML); - } - else { + } else { return $this->rawXML; } - } - else { + } else { user_error("Invalid Response (maybe your calling to wrong URL or server unavailable)", E_USER_ERROR); - } } + } /** * Gets attributes as an array, of a particular type of element. + * @params xml - the source xml to parse, this could be the original response received. + * @params collection - parent node which wraps the elements, if available + * @params element - element we need to extract the attributes. * Example : * returns id, owner,secret and sever attribute values of all such photo elements. - * @param string $xml The source xml to parse, this could be the original response received. - * @param string $collection The name of parent node which wraps the elements, if available - * @param string $element The element we need to extract the attributes. */ function getAttributes($xml, $collection=NULL, $element=NULL){ @@ -131,10 +111,10 @@ class RestfulService extends ViewableData { /** * Gets an attribute of a particular element. - * @param string $xml The source xml to parse, this could be the original response received. - * @param string $collection The name of the parent node which wraps the element, if available - * @param string $element The element we need to extract the attribute - * @param string $attr The name of the attribute + * @params xml - the source xml to parse, this could be the original response received. + * @params collection - parent node which wraps the element, if available + * @params element - element we need to extract the attribute + * @params attr - name of the attribute */ function getAttribute($xml, $collection=NULL, $element=NULL, $attr){ @@ -156,9 +136,9 @@ class RestfulService extends ViewableData { /** * Gets set of node values as an array. * When you get to the depth in the hierachchy use node_child_subchild syntax to get the value. - * @param string $xml The the source xml to parse, this could be the original response received. - * @param string $collection The name of parent node which wraps the elements, if available - * @param string $element The element we need to extract the node values. + * @params xml - the source xml to parse, this could be the original response received. + * @params collection - parent node which wraps the elements, if available + * @params element - element we need to extract the node values. */ function getValues($xml, $collection=NULL, $element=NULL){ @@ -182,24 +162,13 @@ class RestfulService extends ViewableData { } protected function getRecurseValues($xml,&$data,$parent=""){ - $conv_value = ""; $child_count = 0; foreach($xml as $key=>$value) { $child_count++; $k = ($parent == "") ? (string)$key : $parent . "_" . (string)$key; - if($this->getRecurseValues($value,$data,$k) == 0){ // no childern, aka "leaf node" - $conv_value = Convert::raw2xml($value); - } - //Review the fix for similar node names overriding it's predecessor - if(array_key_exists($k, $data) == true) { - $data[$k] = $data[$k] . ",". $conv_value; - } - else { - $data[$k] = $conv_value; - } - - + if($this->getRecurseValues($value,$data,$k) == 0) // no childern, aka "leaf node" + $data[$k] = Convert::raw2xml($value); } return $child_count; @@ -207,9 +176,9 @@ class RestfulService extends ViewableData { /** * Gets a single node value. - * @param string $xml The source xml to parse, this could be the original response received. - * @param string $collection The name of parent node which wraps the elements, if available - * @param string $element The element we need to extract the node value. + * @params xml - the source xml to parse, this could be the original response received. + * @params collection - parent node which wraps the elements, if available + * @params element - element we need to extract the node value. */ function getValue($xml, $collection=NULL, $element=NULL){ @@ -224,11 +193,6 @@ class RestfulService extends ViewableData { return Convert::raw2xml($childElements); } - /** - * Searches for a node in document tree and returns it value. - * @param string $xml source xml to parse, this could be the original response received. - * @param string $node Node to search for - */ function searchValue($xml, $node=NULL){ $xml = new SimpleXMLElement($xml); $childElements = $xml->xpath($node); @@ -237,11 +201,6 @@ class RestfulService extends ViewableData { return Convert::raw2xml($childElements[0]); } - /** - * Searches for a node in document tree and returns its attributes. - * @param string $xml the source xml to parse, this could be the original response received. - * @param string $node Node to search for - */ function searchAttributes($xml, $node=NULL){ $xml = new SimpleXMLElement($xml); $output = new DataObjectSet(); @@ -257,10 +216,12 @@ class RestfulService extends ViewableData { $output->push(new ArrayData($data)); } + + //Debug::show($attr_value); return $output; } } -?> \ No newline at end of file +?> diff --git a/api/SapphireSoapServer.php b/api/SapphireSoapServer.php index e851d7f41..f00f4635c 100755 --- a/api/SapphireSoapServer.php +++ b/api/SapphireSoapServer.php @@ -1,15 +1,5 @@ - * @author Vlad Andersen - * @link http://spyc.sourceforge.net/ - * @copyright Copyright 2005-2006 Chris Wanstrath - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package sapphire - * @subpackage misc - */ - -/** - * A node, used by Spyc for parsing YAML. - * @package sapphire - * @subpackage misc - */ -class YAMLNode { - /**#@+ - * @access public - * @var string - */ - public $parent; - public $id; - /**#@-*/ /** - * @access public - * @var mixed + * Spyc -- A Simple PHP YAML Class + * @version 0.2.(5) -- 2006-12-31 + * @author Chris Wanstrath + * @author Vlad Andersen + * @link http://spyc.sourceforge.net/ + * @copyright Copyright 2005-2006 Chris Wanstrath + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc */ - public $data; - /** - * @access public - * @var int - */ - public $indent; - /** - * @access public - * @var bool - */ - public $children = false; /** - * The constructor assigns the node a unique ID. - * @access public - * @return void + * A node, used by Spyc for parsing YAML. + * @package Spyc */ - public function YAMLNode($nodeId) { - $this->id = $nodeId; - } -} + class YAMLNode { + /**#@+ + * @access public + * @var string + */ + public $parent; + public $id; + /**#@+*/ + /** + * @access public + * @var mixed + */ + public $data; + /** + * @access public + * @var int + */ + public $indent; + /** + * @access public + * @var bool + */ + public $children = false; -/** - * The Simple PHP YAML Class. - * - * This class can be used to read a YAML file and convert its contents - * into a PHP array. It currently supports a very limited subsection of - * the YAML spec. - * - * Usage: - * - * $parser = new Spyc; - * $array = $parser->load($file); - * - * @package sapphire - * @subpackage misc - */ -class Spyc { - - /** - * Load YAML into a PHP array statically - * - * The load method, when supplied with a YAML stream (string or file), - * will do its best to convert YAML in a file into a PHP array. Pretty - * simple. - * Usage: - * - * $array = Spyc::YAMLLoad('lucky.yaml'); - * print_r($array); - * - * @access public - * @return array - * @param string $input Path of YAML file or string containing YAML - */ - public static function YAMLLoad($input) { - $spyc = new Spyc; - return $spyc->load($input); + /** + * The constructor assigns the node a unique ID. + * @access public + * @return void + */ + public function YAMLNode($nodeId) { + $this->id = $nodeId; + } } /** - * Dump YAML from PHP array statically + * The Simple PHP YAML Class. * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as nothing.yaml and pass it around. + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public static function YAMLDump($array,$indent = false,$wordwrap = false) { - $spyc = new Spyc; - return $spyc->dump($array,$indent,$wordwrap); - } - - /** - * Load YAML into a PHP array from an instantiated object - * - * The load method, when supplied with a YAML stream (string or file path), - * will do its best to convert the YAML into a PHP array. Pretty simple. - * Usage: - * + * Usage: + * * $parser = new Spyc; - * $array = $parser->load('lucky.yaml'); - * print_r($array); - * - * @access public - * @return array - * @param string $input Path of YAML file or string containing YAML + * $array = $parser->load($file); + * + * @package Spyc */ - public function load($input) { - // See what type of input we're talking about - // If it's not a file, assume it's a string - if (!empty($input) && (strpos($input, "\n") === false) - && file_exists($input)) { - $yaml = file($input); - } else { - $yaml = explode("\n",$input); + class Spyc { + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * + * $array = Spyc::YAMLLoad('lucky.yaml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public static function YAMLLoad($input) { + $spyc = new Spyc; + return $spyc->load($input); } - // Initiate some objects and values - $base = new YAMLNode (1); - $base->indent = 0; - $this->_lastIndent = 0; - $this->_lastNode = $base->id; - $this->_inBlock = false; - $this->_isInline = false; - $this->_nodeId = 2; - foreach ($yaml as $linenum => $line) { - $ifchk = trim($line); + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public static function YAMLDump($array,$indent = false,$wordwrap = false) { + $spyc = new Spyc; + return $spyc->dump($array,$indent,$wordwrap); + } - // If the line starts with a tab (instead of a space), throw a fit. - if (preg_match('/^(\t)+(\w+)/', $line)) { - $err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'. - ' with a tab. YAML only recognizes spaces. Please reformat.'; - die($err); + /** + * Load YAML into a PHP array from an instantiated object + * + * The load method, when supplied with a YAML stream (string or file path), + * will do its best to convert the YAML into a PHP array. Pretty simple. + * Usage: + * + * $parser = new Spyc; + * $array = $parser->load('lucky.yaml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public function load($input) { + // See what type of input we're talking about + // If it's not a file, assume it's a string + if (!empty($input) && (strpos($input, "\n") === false) + && file_exists($input)) { + $yaml = file($input); + } else { + $yaml = explode("\n",$input); } + // Initiate some objects and values + $base = new YAMLNode (1); + $base->indent = 0; + $this->_lastIndent = 0; + $this->_lastNode = $base->id; + $this->_inBlock = false; + $this->_isInline = false; + $this->_nodeId = 2; - if ($this->_inBlock === false && empty($ifchk)) { - continue; - } elseif ($this->_inBlock == true && empty($ifchk)) { - $last =& $this->_allNodes[$this->_lastNode]; - $last->data[key($last->data)] .= "\n"; - } elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') { - // Create a new node and get its indent - $node = new YAMLNode ($this->_nodeId); - $this->_nodeId++; - $node->indent = $this->_getIndent($line); + foreach ($yaml as $linenum => $line) { + $ifchk = trim($line); - // Check where the node lies in the hierarchy - if ($this->_lastIndent == $node->indent) { - // If we're in a block, add the text to the parent's data - if ($this->_inBlock === true) { - $parent =& $this->_allNodes[$this->_lastNode]; - $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; - } else { - // The current node's parent is the same as the previous node's - if (isset($this->_allNodes[$this->_lastNode])) { - $node->parent = $this->_allNodes[$this->_lastNode]->parent; + // If the line starts with a tab (instead of a space), throw a fit. + if (preg_match('/^(\t)+(\w+)/', $line)) { + $err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'. + ' with a tab. YAML only recognizes spaces. Please reformat.'; + die($err); + } + + if ($this->_inBlock === false && empty($ifchk)) { + continue; + } elseif ($this->_inBlock == true && empty($ifchk)) { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] .= "\n"; + } elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') { + // Create a new node and get its indent + $node = new YAMLNode ($this->_nodeId); + $this->_nodeId++; + $node->indent = $this->_getIndent($line); + + // Check where the node lies in the hierarchy + if ($this->_lastIndent == $node->indent) { + // If we're in a block, add the text to the parent's data + if ($this->_inBlock === true) { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; + } else { + // The current node's parent is the same as the previous node's + if (isset($this->_allNodes[$this->_lastNode])) { + $node->parent = $this->_allNodes[$this->_lastNode]->parent; + } } - } - } elseif ($this->_lastIndent < $node->indent) { - if ($this->_inBlock === true) { - $parent =& $this->_allNodes[$this->_lastNode]; - $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; - } elseif ($this->_inBlock === false) { - // The current node's parent is the previous node - $node->parent = $this->_lastNode; + } elseif ($this->_lastIndent < $node->indent) { + if ($this->_inBlock === true) { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; + } elseif ($this->_inBlock === false) { + // The current node's parent is the previous node + $node->parent = $this->_lastNode; - // If the value of the last node's data was > or | we need to - // start blocking i.e. taking in all lines as a text value until - // we drop our indent. - $parent =& $this->_allNodes[$node->parent]; - $this->_allNodes[$node->parent]->children = true; - if (is_array($parent->data)) { - // if (isset ($parent->data[key($parent->data)])) - $chk = $parent->data[key($parent->data)]; - if ($chk === '>') { - $this->_inBlock = true; - $this->_blockEnd = ' '; - $parent->data[key($parent->data)] = - str_replace('>','',$parent->data[key($parent->data)]); - $parent->data[key($parent->data)] .= trim($line).' '; - $this->_allNodes[$node->parent]->children = false; - $this->_lastIndent = $node->indent; - } elseif ($chk === '|') { - $this->_inBlock = true; - $this->_blockEnd = "\n"; - $parent->data[key($parent->data)] = - str_replace('|','',$parent->data[key($parent->data)]); - $parent->data[key($parent->data)] .= trim($line)."\n"; - $this->_allNodes[$node->parent]->children = false; - $this->_lastIndent = $node->indent; + // If the value of the last node's data was > or | we need to + // start blocking i.e. taking in all lines as a text value until + // we drop our indent. + $parent =& $this->_allNodes[$node->parent]; + $this->_allNodes[$node->parent]->children = true; + if (is_array($parent->data)) { + // if (isset ($parent->data[key($parent->data)])) + $chk = $parent->data[key($parent->data)]; + if ($chk === '>') { + $this->_inBlock = true; + $this->_blockEnd = ' '; + $parent->data[key($parent->data)] = + str_replace('>','',$parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line).' '; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } elseif ($chk === '|') { + $this->_inBlock = true; + $this->_blockEnd = "\n"; + $parent->data[key($parent->data)] = + str_replace('|','',$parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line)."\n"; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } + } + } + } elseif ($this->_lastIndent > $node->indent) { + // Any block we had going is dead now + if ($this->_inBlock === true) { + $this->_inBlock = false; + if ($this->_blockEnd = "\n") { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] = + trim($last->data[key($last->data)]); + } + } + + // We don't know the parent of the node so we have to find it + // foreach ($this->_allNodes as $n) { + foreach ($this->_indentSort[$node->indent] as $n) { + if ($n->indent == $node->indent) { + $node->parent = $n->parent; } } } - } elseif ($this->_lastIndent > $node->indent) { - // Any block we had going is dead now - if ($this->_inBlock === true) { - $this->_inBlock = false; - if ($this->_blockEnd = "\n") { - $last =& $this->_allNodes[$this->_lastNode]; - $last->data[key($last->data)] = - trim($last->data[key($last->data)]); - } - } - // We don't know the parent of the node so we have to find it - // foreach ($this->_allNodes as $n) { - foreach ($this->_indentSort[$node->indent] as $n) { - if ($n->indent == $node->indent) { - $node->parent = $n->parent; - } - } - } - - if ($this->_inBlock === false) { - // Set these properties with information from our current node - $this->_lastIndent = $node->indent; - // Set the last node - $this->_lastNode = $node->id; - // Parse the YAML line and return its data - $node->data = $this->_parseLine($line); - // Add the node to the master list - $this->_allNodes[$node->id] = $node; - // Add a reference to the parent list - $this->_allParent[intval($node->parent)][] = $node->id; - // Add a reference to the node in an indent array - $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; - // Add a reference to the node in a References array if this node - // has a YAML reference in it. - if ( - ( (is_array($node->data)) && - isset($node->data[key($node->data)]) && - (!is_array($node->data[key($node->data)])) ) - && - ( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)])) - || - (preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) ) - ) { - $this->_haveRefs[] =& $this->_allNodes[$node->id]; - } elseif ( - ( (is_array($node->data)) && - isset($node->data[key($node->data)]) && - (is_array($node->data[key($node->data)])) ) - ) { - // Incomplete reference making code. Ugly, needs cleaned up. - foreach ($node->data[key($node->data)] as $d) { - if ( !is_array($d) && - ( (preg_match('/^&([^ ]+)/',$d)) - || - (preg_match('/^\*([^ ]+)/',$d)) ) - ) { - $this->_haveRefs[] =& $this->_allNodes[$node->id]; + if ($this->_inBlock === false) { + // Set these properties with information from our current node + $this->_lastIndent = $node->indent; + // Set the last node + $this->_lastNode = $node->id; + // Parse the YAML line and return its data + $node->data = $this->_parseLine($line); + // Add the node to the master list + $this->_allNodes[$node->id] = $node; + // Add a reference to the parent list + $this->_allParent[intval($node->parent)][] = $node->id; + // Add a reference to the node in an indent array + $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; + // Add a reference to the node in a References array if this node + // has a YAML reference in it. + if ( + ( (is_array($node->data)) && + isset($node->data[key($node->data)]) && + (!is_array($node->data[key($node->data)])) ) + && + ( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)])) + || + (preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) ) + ) { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } elseif ( + ( (is_array($node->data)) && + isset($node->data[key($node->data)]) && + (is_array($node->data[key($node->data)])) ) + ) { + // Incomplete reference making code. Ugly, needs cleaned up. + foreach ($node->data[key($node->data)] as $d) { + if ( !is_array($d) && + ( (preg_match('/^&([^ ]+)/',$d)) + || + (preg_match('/^\*([^ ]+)/',$d)) ) + ) { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } } } } } } - } - unset($node); + unset($node); - // Here we travel through node-space and pick out references (& and *) - $this->_linkReferences(); + // Here we travel through node-space and pick out references (& and *) + $this->_linkReferences(); - // Build the PHP array out of node-space - $trunk = $this->_buildArray(); - return $trunk; - } - - /** - * Dump PHP array to YAML - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as tasteful.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public function dump($array,$indent = false,$wordwrap = false) { - // Dumps to some very clean YAML. We'll have to add some more features - // and options soon. And better support for folding. - - // New features and options. - if ($indent === false or !is_numeric($indent)) { - $this->_dumpIndent = 2; - } else { - $this->_dumpIndent = $indent; - } - - if ($wordwrap === false or !is_numeric($wordwrap)) { - $this->_dumpWordWrap = 40; - } else { - $this->_dumpWordWrap = $wordwrap; - } - - // New YAML document - $string = "---\n"; - - // Start at the base of the array and move through it. - foreach ($array as $key => $value) { - $string .= $this->_yamlize($key,$value,0); - } - return $string; - } - - /**** Private Properties ****/ - - /**#@+ - * @access private - * @var mixed - */ - private $_haveRefs; - private $_allNodes; - private $_allParent; - private $_lastIndent; - private $_lastNode; - private $_inBlock; - private $_isInline; - private $_dumpIndent; - private $_dumpWordWrap; - /**#@-*/ - - /**** Public Properties ****/ - - /**#@+ - * @access public - * @var mixed - */ - public $_nodeId; - /**#@-*/ - - /**** Private Methods ****/ - - /** - * Attempts to convert a key / value array item to YAML - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _yamlize($key,$value,$indent) { - if (is_array($value)) { - // It has children. What to do? - // Make it the right kind of item - $string = $this->_dumpNode($key,NULL,$indent); - // Add the indent - $indent += $this->_dumpIndent; - // Yamlize the array - $string .= $this->_yamlizeArray($value,$indent); - } elseif (!is_array($value)) { - // It doesn't have children. Yip. - $string = $this->_dumpNode($key,$value,$indent); - } - return $string; - } - - /** - * Attempts to convert an array to YAML - * @access private - * @return string - * @param $array The array you want to convert - * @param $indent The indent of the current level - */ - private function _yamlizeArray($array,$indent) { - if (is_array($array)) { - $string = ''; - foreach ($array as $key => $value) { - $string .= $this->_yamlize($key,$value,$indent); - } - return $string; - } else { - return false; - } - } - - /** - * Returns YAML from a key and a value - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _dumpNode($key,$value,$indent) { - // do some folding here, for blocks - if (strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false) { - $value = $this->_doLiteralBlock($value,$indent); - } else { - $value = $this->_doFolding($value,$indent); - } - - if (is_bool($value)) { - $value = ($value) ? "true" : "false"; - } - - $spaces = str_repeat(' ',$indent); - - if (is_int($key)) { - // It's a sequence - $string = $spaces.'- '.$value."\n"; - } else { - // It's mapped - $string = $spaces.$key.': '.$value."\n"; - } - return $string; - } - - /** - * Creates a literal block for dumping - * @access private - * @return string - * @param $value - * @param $indent int The value of the indent - */ - private function _doLiteralBlock($value,$indent) { - $exploded = explode("\n",$value); - $newValue = '|'; - $indent += $this->_dumpIndent; - $spaces = str_repeat(' ',$indent); - foreach ($exploded as $line) { - $newValue .= "\n" . $spaces . trim($line); - } - return $newValue; - } - - /** - * Folds a string of text, if necessary - * @access private - * @return string - * @param $value The string you wish to fold - */ - private function _doFolding($value,$indent) { - // Don't do anything if wordwrap is set to 0 - if ($this->_dumpWordWrap === 0) { - return $value; - } - - if (strlen($value) > $this->_dumpWordWrap) { - $indent += $this->_dumpIndent; - $indent = str_repeat(' ',$indent); - $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); - $value = ">\n".$indent.$wrapped; - } - return $value; - } - - /* Methods used in loading */ - - /** - * Finds and returns the indentation of a YAML line - * @access private - * @return int - * @param string $line A line from the YAML file - */ - private function _getIndent($line) { - preg_match('/^\s{1,}/',$line,$match); - if (!empty($match[0])) { - $indent = substr_count($match[0],' '); - } else { - $indent = 0; - } - return $indent; - } - - /** - * Parses YAML code and returns an array for a node - * @access private - * @return array - * @param string $line A line from the YAML file - */ - private function _parseLine($line) { - $line = trim($line); - - $array = array(); - - if (preg_match('/^-(.*):$/',$line)) { - // It's a mapped sequence - $key = trim(substr(substr($line,1),0,-1)); - $array[$key] = ''; - } elseif ($line[0] == '-' && substr($line,0,3) != '---') { - // It's a list item but not a new stream - if (strlen($line) > 1) { - $value = trim(substr($line,1)); - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - $array[] = $value; - } else { - $array[] = array(); - } - } elseif (preg_match('/^(.+):/',$line,$key)) { - // It's a key/value pair most likely - // If the key is in double quotes pull it out - if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { - $value = trim(str_replace($matches[1],'',$line)); - $key = $matches[2]; - } else { - // Do some guesswork as to the key and the value - $explode = explode(':',$line); - $key = trim($explode[0]); - array_shift($explode); - $value = trim(implode(':',$explode)); - } - - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - if (empty($key)) { - $array[] = $value; - } else { - $array[$key] = $value; - } - } - return $array; - } - - /** - * Finds the type of the passed value, returns the value as the new type. - * @access private - * @param string $value - * @return mixed - */ - private function _toType($value) { - if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) { - $value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches)); - $value = preg_replace('/\\\\"/','"',$value); - } elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) { - // Inline Sequence - - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($matches[1]); - - // Propogate value array - $value = array(); - foreach ($explode as $v) { - $value[] = $this->_toType($v); - } - } elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) { - // It's a map - $array = explode(': ',$value); - $key = trim($array[0]); - array_shift($array); - $value = trim(implode(': ',$array)); - $value = $this->_toType($value); - $value = array($key => $value); - } elseif (preg_match("/{(.+)}$/",$value,$matches)) { - // Inline Mapping - - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($matches[1]); - - // Propogate value array - $array = array(); - foreach ($explode as $v) { - $array = $array + $this->_toType($v); - } - $value = $array; - } elseif (strtolower($value) == 'null' or $value == '' or $value == '~') { - $value = NULL; - } elseif (preg_match ('/^[0-9]+$/', $value)) { - $value = (int)$value; - } elseif (in_array(strtolower($value), - array('true', 'on', '+', 'yes', 'y'))) { - $value = TRUE; - } elseif (in_array(strtolower($value), - array('false', 'off', '-', 'no', 'n'))) { - $value = FALSE; - } elseif (is_numeric($value)) { - $value = (float)$value; - } else { - // Just a normal string, right? - $value = trim(preg_replace('/#(.+)$/','',$value)); - } - - return $value; - } - - /** - * Used in inlines to check for more inlines or quoted strings - * @access private - * @return array - */ - private function _inlineEscape($inline) { - // There's gotta be a cleaner way to do this... - // While pure sequences seem to be nesting just fine, - // pure mappings and mappings with sequences inside can't go very - // deep. This needs to be fixed. - - $saved_strings = array(); - - // Check for strings - $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; - if (preg_match_all($regex,$inline,$strings)) { - $saved_strings = $strings[0]; - $inline = preg_replace($regex,'YAMLString',$inline); - } - unset($regex); - - // Check for sequences - if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) { - $inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline); - $seqs = $seqs[0]; - } - - // Check for mappings - if (preg_match_all('/{(.+)}/U',$inline,$maps)) { - $inline = preg_replace('/{(.+)}/U','YAMLMap',$inline); - $maps = $maps[0]; - } - - $explode = explode(', ',$inline); - - - // Re-add the sequences - if (!empty($seqs)) { - $i = 0; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - $explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value); - ++$i; - } - } - } - - // Re-add the mappings - if (!empty($maps)) { - $i = 0; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLMap') !== false) { - $explode[$key] = str_replace('YAMLMap',$maps[$i],$value); - ++$i; - } - } - } - - - // Re-add the strings - if (!empty($saved_strings)) { - $i = 0; - foreach ($explode as $key => $value) { - while (strpos($value,'YAMLString') !== false) { - $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$i],$value, 1); - ++$i; - $value = $explode[$key]; - } - } - } - - return $explode; - } - - /** - * Builds the PHP array from all the YAML nodes we've gathered - * @access private - * @return array - */ - private function _buildArray() { - $trunk = array(); - - if (!isset($this->_indentSort[0])) { + // Build the PHP array out of node-space + $trunk = $this->_buildArray(); return $trunk; } - foreach ($this->_indentSort[0] as $n) { - if (empty($n->parent)) { - $this->_nodeArrayizeData($n); - // Check for references and copy the needed data to complete them. - $this->_makeReferences($n); - // Merge our data with the big array we're building - $trunk = $this->_array_kmerge($trunk,$n->data); + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array,$indent = false,$wordwrap = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key,$value,0); + } + return $string; + } + + /**** Private Properties ****/ + + /**#@+ + * @access private + * @var mixed + */ + private $_haveRefs; + private $_allNodes; + private $_allParent; + private $_lastIndent; + private $_lastNode; + private $_inBlock; + private $_isInline; + private $_dumpIndent; + private $_dumpWordWrap; + /**#@+*/ + + /**** Public Properties ****/ + + /**#@+ + * @access public + * @var mixed + */ + public $_nodeId; + /**#@+*/ + + /**** Private Methods ****/ + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _yamlize($key,$value,$indent) { + if (is_array($value)) { + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key,NULL,$indent); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key,$value,$indent); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + private function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key,$value,$indent); + } + return $string; + } else { + return false; } } - return $trunk; - } + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _dumpNode($key,$value,$indent) { + // do some folding here, for blocks + if (strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + } - /** - * Traverses node-space and sets references (& and *) accordingly - * @access private - * @return bool - */ - private function _linkReferences() { - if (is_array($this->_haveRefs)) { - foreach ($this->_haveRefs as $node) { - if (!empty($node->data)) { - $key = key($node->data); - // If it's an array, don't check. - if (is_array($node->data[$key])) { - foreach ($node->data[$key] as $k => $v) { - $this->_linkRef($node,$key,$k,$v); - } - } else { - $this->_linkRef($node,$key); + if (is_bool($value)) { + $value = ($value) ? "true" : "false"; + } + + $spaces = str_repeat(' ',$indent); + + if (is_int($key)) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + // It's mapped + $string = $spaces.$key.': '.$value."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + private function _doLiteralBlock($value,$indent) { + $exploded = explode("\n",$value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $newValue .= "\n" . $spaces . trim($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + private function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + if ($this->_dumpWordWrap === 0) { + return $value; + } + + if (strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } + return $value; + } + + /* Methods used in loading */ + + /** + * Finds and returns the indentation of a YAML line + * @access private + * @return int + * @param string $line A line from the YAML file + */ + private function _getIndent($line) { + preg_match('/^\s{1,}/',$line,$match); + if (!empty($match[0])) { + $indent = substr_count($match[0],' '); + } else { + $indent = 0; + } + return $indent; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + private function _parseLine($line) { + $line = trim($line); + + $array = array(); + + if (preg_match('/^-(.*):$/',$line)) { + // It's a mapped sequence + $key = trim(substr(substr($line,1),0,-1)); + $array[$key] = ''; + } elseif ($line[0] == '-' && substr($line,0,3) != '---') { + // It's a list item but not a new stream + if (strlen($line) > 1) { + $value = trim(substr($line,1)); + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + $array[] = $value; + } else { + $array[] = array(); + } + } elseif (preg_match('/^(.+):/',$line,$key)) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(':',$line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':',$explode)); + } + + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if (empty($key)) { + $array[] = $value; + } else { + $array[$key] = $value; + } + } + return $array; + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + private function _toType($value) { + if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) { + $value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches)); + $value = preg_replace('/\\\\"/','"',$value); + } elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) { + // Inline Sequence + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + } elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) { + // It's a map + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + $value = array($key => $value); + } elseif (preg_match("/{(.+)}$/",$value,$matches)) { + // Inline Mapping + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $array = array(); + foreach ($explode as $v) { + $array = $array + $this->_toType($v); + } + $value = $array; + } elseif (strtolower($value) == 'null' or $value == '' or $value == '~') { + $value = NULL; + } elseif (preg_match ('/^[0-9]+$/', $value)) { + $value = (int)$value; + } elseif (in_array(strtolower($value), + array('true', 'on', '+', 'yes', 'y'))) { + $value = TRUE; + } elseif (in_array(strtolower($value), + array('false', 'off', '-', 'no', 'n'))) { + $value = FALSE; + } elseif (is_numeric($value)) { + $value = (float)$value; + } else { + // Just a normal string, right? + $value = trim(preg_replace('/#(.+)$/','',$value)); + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + private function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + $saved_strings = array(); + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_strings = $strings[0]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + // Check for sequences + if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) { + $inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline); + $seqs = $seqs[0]; + } + + // Check for mappings + if (preg_match_all('/{(.+)}/U',$inline,$maps)) { + $inline = preg_replace('/{(.+)}/U','YAMLMap',$inline); + $maps = $maps[0]; + } + + $explode = explode(', ',$inline); + + + // Re-add the sequences + if (!empty($seqs)) { + $i = 0; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value); + ++$i; } } } - } - return true; - } - function _linkRef(&$n,$key,$k = NULL,$v = NULL) { - if (empty($k) && empty($v)) { - // Look for &refs - if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) { - // Flag the node so we know it's a reference - $this->_allNodes[$n->id]->ref = substr($matches[0],1); - $this->_allNodes[$n->id]->data[$key] = - substr($n->data[$key],strlen($matches[0])+1); - // Look for *refs - } elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) { - $ref = substr($matches[0],1); - // Flag the node as having a reference - $this->_allNodes[$n->id]->refKey = $ref; - } - } elseif (!empty($k) && !empty($v)) { - if (preg_match('/^&([^ ]+)/',$v,$matches)) { - // Flag the node so we know it's a reference - $this->_allNodes[$n->id]->ref = substr($matches[0],1); - $this->_allNodes[$n->id]->data[$key][$k] = - substr($v,strlen($matches[0])+1); - // Look for *refs - } elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) { - $ref = substr($matches[0],1); - // Flag the node as having a reference - $this->_allNodes[$n->id]->refKey = $ref; - } - } - } - - /** - * Finds the children of a node and aids in the building of the PHP array - * @access private - * @param int $nid The id of the node whose children we're gathering - * @return array - */ - private function _gatherChildren($nid) { - $return = array(); - $node =& $this->_allNodes[$nid]; - if (is_array ($this->_allParent[$node->id])) { - foreach ($this->_allParent[$node->id] as $nodeZ) { - $z =& $this->_allNodes[$nodeZ]; - // We found a child - $this->_nodeArrayizeData($z); - // Check for references - $this->_makeReferences($z); - // Merge with the big array we're returning - // The big array being all the data of the children of our parent node - $return = $this->_array_kmerge($return,$z->data); - } - } - return $return; - } - - /** - * Turns a node's data and its children's data into a PHP array - * - * @access private - * @param array $node The node which you want to arrayize - * @return boolean - */ - private function _nodeArrayizeData(&$node) { - if (is_array($node->data) && $node->children == true) { - // This node has children, so we need to find them - $childs = $this->_gatherChildren($node->id); - // We've gathered all our children's data and are ready to use it - $key = key($node->data); - $key = empty($key) ? 0 : $key; - // If it's an array, add to it of course - if (isset ($node->data[$key])) { - if (is_array($node->data[$key])) { - $node->data[$key] = $this->_array_kmerge($node->data[$key],$childs); - } else { - $node->data[$key] = $childs; + // Re-add the mappings + if (!empty($maps)) { + $i = 0; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + $explode[$key] = str_replace('YAMLMap',$maps[$i],$value); + ++$i; } - } else { - $node->data[$key] = $childs; + } } - } elseif (!is_array($node->data) && $node->children == true) { - // Same as above, find the children of this node - $childs = $this->_gatherChildren($node->id); - $node->data = array(); - $node->data[] = $childs; + + + // Re-add the strings + if (!empty($saved_strings)) { + $i = 0; + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLString') !== false) { + $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$i],$value, 1); + ++$i; + $value = $explode[$key]; + } + } + } + + return $explode; } - // We edited $node by reference, so just return true - return true; - } + /** + * Builds the PHP array from all the YAML nodes we've gathered + * @access private + * @return array + */ + private function _buildArray() { + $trunk = array(); - /** - * Traverses node-space and copies references to / from this object. - * @access private - * @param object $z A node whose references we wish to make real - * @return bool - */ - private function _makeReferences(&$z) { - // It is a reference - if (isset($z->ref)) { - $key = key($z->data); - // Copy the data to this object for easy retrieval later - $this->ref[$z->ref] =& $z->data[$key]; - // It has a reference - } elseif (isset($z->refKey)) { - if (isset($this->ref[$z->refKey])) { - $key = key($z->data); - // Copy the data from this object to make the node a real reference - $z->data[$key] =& $this->ref[$z->refKey]; + if (!isset($this->_indentSort[0])) { + return $trunk; + } + + foreach ($this->_indentSort[0] as $n) { + if (empty($n->parent)) { + $this->_nodeArrayizeData($n); + // Check for references and copy the needed data to complete them. + $this->_makeReferences($n); + // Merge our data with the big array we're building + $trunk = $this->_array_kmerge($trunk,$n->data); + } + } + + return $trunk; + } + + /** + * Traverses node-space and sets references (& and *) accordingly + * @access private + * @return bool + */ + private function _linkReferences() { + if (is_array($this->_haveRefs)) { + foreach ($this->_haveRefs as $node) { + if (!empty($node->data)) { + $key = key($node->data); + // If it's an array, don't check. + if (is_array($node->data[$key])) { + foreach ($node->data[$key] as $k => $v) { + $this->_linkRef($node,$key,$k,$v); + } + } else { + $this->_linkRef($node,$key); + } + } + } + } + return true; + } + + function _linkRef(&$n,$key,$k = NULL,$v = NULL) { + if (empty($k) && empty($v)) { + // Look for &refs + if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0],1); + $this->_allNodes[$n->id]->data[$key] = + substr($n->data[$key],strlen($matches[0])+1); + // Look for *refs + } elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) { + $ref = substr($matches[0],1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } + } elseif (!empty($k) && !empty($v)) { + if (preg_match('/^&([^ ]+)/',$v,$matches)) { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0],1); + $this->_allNodes[$n->id]->data[$key][$k] = + substr($v,strlen($matches[0])+1); + // Look for *refs + } elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) { + $ref = substr($matches[0],1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } } } - return true; - } - - /** - * Merges arrays and maintains numeric keys. - * - * An ever-so-slightly modified version of the array_kmerge() function posted - * to php.net by mail at nospam dot iaindooley dot com on 2004-04-08. - * - * http://us3.php.net/manual/en/function.array-merge.php - * - * @access private - * @param array $arr1 - * @param array $arr2 - * @return array - */ - private function _array_kmerge($arr1,$arr2) { - if(!is_array($arr1)) $arr1 = array(); - if(!is_array($arr2)) $arr2 = array(); - - $keys = array_merge(array_keys($arr1),array_keys($arr2)); - $vals = array_merge(array_values($arr1),array_values($arr2)); - $ret = array(); - foreach($keys as $key) { - list($unused,$val) = each($vals); - if (isset($ret[$key]) and is_int($key)) $ret[] = $val; else $ret[$key] = $val; + /** + * Finds the children of a node and aids in the building of the PHP array + * @access private + * @param int $nid The id of the node whose children we're gathering + * @return array + */ + private function _gatherChildren($nid) { + $return = array(); + $node =& $this->_allNodes[$nid]; + if (is_array ($this->_allParent[$node->id])) { + foreach ($this->_allParent[$node->id] as $nodeZ) { + $z =& $this->_allNodes[$nodeZ]; + // We found a child + $this->_nodeArrayizeData($z); + // Check for references + $this->_makeReferences($z); + // Merge with the big array we're returning + // The big array being all the data of the children of our parent node + $return = $this->_array_kmerge($return,$z->data); + } + } + return $return; + } + + /** + * Turns a node's data and its children's data into a PHP array + * + * @access private + * @param array $node The node which you want to arrayize + * @return boolean + */ + private function _nodeArrayizeData(&$node) { + if (is_array($node->data) && $node->children == true) { + // This node has children, so we need to find them + $childs = $this->_gatherChildren($node->id); + // We've gathered all our children's data and are ready to use it + $key = key($node->data); + $key = empty($key) ? 0 : $key; + // If it's an array, add to it of course + if (isset ($node->data[$key])) { + if (is_array($node->data[$key])) { + $node->data[$key] = $this->_array_kmerge($node->data[$key],$childs); + } else { + $node->data[$key] = $childs; + } + } else { + $node->data[$key] = $childs; + } + } elseif (!is_array($node->data) && $node->children == true) { + // Same as above, find the children of this node + $childs = $this->_gatherChildren($node->id); + $node->data = array(); + $node->data[] = $childs; + } + + // We edited $node by reference, so just return true + return true; + } + + /** + * Traverses node-space and copies references to / from this object. + * @access private + * @param object $z A node whose references we wish to make real + * @return bool + */ + private function _makeReferences(&$z) { + // It is a reference + if (isset($z->ref)) { + $key = key($z->data); + // Copy the data to this object for easy retrieval later + $this->ref[$z->ref] =& $z->data[$key]; + // It has a reference + } elseif (isset($z->refKey)) { + if (isset($this->ref[$z->refKey])) { + $key = key($z->data); + // Copy the data from this object to make the node a real reference + $z->data[$key] =& $this->ref[$z->refKey]; + } + } + return true; + } + + + /** + * Merges arrays and maintains numeric keys. + * + * An ever-so-slightly modified version of the array_kmerge() function posted + * to php.net by mail at nospam dot iaindooley dot com on 2004-04-08. + * + * http://us3.php.net/manual/en/function.array-merge.php#41394 + * + * @access private + * @param array $arr1 + * @param array $arr2 + * @return array + */ + private function _array_kmerge($arr1,$arr2) { + if(!is_array($arr1)) $arr1 = array(); + if(!is_array($arr2)) $arr2 = array(); + + $keys = array_merge(array_keys($arr1),array_keys($arr2)); + $vals = array_merge(array_values($arr1),array_values($arr2)); + $ret = array(); + foreach($keys as $key) { + list($unused,$val) = each($vals); + if (isset($ret[$key]) and is_int($key)) $ret[] = $val; else $ret[$key] = $val; + } + return $ret; } - return $ret; } -} ?> diff --git a/cli-script.php b/cli-script.php index bf00e3fed..10e2a807a 100755 --- a/cli-script.php +++ b/cli-script.php @@ -1,24 +1,13 @@ #!/usr/bin/php5 disableBasicAuth(); diff --git a/cli/DailyTask.php b/cli/DailyTask.php index 92e00dbee..9a6c8ae0f 100755 --- a/cli/DailyTask.php +++ b/cli/DailyTask.php @@ -1,14 +1,7 @@ + * Usage: * new ArrayData(array( * "ClassName" => "Page", * "AddAction" => "Add a new Page page", * )); - * - * - * @package sapphire - * @subpackage view */ class ArrayData extends ViewableData { protected $array; - /** - * @param object|array $array Either an object with simple properties or an associative array. - * Converts object-properties to indices of an associative array. - */ public function __construct($array) { - if(is_object($array)) { - $this->array = self::object_to_array($array); - } elseif(is_array($array) && ArrayLib::is_associative($array)) { - $this->array = $array; - } else { - $this->array = $array; - user_error( - "ArrayData::__construct: Parameter needs to be an object or associative array", - E_USER_WARNING - ); - } + $this->array = $array; } public function getField($f) { @@ -52,24 +31,6 @@ class ArrayData extends ViewableData { return isset($this->array[$f]); } - /** - * Converts an object with simple properties to - * an associative array. - * - * @todo Allow for recursive creation of DataObjectSets when property value is an object/array - * - * @param obj $obj - * @return array - */ - static function object_to_array($obj) { - $arr = array(); - foreach($obj as $k=>$v) { - $arr[$k] = $v; - } - - return $arr; - } - } ?> \ No newline at end of file diff --git a/core/ArrayLib.php b/core/ArrayLib.php index 985fd3ecf..1b3171f38 100755 --- a/core/ArrayLib.php +++ b/core/ArrayLib.php @@ -1,15 +1,5 @@ \ No newline at end of file diff --git a/core/ClassInfo.php b/core/ClassInfo.php index 4f95c5d66..c72f370c3 100755 --- a/core/ClassInfo.php +++ b/core/ClassInfo.php @@ -1,17 +1,8 @@ implementsInterface($interfaceName)) { + $matchingClasses[$potentialClass] = $potentialClass; + } + } + } + + self::$implementors_of[$interfaceName] = $matchingClasses; + + return $matchingClasses; } } ?> \ No newline at end of file diff --git a/core/Convert.php b/core/Convert.php index 1dd5bf107..7530cbd53 100755 --- a/core/Convert.php +++ b/core/Convert.php @@ -1,10 +1,5 @@ hasMethod('debug'); - } else { - $hasDebugMethod = method_exists($val, 'debug'); - } - - if($hasDebugMethod) { - return $val->debug(); - } - } - - if(is_array($val)) { - $result = "
    \n"; - foreach($val as $k => $v) { - $result .= "
  • $k = " . Debug::text($v) . "
  • \n"; - } - $val = $result . "
\n"; - - } else if (is_object($val)) { - $val = var_export($val, true); + if(is_object($val) && $val->hasMethod('debug')) { + return $val->debug(); } else { - if(true || !Director::is_ajax()) { - $val = "
" . htmlentities($val) . "
\n"; - } - } + if(is_array($val)) { + $result = "
    \n"; + foreach($val as $k => $v) { + $result .= "
  • $k = " . Debug::text($v) . "
  • \n"; + } + $val = $result . "
\n"; - return $val; + } else if (is_object($val)) { + $val = var_export($val, true); + } else { + if(true || !Director::is_ajax()) { + $val = "
" . htmlentities($val) . "
\n"; + } + } + + return $val; + } } /** @@ -112,27 +85,23 @@ class Debug { /** * Load an error handler - * - * @todo why does this delegate to loadFatalErrorHandler? */ static function loadErrorHandlers() { Debug::loadFatalErrorHandler(); } - /** - * @todo can this be moved into loadErrorHandlers? - */ static function loadFatalErrorHandler() { - set_error_handler('errorHandler', (E_ALL ^ E_NOTICE) ^ E_USER_NOTICE); - set_exception_handler('exceptionHandler'); + set_error_handler('errorHandler', E_ALL & ~E_NOTICE); } static function warningHandler($errno, $errstr, $errfile, $errline, $errcontext) { - if(error_reporting() == 0) return; if(self::$send_warnings_to) self::emailError(self::$send_warnings_to, $errno, $errstr, $errfile, $errline, $errcontext, "Warning"); if(Director::isDev()) { - self::showError($errno, $errstr, $errfile, $errline, $errcontext); + if(error_reporting() != 0) { // otherwise the error was suppressed with @ + self::showError($errno, $errstr, $errfile, $errline, $errcontext); + die(); + } } } @@ -151,13 +120,14 @@ class Debug { header("HTTP/1.0 500 Internal server error"); if(Director::is_ajax()) { - echo "There has been an error"; + echo "ERROR:There has been an error"; } else { if(file_exists('../assets/error-500.html')) { + echo "ERROR:"; include('../assets/error-500.html'); } else { - echo "

Error

The website server has not been able to respond to your request.

\n"; + echo "ERROR:

Error

The website server has not been able to respond to your request.

\n"; } } } @@ -174,7 +144,6 @@ class Debug { echo "

FATAL ERROR: $errstr
\n At line $errline in $errfile
\n
\n

\n"; Debug::backtrace(); - //Debug::show(debug_backtrace()); echo "

Context

\n"; Debug::show($errcontext); @@ -200,10 +169,7 @@ class Debug { if(self::$custom_smtp_server) { ini_set("SMTP", self::$custom_smtp_server); } - - $relfile = Director::makeRelative($errfile); - if($relfile[0] == '/') $relfile = substr($relfile,1); - mail($emailAddress, "$errorType at $relfile line $errline (http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI])", $data, "Content-type: text/html\nFrom: errors@silverstripe.com"); + mail($emailAddress, "$errorType on $_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", $data, "Content-type: text/html\nFrom: errors@silverstripe.com"); } /** @@ -248,10 +214,9 @@ class Debug { /** * Deprecated. Send live errors and warnings to the given address. - * @deprecated Use send_errors_to() instead. + * Use send_errors_to() instead. */ static function sendLiveErrorsTo($emailAddress) { - user_error('Debug::sendLiveErrorsTo() is deprecated. Use Debug::send_errors_to() instead.', E_USER_NOTICE); if(!Director::isDev()) self::send_errors_to($emailAddress, true); } @@ -270,11 +235,11 @@ class Debug { $bt = debug_backtrace(); // Ingore functions that are plumbing of the error handler - $ignoredFunctions = array('Debug::emailError','Debug::warningHandler','Debug::fatalHandler','errorHandler','Debug::showError','Debug::backtrace', 'exceptionHandler'); + $ignoredFunctions = array('Debug::emailError','Debug::warningHandler','Debug::fatalHandler','errorHandler','Debug::showError','Debug::backtrace'); while( $bt && in_array(self::full_func_name($bt[0]), $ignoredFunctions) ) { array_shift($bt); } - + $result = ""; foreach($bt as $item) { if(Director::is_ajax() && !$ignoreAjax) { @@ -287,12 +252,9 @@ class Debug { $result .= "

\n"; } } - - if ($returnVal) { - return $result; - } else { - echo $result; - } + + if($returnVal) return $result; + else echo $result; } /** @@ -305,16 +267,7 @@ class Debug { if(isset($item['function'])) $funcName .= $item['function']; if($showArgs && isset($item['args'])) { - $args = array(); - foreach($item['args'] as $arg) { - if(!is_object($arg) || method_exists($arg, '__toString')) { - $args[] = (string) $arg; - } else { - $args[] = get_class($arg); - } - } - - $funcName .= "(" . implode(",", $args) .")"; + @$funcName .= "(" . implode(",", (array)$item['args']) .")"; } return $funcName; @@ -366,16 +319,6 @@ class Debug { } } -function exceptionHandler($exception) { - $errno = E_USER_ERROR; - $type = get_class($exception); - $message = "Uncaught " . $type . ": " . $exception->getMessage(); - $file = $exception->getFile(); - $line = $exception->getLine(); - $context = $exception->getTrace(); - Debug::fatalHandler($errno, $message, $file, $line, $context); -} - function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { switch($errno) { case E_ERROR: diff --git a/core/Email.php b/core/Email.php index 473fe4757..7d6614f9c 100755 --- a/core/Email.php +++ b/core/Email.php @@ -1,27 +1,10 @@ $this->from, "Subject" => $this->subject, "Body" => $this->body, - "BaseURL" => $this->BaseURL(), - "IsEmail" => true, + "BaseURL" => $this->BaseURL() )); } else { return $this; } } - /** - * Used by SSViewer templates to detect if we're rendering an email template rather than a page template - */ - public function IsEmail() { - return true; - } - /** * Load all the template variables into the internal variables, including * the template into body. Called before send() or debugSend() @@ -375,11 +350,6 @@ class Email extends ViewableData { } } -/** - * Implements an email template that can be populated. - * @package sapphire - * @subpackage email - */ class Email_Template extends Email { public function __construct() { } @@ -440,13 +410,13 @@ function htmlEmail($to, $from, $subject, $htmlContent, $attachedFiles = false, $ // Make the plain text part - $headers["Content-Type"] = "text/plain; charset=\"utf-8\""; + $headers["Content-Type"] = "text/plain; charset=\"iso-8859-15\""; $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "quoted-printable"; $plainPart = processHeaders($headers, ($plainEncoding == "base64") ? chunk_split(base64_encode($plainContent),60) : wordwrap($plainContent,120)); // Make the HTML part - $headers["Content-Type"] = "text/html; charset=\"utf-8\""; + $headers["Content-Type"] = "text/html; charset=\"iso-8859-15\""; // Add basic wrapper tags if the body tag hasn't been given @@ -454,7 +424,7 @@ function htmlEmail($to, $from, $subject, $htmlContent, $attachedFiles = false, $ $htmlContent = "\n" . "\n" . - "\n" . + "\n" . "\n\n". "\n" . "\n" . @@ -558,7 +528,7 @@ function plaintextEmail($to, $from, $subject, $plainContent, $attachedFiles, $cu // Make the plain text part - $headers["Content-Type"] = "text/plain; charset=\"utf-8\""; + $headers["Content-Type"] = "text/plain; charset=\"iso-8859-15\""; $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "quoted-printable"; $plainContent = ($plainEncoding == "base64") ? chunk_split(base64_encode($plainContent),60) : QuotedPrintable_encode($plainContent); @@ -663,7 +633,7 @@ function wrapImagesInline($htmlContent) { // Make the HTML part - $headers["Content-Type"] = "text/html; charset=\"utf-8\""; + $headers["Content-Type"] = "text/html; charset=\"iso-8859-15\""; $headers["Content-Transfer-Encoding"] = "quoted-printable"; $multiparts[] = processHeaders($headers, QuotedPrintable_encode($replacedContent)); @@ -787,7 +757,7 @@ function getMimeType($filename) { function loadMimeTypes() { $mimetypePathCustom = '/etc/mime.types'; $mimetypePathGeneric = Director::baseFolder() . '/sapphire/email/mime.types'; - $mimeTypes = file_exists($mimetypePathGeneric) ? file($mimetypePathGeneric) : file($mimetypePathCustom); + $mimeTypes = file_exists($mimetypePathCustom) ? file($mimetypePathCustom) : file($mimetypePathGeneric); foreach($mimeTypes as $typeSpec) { if(($typeSpec = trim($typeSpec)) && substr($typeSpec,0,1) != "#") { $parts = split("[ \t\r\n]+", $typeSpec); @@ -807,10 +777,8 @@ function loadMimeTypes() { } /** - * Base class that email bounce handlers extend - * @package sapphire - * @subpackage email - */ +* Base class that email bounce handlers extend +*/ class Email_BounceHandler extends Controller { function init() { @@ -925,11 +893,6 @@ class Email_BounceHandler extends Controller { } -/** - * Database record for recording a bounced email - * @package sapphire - * @subpackage email - */ class Email_BounceRecord extends DataObject { static $db = array( 'BounceEmail' => 'Varchar', @@ -945,8 +908,6 @@ class Email_BounceRecord extends DataObject { /** * This class is responsible for ensuring that members who are on it receive NO email * communication at all. any correspondance is caught before the email is sent. - * @package sapphire - * @subpackage email */ class Email_BlackList extends DataObject{ static $db = array( diff --git a/core/Extension.php b/core/Extension.php index 5152d6a35..6c53ec98e 100644 --- a/core/Extension.php +++ b/core/Extension.php @@ -1,17 +1,10 @@ tableList() : array(); - - $allClasses["parents"] = self::find_parents(); - $allClasses["children"] = self::find_children(); - $allClasses["implementors"] = self::$implementsArray; - - foreach(self::$classArray as $class => $info) { - $allClasses['exists'][$class] = $class; - if(isset($tables[strtolower($class)])) $allClasses['hastable'][$class] = $class; + + if(DB::isActive()) { + $tables = DB::getConn()->tableList(); + } else { + $tables = array(); } - + + $allClasses['hastable'] = array(); + // Build a map of classes and their subclasses $_classes = get_declared_classes(); - foreach($_classes as $class) { $allClasses['exists'][$class] = $class; - if(isset($tables[strtolower($class)])) $allClasses['hastable'][$class] = $class; + + if(isset($tables[strtolower($class)])) + $allClasses['hastable'][$class] = $class; + foreach($_classes as $subclass) { - if(is_subclass_of($class, $subclass)) $allClasses['parents'][$class][$subclass] = $subclass; - if(is_subclass_of($subclass, $class)) $allClasses['children'][$class][$subclass] = $subclass; + if(is_subclass_of($class, $subclass)) + $allClasses['parents'][$class][$subclass] = $subclass; + + if(is_subclass_of($subclass, $class)) + $allClasses['children'][$class][$subclass] = $subclass; } } return $allClasses; } -/** - * Parses a php file and adds any class or interface information into self::$classArray - * - * @param string $filename - */ - private static function parse_file($filename) { - $file = file_get_contents($filename); - - $implements = ""; - $extends = ""; - $class=""; - - if(!$file) die("Couldn't open $filename
"); - - $classes = array(); - $size = preg_match_all('/class (.*)[ \n]*{/m', $file, $classes); - - for($i=0; $i < $size; $i++) { - //we have a class - $args = split("implements", $classes[1][$i]); - $implements = isset($args[1]) ? $args[1] : null; - - $interfaces = explode(",", $implements); - $args = split("extends", $args[0]); - $extends = trim(isset($args[1]) ? $args[1] : null); - $class = trim($args[0]); - if($extends) self::$extendsArray[$extends][$class] = $class; - - foreach($interfaces as $interface) { - self::$implementsArray[$interface][$class] = $class; - } - - self::$classArray[$class] = array( - "interfaces" => $interfaces, - "extends" => $extends, - "file" => $filename - ); - } - - $interfaces = array(); - $size = preg_match_all('/interface (.*){/', $file, $interfaces); - - for($i=0;$i<$size;$i++) { - $class = trim($interfaces[1][$i]); - self::$classArray[$class] = array( - "interfaces"=>array(), - "extends" => "", - "isinterface"=>true - ); - } - } /** - * Moves through self::$classArray and creates an array containing parent data - * - * @return array + * Include all files of the class manifest so that that actually *all* + * classes are available */ - private static function find_parents() { - $parentArray = array(); - foreach(self::$classArray as $class => $info) { - $extendArray = array(); + static function includeEverything() { + global $_CLASS_MANIFEST; - $parent = $info["extends"]; + foreach($_CLASS_MANIFEST as $filename) { + if(preg_match('/.*cli-script\.php$/', $filename)) + continue; - while($parent) { - $extendArray[$parent] = $parent; - $parent = isset(self::$classArray[$parent]["extends"]) ? self::$classArray[$parent]["extends"] : null; - } - $parentArray[$class] = array_reverse($extendArray); + require_once($filename); } - return $parentArray; - } - - /** - * Iterates through self::$classArray and returns an array with any descendant data - * - * @return array - */ - private static function find_children() { - $childrenArray = array(); - foreach(self::$extendsArray as $class => $children) { - $allChildren = $children; - foreach($children as $childName) { - $allChildren = array_merge($allChildren, self::up_children($childName)); - } - $childrenArray[$class] = $allChildren; - } - return $childrenArray; - } - - /** - * Helper function to find all children of give class - * - * @param string $class - * @return array - */ - private static function get_children($class) { - return isset(self::$extendsArray[$class]) ? self::$extendsArray[$class] : array(); - } - - /** - * Returns a flat array with all children of a given class - * - * @param string $class - * @param array $results - */ - function up_children($class) { - $children = self::get_Children($class); - $results = $children; - foreach($children as $className) { - $results = array_merge($results, self::up_children($className)); - } - return $results;; } /** @@ -467,15 +361,15 @@ class ManifestBuilder { $_ALL_CLASSES['hastable'] = array(); $tables = DB::getConn()->tableList(); - + // We need to iterate through the full class lists, because the table names come out in lowercase foreach($_ALL_CLASSES['exists'] as $class) { if(isset($tables[strtolower($class)])) $_ALL_CLASSES['hastable'][$class] = $class; } - + self::write_manifest(); } - + /** * Write the manifest file, containing the updated values in the applicable globals */ @@ -485,13 +379,12 @@ class ManifestBuilder { $manifest = "\$_CLASS_MANIFEST = " . var_export($_CLASS_MANIFEST, true) . ";\n"; // Config manifest - $baseDir = dirname($_SERVER['SCRIPT_FILENAME']) . "/.."; + $baseDir = dirname($_SERVER['SCRIPT_FILENAME']) . "/.."; $baseDir = ereg_replace("/[^/]+/\\.\\.","",$baseDir); $topLevel = scandir($baseDir); foreach($topLevel as $filename) { - if($filename[0] == '.') continue; - if(@is_dir("$baseDir/$filename/") && file_exists("$baseDir/$filename/_config.php")) { + if(is_dir("$baseDir/$filename/") && file_exists("$baseDir/$filename/_config.php")) { $manifest .= "require_once(\"$baseDir/$filename/_config.php\");\n"; } } @@ -501,7 +394,7 @@ class ManifestBuilder { $manifest .= "\$_ALL_CLASSES = " . var_export($_ALL_CLASSES, true) . ";\n"; $manifest = ""; - if($fh = fopen(MANIFEST_FILE,"w")) { + if($fh = fopen(MANIFEST_FILE,"w")) { fwrite($fh, $manifest); fclose($fh); @@ -513,4 +406,4 @@ class ManifestBuilder { } -?> +?> \ No newline at end of file diff --git a/core/Object.php b/core/Object.php index 2ca0bdefa..c637d57bb 100755 --- a/core/Object.php +++ b/core/Object.php @@ -1,16 +1,9 @@ extension_instances[$name]; } @@ -429,123 +422,6 @@ class Object { ), )); } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // CACHE METHODS (added by simon_w (simon -at- simon -dot- geek -dot- nz)) - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - /** - * Loads a current cache from the filesystem, if it can. - * - * @param string $cachename The name of the cache to load - * @param int $expire The lifetime of the cache in seconds - * @return mixed The data from the cache, or false if the cache wasn't loaded - */ - protected function loadCache($cachename, $expire = 3600) { - $cache_dir = TEMP_FOLDER; - $cache_path = $cache_dir . "/" . $this->sanitiseCachename($cachename); - if((!isset($_GET['flush']) || $_GET['flush']!=1) && (@file_exists($cache_path) && ((@filemtime($cache_path) + $expire) > (time())))) { - return @unserialize(file_get_contents($cache_path)); - } - return false; - } - - /** - * Saves a cache to the file system - * - * @param string $cachename The name of the cache to save - * @param mixed $data The data to cache - */ - protected function saveCache($cachename, $data) { - $cache_dir = TEMP_FOLDER; - $cache_path = $cache_dir . "/" . $this->sanitiseCachename($cachename); - $fp = @fopen($cache_path, "w+"); - if(!$fp) { - return; // Throw an error? - } - @fwrite($fp, @serialize($data)); - @fclose($fp); - } - - /** - * Makes a cache name safe to use in a file system - * - * @param string $cachename The cache name to sanitise - * @return string the sanitised cache name - */ - protected function sanitiseCachename($cachename) { - // Replace illegal characters with underscores - $cachename = str_replace(array('~', '.', '/', '!', ' ', "\n", "\r", "\t", '\\', ':', '"', '\'', ';'), '_', $cachename); - return $cachename; - } - - /** - * Caches the return value of a method. - * - * @param callback $callback The method to cache - * @param int $expire The lifetime of the cache - * @param string|int $id An id for the cache - * @return mixed The cached return of the method - */ - public function cacheToFile($callback, $expire = 3600, $id = false) { - if(!$this->class) { - $this->class = get_class($this); - } - if(!method_exists($this->class, $callback)) { - user_error("Class {$this->class} doesn't have the method $callback.", E_USER_ERROR); - } - $cachename = $this->class . "_" . $callback; - if($id) { - $cachename .= "_" . (string)$id; - } - if(($data = $this->loadCache($cachename, $expire)) !== false) { - return $data; - } - // No cache to use - $data = $this->$callback(); - if($data === false) { - // Some problem with function. Didn't give anything to cache. So don't cache it. - return false; - } - $this->saveCache($cachename, $data); - return $data; - } - - /** - * Caches the return value of a method. Passes args to the method as well. - * - * @param callback $callback The method to cache - * @param array $args The arguments to pass to the method - * @param int $expire The lifetime of the cache - * @param string|int $id An id for the cache - * @return mixed The cached return of the method - */ - // I know this is almost exactly the same as cacheToFile, but call_user_func_array() is slow. - // Which is why there's two separate functions - public function cacheToFileWithArgs($callback, $args = array(), $expire = 3600, $id = false) { - if(!$this->class) { - $this->class = get_class($this); - } - if(!method_exists($this->class, $callback)) { - user_error("Class {$this->class} doesn't have the method $callback.", E_USER_ERROR); - } - $cachename = $this->class . "_" . $callback; - if($id) { - $cachename .= "_" . (string)$id; - } - if(($data = $this->loadCache($cachename, $expire)) !== false) { - return $data; - } - // No cache to use - $data = call_user_func_array(array($this, $callback), $args); - if($data === false) { - // Some problem with function. Didn't give anything to cache. So don't cache it. - return false; - } - $this->saveCache($cachename, $data); - return $data; - } } /** @@ -554,3 +430,4 @@ class Object { * // ENFORCE STRONG_CREATE */ Object::useCustomClass('Datetime','SSDatetime',true); +?> diff --git a/core/Requirements.php b/core/Requirements.php index 6d1ae7715..bee2d7679 100644 --- a/core/Requirements.php +++ b/core/Requirements.php @@ -1,15 +1,8 @@ $dummy) { + foreach(Requirements::$javascript as $file => $dummy) { if(substr($file,0,7) == 'http://' || Director::fileExists($file)) { $requirements .= "\n"; } } - if(self::$customScript) { + if(Requirements::$customScript) { $requirements .= "\n"; } - foreach(array_diff_key(self::$css,self::$blocked) as $file => $params) { + foreach(Requirements::$css as $file => $params) { if(Director::fileExists($file)) { $media = (isset($params['media'])) ? " media=\"{$params['media']}\"" : ""; $requirements .= "\n"; } } - foreach(array_diff_key(self::$customCSS,self::$blocked) as $css) { + foreach(Requirements::$customCSS as $css) { $requirements .= "\n"; } - $requirements .= self::$customHeadTags; + $requirements .= Requirements::$customHeadTags; if(isset($_GET['debug_profile'])) Profiler::unmark("Requirements::includeInHTML"); return eregi_replace("(]*>)", $requirements . "\\1", $content); diff --git a/core/SSViewer.php b/core/SSViewer.php index c8534a417..0042915e1 100644 --- a/core/SSViewer.php +++ b/core/SSViewer.php @@ -1,10 +1,5 @@ ', '', $content); - // i18n - sprintf => "sprintf(_t(...),$argument)" - // CAUTION: No spaces allowed between arguments! - $content = ereg_replace('<' . '% +sprintf\(_t\((\'([^\']*)\'|"([^"]*)")(([^)]|\)[^ ]|\) +[^% ])*)\),\<\?= +([^\?]*) +\?\>) +%' . '>', '', $content); - // isnt valid html? !? $content = ereg_replace('<' . '% +base_tag +%' . '>', '', $content); @@ -335,11 +324,7 @@ class SSViewer extends Object { } } -/** - * Special SSViewer that will process a template passed as a string, rather than a filename. - * @package sapphire - * @subpackage view - */ + class SSViewer_FromString extends SSViewer { protected $content; diff --git a/core/Session.php b/core/Session.php index 0d9a1e286..8f94ec529 100644 --- a/core/Session.php +++ b/core/Session.php @@ -1,10 +1,5 @@ myVar = 'XYZ' would be fine, as would Session::data->myVar. What about the equivalent + * of Session::get('member.abc')? Are the explicit accessor methods acceptable? Do we need a + * broader spectrum of functions, such as Session::inc("cart.$productID", 2)? And what should + * Session::get("cart") then return? An array? + * + * @todo Decide whether this class is really necessary, and if so, overhaul it. Perhaps use + * __set() and __get() on an instance, rather than static functions? */ class Session { public static function set($name, $val) { @@ -44,7 +45,6 @@ class Session { * Session data */ protected $data = array(); - protected $changedData = array(); /** * Create a new session object, with the given starting data @@ -61,15 +61,12 @@ class Session { // We still want to do this even if we have strict path checking for legacy code $var = &$this->data; - $diffVar = &$this->changedData; foreach($names as $n) { $var = &$var[$n]; - $diffVar = &$diffVar[$n]; } $var = $val; - $diffVar = $val; } public function inst_addToArray($name, $val) { @@ -77,15 +74,12 @@ class Session { // We still want to do this even if we have strict path checking for legacy code $var = &$this->data; - $diffVar = &$this->changedData; foreach($names as $n) { $var = &$var[$n]; - $diffVar = &$diffVar[$n]; } $var[] = $val; - $diffVar[sizeof($var)-1] = $val; } public function inst_get($name) { @@ -112,44 +106,26 @@ class Session { // We still want to do this even if we have strict path checking for legacy code $var = &$this->data; - $diffVar = &$this->changedData; foreach($names as $n) { $var = &$var[$n]; - $diffVar = &$diffVar[$n]; } $var = null; - $diffVar = null; } public function inst_getAll() { return $this->data; } - /** - * Save data to session - * Only save the changes, so that anyone manipulating $_SESSION directly doesn't get burned. - */ public function inst_save() { - $this->recursivelyApply($this->changedData, $_SESSION); - } - - /** - * Recursively apply the changes represented in $data to $dest. - * Used to update $_SESSION - */ - protected function recursivelyApply($data, &$dest) { - foreach($data as $k => $v) { - if(is_array($v)) { - if(!isset($dest[$k])) $dest[$k] = array(); - $this->recursivelyApply($v, $dest[$k]); - } else { - $dest[$k] = $v; - } + // Save the updated session back + foreach($this->data as $k => $v) { + $_SESSION[$k] = $v; } } + /** * Sets the appropriate form message in session, with type. This will be shown once, * for the form specified. diff --git a/core/ViewableData.php b/core/ViewableData.php index 2462b4658..3cabebae2 100644 --- a/core/ViewableData.php +++ b/core/ViewableData.php @@ -2,7 +2,7 @@ /** * @package sapphire - * @subpackage view + * @subpackage core */ /** @@ -15,8 +15,6 @@ * * ViewableData cover page controls, controllers, and data objects. It's the basic unit of * data exchange. More specifically, it's anything that can be put into a view. - * @package sapphire - * @subpackage view */ class ViewableData extends Object implements Iterator { /** @@ -270,20 +268,6 @@ class ViewableData extends Object implements Iterator { } } - /** - * Return the string-format type for the given field. - * - * @usedby ViewableData::XML_val() - * @param string $fieldName - * @return string 'xml'|'raw' - */ - function escapeTypeForField($fieldName) { - $helperPair = $this->castingHelperPair($fieldName); - $castedClass = $helperPair['className']; - if(!$castedClass || $castedClass == 'HTMLText' || $castedClass == 'HTMLVarchar') return "xml"; - else return "raw"; - } - /** * Return the object version of the given field/method. * @param string $fieldName The name of the field/method. @@ -417,8 +401,18 @@ class ViewableData extends Object implements Iterator { Profiler::mark('casting cost'); } - // Case 2: Check if the value is raw and must be made XML-safe - if($this->escapeTypeForField($fieldName) != 'xml') $val = Convert::raw2xml($val); + $helperPair = $this->castingHelperPair($fieldName); + $castedClass = $helperPair['className']; + + // Note: these probably shouldn't be hard-coded. But right now it's not a problem, and I don't + // want to over-engineer + if(!$castedClass || $castedClass == 'HTMLText' || $castedClass == 'HTMLVarchar' || $castedClass == 'Text') { + // Case 2: the value is already XML-safe, just return it + + } else { + // Case 3: the value is raw and must be made XML-safe + $val = Convert::raw2xml($val); + } if(isset($_GET['debug_profile'])) { Profiler::unmark('casting cost'); @@ -687,22 +681,6 @@ class ViewableData extends Object implements Iterator { function CurrentMember() { return Member::currentUser(); } - - /** - * Returns the Security ID. - * This is used to prevent CRSF attacks in forms. - * @return int - */ - function SecurityID() { - if(Session::get('SecurityID')) { - $securityID = Session::get('SecurityID'); - } else { - $securityID = rand(); - Session::set('SecurityID', $securityID); - } - - return $securityID; - } /** * Checks if the current user has the given permission. @@ -762,16 +740,6 @@ class ViewableData extends Object implements Iterator { return Director::absoluteBaseURL(); } - /** - * When rendering some objects it is necessary to iterate over the object being rendered, to - * do this, you need access to itself. - * - * @return ViewableData - */ - function Me() { - return $this; - } - /** * Return a Debugger object. * This is set up like so that you can put $Debug.Content into your template to get debugging @@ -889,9 +857,7 @@ class ViewableData extends Object implements Iterator { * Object-casting information for class methods * @var mixed */ - public static $casting = array( - 'BaseHref' => 'Varchar' - ); + public static $casting = null; /** * Keep a record of the parent node of this data node. @@ -909,8 +875,6 @@ class ViewableData extends Object implements Iterator { /** * A ViewableData object that has been customised with extra data. Use * ViewableData->customise() to create. - * @package sapphire - * @subpackage view */ class ViewableData_Customised extends ViewableData { public function castingHelperPair($field) { @@ -1017,8 +981,6 @@ class ViewableData_Customised extends ViewableData { /** * A ViewableData object that has been customised with an extra object. Use * ViewableData->customise() to create. - * @package sapphire - * @subpackage view */ class ViewableData_ObjectCustomised extends ViewableData { function __construct($obj, $extraObj) { @@ -1088,8 +1050,6 @@ class ViewableData_ObjectCustomised extends ViewableData { /** * Debugger helper. - * @package sapphire - * @subpackage view * @todo Finish this off */ class ViewableData_Debugger extends ViewableData { diff --git a/core/control/ContentController.php b/core/control/ContentController.php index 716f9c7c2..16e8c7c42 100644 --- a/core/control/ContentController.php +++ b/core/control/ContentController.php @@ -1,10 +1,4 @@ data(); + $stack = array($parent); + while($parent = $parent->Parent) { + array_unshift($stack, $parent); + } + + return isset($stack[$level-1]) ? $stack[$level-1] : null; + } public function Menu($level) { return $this->getMenu($level); @@ -232,17 +237,17 @@ JS $archiveLink = "Archived Site"; $liveLink = "Published Site"; $stageLink = "Draft Site"; - $message = "
Archived site from
" . $dateObj->Nice() . "
"; + $message = "
Archived site from
" . $dateObj->Nice() . "
"; } else if(Versioned::current_stage() == 'Stage') { $stageLink = "Draft Site"; $liveLink = "Published Site"; - $message = "
DRAFT SITE
"; + $message = "
DRAFT SITE
"; } else { $liveLink = "Published Site"; $stageLink = "Draft Site"; - $message = "
PUBLISHED SITE
"; + $message = "
PUBLISHED SITE
"; } if($member) { diff --git a/core/control/ContentNegotiator.php b/core/control/ContentNegotiator.php index 423982c41..b8a65406e 100755 --- a/core/control/ContentNegotiator.php +++ b/core/control/ContentNegotiator.php @@ -1,14 +1,8 @@ $mime) { - $regExp = '/' . str_replace(array('+','/'),array('\+','\/'), $mime) . '(;q=(\d+\.\d+))?/i'; - if (isset($_SERVER['HTTP_ACCEPT']) && preg_match($regExp, $_SERVER['HTTP_ACCEPT'], $matches)) { - $preference = isset($matches[2]) ? $matches[2] : 1; - if(!isset($q[$preference])) $q[$preference] = $format; - } + foreach($mimes as $format => $mime) { + $regExp = '/' . str_replace(array('+','/'),array('\+','\/'), $mime) . '(;q=(\d+\.\d+))?/i'; + if (preg_match($regExp, $_SERVER['HTTP_ACCEPT'], $matches)) { + $preference = isset($matches[2]) ? $matches[2] : 1; + if(!isset($q[$preference])) $q[$preference] = $format; } + } - if($q) { - // Get the preferred format - krsort($q); - $chosenFormat = reset($q); - } else { - $chosenFormat = "html"; - } + if($q) { + // Get the preferred format + krsort($q); + $chosenFormat = reset($q); + } else { + $chosenFormat = "html"; } } diff --git a/core/control/Controller.php b/core/control/Controller.php index 489696991..989873d0b 100644 --- a/core/control/Controller.php +++ b/core/control/Controller.php @@ -1,10 +1,5 @@ - * array( - * 'someaction', // someaction can be accessed by anyone, any time - * 'otheraction' => true, // So can otheraction - * 'restrictedaction' => 'ADMIN', // restrictedaction can only be people with ADMIN privilege - * 'complexaction' '->canComplexAction' // complexaction can only be accessed if $this->canComplexAction() returns true - * ); - * - */ - static $allowed_actions = null; - protected $urlParams; protected $requestParams; @@ -61,7 +39,7 @@ class Controller extends ViewableData { } /** - * @return array The parameters extracted from the URL by the {@link Director}. + * @return */ function getURLParams() { return $this->urlParams; @@ -76,32 +54,11 @@ class Controller extends ViewableData { } /** - * Executes this controller, and return an {@link HTTPResponse} object with the result. - * - * This method first does a few set-up activities: - * - Push this controller ont to the controller stack - see {@link Controller::curr()} for information about this. - * - Call {@link init()} - * - * Then it looks for the action method. The action is taken from $this->urlParams['Action'] - for this reason, it's important - * to have $Action included in your Director rule - * - * If $requestParams['executeForm'] is set, then the Controller assumes that we're processing a form. This is usually - * set by adding ?executeForm=XXX to the form's action URL. Form processing differs in the following ways: - * - The action name will be the name of the button clicked. If no button-click can be detected, the first button in the - * list will be assumed. - * - If the given action method doesn't exist on the controller, Controller will look for that method on the Form object. - * this lets developers package both a form and its action handlers in a single subclass of Form. - * - * NOTE: You should rarely need to overload run() - this kind of change is only really appropriate for things like nested - * controllers - {@link ModelAsController} and {@link RootURLController} are two examples here. If you want to make more - * orthodox functionality, it's better to overload {@link init()} or {@link index()}. - * - * - * * Execute the appropriate action handler. If none is given, use defaultAction to display * a template. The default action will be appropriate in most cases where displaying data * is the core goal; the Viewer can call methods on the controller to get the data it needs. * + * @param array $urlParams named parameters extracted from the URL, including Action. * @param array $requestParams GET and POST variables. * @return HTTPResponse The response that this controller produces, including HTTP headers such as redirection info */ @@ -113,13 +70,7 @@ class Controller extends ViewableData { $this->response = new HTTPResponse(); $this->requestParams = $requestParams; - $this->action = isset($this->urlParams['Action']) ? strtolower(str_replace("-","_",$this->urlParams['Action'])) : ""; - if(!$this->action) $this->action = 'index'; - - // Check security on the controller - if(!$this->checkAccessAction($this->action)) { - user_error("Disallowed action: '$this->action' on controller '$this->class'", E_USER_ERROR); - } + $this->action = isset($this->urlParams['Action']) ? str_replace("-","_",$this->urlParams['Action']) : "index"; // Init $this->baseInitCalled = false; @@ -162,7 +113,6 @@ class Controller extends ViewableData { // Create the form object $form = $formController; - $formObjParts = explode('.', $this->requestParams['executeForm']); foreach($formObjParts as $formMethod){ if(isset($_GET['debug_profile'])) Profiler::mark("Calling $formMethod", "on $form->class"); @@ -171,7 +121,6 @@ class Controller extends ViewableData { if(!$form) break; //user_error("Form method '" . $this->requestParams['executeForm'] . "' returns null in controller class '$this->class' ($_SERVER[REQUEST_URI])", E_USER_ERROR); } - // Populate the form if(isset($_GET['debug_profile'])) Profiler::mark("Controller", "populate form"); if($form){ @@ -360,11 +309,10 @@ class Controller extends ViewableData { } /** - * @deprecated use Controller::curr() instead + * Deprecated - use Controller::curr() instead * @returns Controller */ public static function currentController() { - user_error('Controller::currentController() is deprecated. Use Controller::curr() instead.', E_USER_NOTICE); return self::curr(); } @@ -483,10 +431,6 @@ class Controller extends ViewableData { * Handle redirection */ function redirect($url) { - if($this->response->getHeader('Location')) { - user_error("Already directed to " . $this->response->getHeader('Location') . "; now trying to direct to $url", E_USER_ERROR); - } - // Attach site-root to relative links, if they have a slash in them if($url == "" || $url[0] == '?' || (substr($url,0,4) != "http" && $url[0] != "/" && strpos($url,'/') !== false)){ $url = Director::baseURL() . $url; @@ -529,45 +473,6 @@ class Controller extends ViewableData { ); } - /** - * Check thAT - */ - function checkAccessAction($action) { - // Collate self::$allowed_actions from this class and all parent classes - $access = null; - $className = $this->class; - while($className != 'Controller') { - // Merge any non-null parts onto $access. - $accessPart = eval("return $className::\$allowed_actions;"); - if($accessPart !== null) $access = array_merge((array)$access, $accessPart); - - // Build an array of parts for checking if part[0] == part[1], which means that this class doesn't directly define it. - $accessParts[] = $accessPart; - - $className = get_parent_class($className); - } - - if($access === null || $accessParts[0] === $accessParts[1]) { - // user_error("Deprecated: please define static \$allowed_actions on your Controllers for security purposes", E_USER_NOTICE); - return true; - } - - if($action == 'index') return true; - - if(isset($access[$action])) { - $test = $access[$action]; - if($test === true) return true; - if(substr($test,0,2) == '->') { - $funcName = substr($test,2); - return $this->$funcName(); - } - if(Permission::check($test)) return true; - } else if((($key = array_search($action, $access)) !== false) && is_numeric($key)) { - return true; - } - return false; - } - } ?> diff --git a/core/control/Director.php b/core/control/Director.php index f5ad9f755..dc3059060 100644 --- a/core/control/Director.php +++ b/core/control/Director.php @@ -1,21 +1,11 @@ setSession(new Session($_SESSION)); + if(is_string($controllerObj) && substr($controllerObj,0,9) == 'redirect:') { - $response = new HTTPResponse(); - $response->redirect(substr($controllerObj, 9)); - $response->output(); + Director::redirect(substr($controllerObj, 9)); + } else if($controllerObj) { - // Load the session into the controller - $controllerObj->setSession(new Session($_SESSION)); - $response = $controllerObj->run(array_merge((array)$_GET, (array)$_POST, (array)$_FILES)); @@ -116,16 +88,9 @@ class Director { /** * Test a URL request, returning a response object. - * - * This method is the counterpart of Director::direct() that is used in functional testing. It will execute the URL given, - * * @param $url The URL to visit * @param $post The $_POST & $_FILES variables - * @param $session The {@link Session} object representing the current session. By passing the same object to multiple - * calls of Director::test(), you can simulate a peristed session. - * - * @uses getControllerForURL() The rule-lookup logic is handled by this. - * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call. + * @param $session The {@link Session} object representing the current session. */ function test($url, $post = null, $session = null) { $getVars = array(); @@ -275,7 +240,7 @@ class Director { * @return string If redirect() has been called, it will return the URL redirected to. Otherwise, it will return null; */ static function redirected_to() { - return Controller::curr()->redirectedTo(); + Controller::curr()->redirectedTo(); } /** @@ -363,7 +328,7 @@ class Director { } static function getAbsURL($url) { - return Director::baseURL() . $url; + return Director::baseURL() . '/' . $url; } static function getAbsFile($file) { @@ -436,18 +401,12 @@ class Director { } /** - * Returns true if this script is being run from the command line rather than the webserver. - * * @return boolean */ public static function is_cli() { return preg_match('/cli-script\.php/', $_SERVER['SCRIPT_NAME']); } - //////////////////////////////////////////////////////////////////////////////////////////// - // Site mode methods - //////////////////////////////////////////////////////////////////////////////////////////// - /** * Sets the site mode (if it is the public site or the cms), * and runs registered modules. @@ -480,35 +439,17 @@ class Director { self::$callbacks[$mode][] = $function; } - //////////////////////////////////////////////////////////////////////////////////////////// - // Environment type methods - //////////////////////////////////////////////////////////////////////////////////////////// - + static function set_dev_servers($servers) { + Director::$dev_servers = $servers; + } + + static function set_test_servers($servers) { + Director::$test_servers = $servers; + } + /** - * Set the environment type of the current site. - * - * Typically, a SilverStripe site have a number of environments: - * - development environments, such a copy on your local machine. - * - test sites, such as the one you show the client before going live. - * - the live site itself. - * - * The behaviour of these environments often varies slightly. For example, development sites may have errors dumped to the screen, - * and order confirmation emails might be sent to the developer instead of the client. - * - * To help with this, Sapphire support the notion of an environment type. The environment type can be dev, test, or live. - * - * You can set it explicitly with Director::set_environment_tpye(). Or you can use {@link Director::set_dev_servers()} and {@link Director::set_test_servers()} - * to set it implicitly, based on the value of $_SERVER['HTTP_HOST']. If the HTTP_HOST value is one of the servers listed, then - * the environment type will be test or dev. Otherwise, the environment type will be live. - * - * Dev mode can also be forced by putting ?isDev=1 in your URL, which will ask you to log in and then push the site into dev - * mode for the remainder of the session. Putting ?isDev=0 onto the URL can turn it back. - * Generally speaking, these methods will be called from your _config.php file. - * - * Once the environment type is set, it can be checked with {@link Director::isDev()}, {@link Director::isTest()}, and - * {@link Director::isLive()}. - * - * @param $et string The environment type: dev, test, or live. + * Force the environment type to be dev, test or live. + * This will affect the results of isLive, isDev, and isTest */ static function set_environment_type($et) { if($et != 'dev' && $et != 'test' && $et != 'live') { @@ -518,36 +459,10 @@ class Director { } } - /** - * Specify HTTP_HOST values that are development environments. - * For information about environment types, see {@link Director::set_environment_type()}. - * @param $servers array An array of HTTP_HOST values that should be treated as development environments. - */ - static function set_dev_servers($servers) { - Director::$dev_servers = $servers; - } - - /** - * Specify HTTP_HOST values that are test environments. - * For information about environment types, see {@link Director::set_environment_type()}. - * @param $servers array An array of HTTP_HOST values that should be treated as test environments. - */ - static function set_test_servers($servers) { - Director::$test_servers = $servers; - } - - /* - * This function will return true if the site is in a live environment. - * For information about environment types, see {@link Director::set_environment_type()}. - */ static function isLive() { return !(Director::isDev() || Director::isTest()); } - /** - * This function will return true if the site is in a development environment. - * For information about environment types, see {@link Director::set_environment_type()}. - */ static function isDev() { if(self::$environment_type) return self::$environment_type == 'dev'; @@ -576,10 +491,6 @@ class Director { return false; } - /** - * This function will return true if the site is in a test environment. - * For information about environment types, see {@link Director::set_environment_type()}. - */ static function isTest() { if(self::$environment_type) { return self::$environment_type == 'test'; @@ -594,28 +505,11 @@ class Director { } /** - * @deprecated use isDev() instead + * @todo These functions are deprecated, let's use isLive isDev and isTest instead. */ - function isDevMode() { - user_error('Director::isDevMode() is deprecated. Use Director::isDev() instead.', E_USER_NOTICE); - return self::isDev(); - } - - /** - * @deprecated use isTest() instead - */ - function isTestMode() { - user_error('Director::isTestMode() is deprecated. Use Director::isTest() instead.', E_USER_NOTICE); - return self::isTest(); - } - - /** - * @deprecated use isLive() instead - */ - function isLiveMode() { - user_error('Director::isLiveMode() is deprecated. Use Director::isLive() instead.', E_USER_NOTICE); - return self::isLive(); - } + function isDevMode() { return self::isDev(); } + function isTestMode() { return self::isTest(); } + function isLiveMode() { return self::isLive(); } } diff --git a/core/control/FormResponse.php b/core/control/FormResponse.php index 208328aa5..499305f51 100755 --- a/core/control/FormResponse.php +++ b/core/control/FormResponse.php @@ -1,10 +1,4 @@ - * @package sapphire - * @subpackage misc */ + class i18n extends Controller { /** @@ -310,7 +304,6 @@ class i18n extends Controller { 'lah_PK' => 'Lahnda (Pakistan)', 'lb_LU' => 'Luxembourgish (Luxembourg)', 'lbe_RU' => 'Lak (Russia)', - 'lc_XX' => 'LOLCAT', 'lez_RU' => 'Lezghian (Russia)', 'lg_UG' => 'Ganda (Uganda)', 'lij_IT' => 'Ligurian (Italy)', @@ -356,8 +349,8 @@ class i18n extends Controller { 'my_MM' => 'Burmese (Myanmar)', 'myv_RU' => 'Erzya (Russia)', 'na_NR' => 'Nauru (Nauru)', - 'nb_NO' => 'Norwegian Bokmal (Norway)', - 'nb_SJ' => 'Norwegian Bokmal (Svalbard and Jan Mayen)', + 'nb_NO' => 'Norwegian Bokm�l (Norway)', + 'nb_SJ' => 'Norwegian Bokm�l (Svalbard and Jan Mayen)', 'nd_ZW' => 'North Ndebele (Zimbabwe)', 'ndc_MZ' => 'Ndau (Mozambique)', 'ne_NP' => 'Nepali (Nepal)', @@ -845,9 +838,6 @@ class i18n extends Controller { } } - // sort by title (not locale) - asort($locales); - return $locales; } @@ -933,15 +923,14 @@ class i18n extends Controller { protected static function get_owner_module($name) { if (substr($name,-3) == '.ss') { global $_TEMPLATE_MANIFEST; - $path = str_replace('\\','/',Director::makeRelative(current($_TEMPLATE_MANIFEST[substr($name,0,-3)]))); - ereg('/([^/]+)/',$path,$module); + $path = current($_TEMPLATE_MANIFEST[substr($name,0,-3)]); + ereg(Director::baseFolder() . '/([^/]+)/',$path,$module); } else { global $_CLASS_MANIFEST; - if(strpos($name,'_') !== false) $name = strtok($name,'_'); - $path = str_replace('\\','/',Director::makeRelative($_CLASS_MANIFEST[$name])); - ereg('/([^/]+)/', $path, $module); + $path = $_CLASS_MANIFEST[$name]; + ereg(Director::baseFolder() . '/([^/]+)/',$path,$module); } - return ($module) ? $module[1] : false; + return $module[1]; } @@ -1253,18 +1242,13 @@ class i18n extends Controller { */ static function include_by_class($class) { $module = self::get_owner_module($class); - if(!$module) user_error("i18n::include_by_class: Class {$class} not found", E_USER_WARNING); - if (file_exists($file = Director::getAbsFile("$module/lang/". self::get_locale() . '.php'))) { include_once($file); } else if (self::get_locale() != 'en_US') { - $old = self::get_locale(); self::set_locale('en_US'); self::include_by_class($class); - self::set_locale($old); - - } else if(file_exists(Director::getAbsFile("$module/lang"))) { - user_error("i18n::include_by_class: Locale file $file should exist", E_USER_WARNING); + } else { + user_error("Locale file $file should exist", E_USER_WARNING); } } diff --git a/core/model/ComponentSet.php b/core/model/ComponentSet.php index 412667880..a3c54eaa1 100755 --- a/core/model/ComponentSet.php +++ b/core/model/ComponentSet.php @@ -1,14 +1,13 @@ childClass)) { - user_error("ComponentSet::add() Tried to add an '{$item->class}' object, but a '{$this->childClass}' object expected", E_USER_ERROR); + // TODO Should this allow subclasses? + if($item->class != $this->childClass) { + user_error("ComponentSet::add() Tried to add an '{$item->class}' object, but '{$this->childClass}' expected", E_USER_ERROR); } } else { $id = $item; @@ -195,8 +195,8 @@ class ComponentSet extends DataObjectSet { */ function remove($item) { if(is_object($item)) { - if(!is_a($item, $this->childClass)) { - user_error("ComponentSet::remove() Tried to remove an '{$item->class}' object, but a '{$this->childClass}' object expected", E_USER_ERROR); + if($item->class != $this->childClass && !is_subclass_of($item, $this->childClass)) { + user_error("ComponentSet::remove() Tried to remove an '{$item->class}' object, but '{$this->childClass}' expected", E_USER_ERROR); } } else { $item = DataObject::get_by_id($this->childClass, $item); diff --git a/core/model/CurrentPageIdentifier.php b/core/model/CurrentPageIdentifier.php index a91044d5c..ac2917aca 100644 --- a/core/model/CurrentPageIdentifier.php +++ b/core/model/CurrentPageIdentifier.php @@ -1,12 +1,12 @@ '; + print_r($databaseConfig); + echo ''; + //At this point, the database 'type' value should be the class name we want to instantiate. + //This class that gets called will create a value in the parameters array called pdo_type which + //is the name of the driver we want to use (ie, pgsql). + if(!isset($databaseConfig['type']) || empty($databaseConfig['type'])) { user_error("DB::connect: Not passed a valid database config", E_USER_ERROR); } - if (isset($databaseConfig['pdo']) && $databaseConfig['pdo']) { // TODO:pkrenn_remove + //if($databaseConfig['type']=='pdo'){ + // $conn = new PDODatabase($databaseConfig); + //} else { + $dbClass = $databaseConfig['type']; + echo 'creating a ' . $dbClass . ' instance!
'; + //This will shoot off to the PostgreSQLDatabase class... + $conn = new $dbClass($databaseConfig); + //} + /*if (isset($databaseConfig['pdo']) && $databaseConfig['pdo']) { // TODO:pkrenn_remove $conn = new PDODatabase($databaseConfig); } else { // TODO:pkrenn_remove begin $dbClass = $databaseConfig['type']; $conn = new $dbClass($databaseConfig); - } // TODO:pkrenn_remove end + } // TODO:pkrenn_remove end*/ + DB::setConn($conn); } @@ -67,6 +83,7 @@ class DB { * @return string $connect The connection string. **/ public function getConnect($parameters) { + echo 'the DB:$globalConn value is ' . DB::$globalConn . '
'; return DB::$globalConn->getConnect($parameters); } diff --git a/core/model/DataObject.php b/core/model/DataObject.php index fc1c82a2a..421147050 100644 --- a/core/model/DataObject.php +++ b/core/model/DataObject.php @@ -2,15 +2,13 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** * A single database record & abstract class for the data-access-model. - * @package sapphire - * @subpackage model */ -class DataObject extends ViewableData implements DataObjectInterface { +class DataObject extends Controller { /** * Data stored in this objects database record. An array indexed * by fieldname. @@ -95,7 +93,7 @@ class DataObject extends ViewableData implements DataObjectInterface { parent::__construct(); // Must be called after parent constructor - if(!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) { + if(!$isSingleton && !$this->record['ID']) { $this->populateDefaults(); } @@ -115,10 +113,13 @@ class DataObject extends ViewableData implements DataObjectInterface { /** * Create a duplicate of this node. - * Caution: Doesn't duplicate relations. * * @param $doWrite Perform a write() operation before returning the object. If this is true, it will create the duplicate in the database. + * * @return DataObject A duplicate of this node. The exact type will be the type of this node. + * Caution: Doesn't duplicate relations. + * + * @return DataObject */ function duplicate($doWrite = true) { $className = $this->class; @@ -231,27 +232,6 @@ class DataObject extends ViewableData implements DataObjectInterface { return $name; } - /** - * Get the translated user friendly singular name of this DataObject - * same as singular_name() but runs it through the translating function - * - * NOTE: - * It uses as default text if no translation found the $add_action when - * defined or else the default text is singular_name() - * - * Translating string is in the form: - * $this->class.SINGULARNAME - * Example: - * Page.SINGULARNAME - * - * @return string User friendly translated singular name of this DataObject - */ - function i18n_singular_name() - { - $name = (!empty($this->add_action)) ? $this->add_action : $this->singular_name(); - return _t($this->class.'.SINGULARNAME', $name); - } - /** * Get the user friendly plural name of this DataObject * If the name is not defined (by renaming $plural_name in the subclass), @@ -271,22 +251,6 @@ class DataObject extends ViewableData implements DataObjectInterface { } } - /** - * Get the translated user friendly plural name of this DataObject - * Same as plural_name but runs it through the translation function - * Translation string is in the form: - * $this->class.PLURALNAME - * Example: - * Page.PLURALNAME - * - * @return string User friendly translated plural name of this DataObject - */ - function i18n_plural_name() - { - $name = $this->plural_name(); - return _t($this->class.'.PLURALNAME', $name); - } - /** * Returns the associated database record - in this case, the object itself. * This is included so that you can call $dataOrController->data() and get a DataObject all the time. @@ -508,7 +472,6 @@ class DataObject extends ViewableData implements DataObjectInterface { public function write($showDebug = false, $forceInsert = false, $forceWrite = false) { $firstWrite = false; $this->brokenOnWrite = true; - $isNewRecord = false; $this->onBeforeWrite(); if($this->brokenOnWrite) { user_error("$this->class has a broken onBeforeWrite() function. Make sure that you call parent::onBeforeWrite().", E_USER_ERROR); @@ -530,96 +493,93 @@ class DataObject extends ViewableData implements DataObjectInterface { } // No changes made - if($this->changed) { - foreach($this->getClassAncestry() as $ancestor) { - if(ClassInfo::hasTable($ancestor)) - $ancestry[] = $ancestor; + if(!$this->changed) { + return $this->record['ID']; + } + + foreach($this->getClassAncestry() as $ancestor) { + if(ClassInfo::hasTable($ancestor)) + $ancestry[] = $ancestor; + } + + // Look for some changes to make + unset($this->changed['ID']); + + $hasChanges = false; + foreach($this->changed as $fieldName => $changed) { + if($changed) { + $hasChanges = true; + break; } + } - // Look for some changes to make - unset($this->changed['ID']); - - $hasChanges = false; - foreach($this->changed as $fieldName => $changed) { - if($changed) { - $hasChanges = true; - break; - } - } - - if($hasChanges || $forceWrite || !$this->record['ID']) { + if($hasChanges || $forceWrite || !$this->record['ID']) { - // New records have their insert into the base data table done first, so that they can pass the - // generated primary key on to the rest of the manipulation - if(!$this->record['ID'] && isset($ancestry[0])) { - $baseTable = $ancestry[0]; + // New records have their insert into the base data table done first, so that they can pass the + // generated primary key on to the rest of the manipulation + if(!$this->record['ID'] && isset($ancestry[0])) { + $baseTable = $ancestry[0]; - DB::query("INSERT INTO `{$baseTable}` SET Created = NOW()"); - $this->record['ID'] = DB::getGeneratedID($baseTable); - $this->changed['ID'] = 2; + DB::query("INSERT INTO `{$baseTable}` SET Created = NOW()"); + $this->record['ID'] = DB::getGeneratedID($baseTable); + $this->changed['ID'] = 2; - $isNewRecord = true; - } + $isNewRecord = true; + } - // Divvy up field saving into a number of database manipulations - if(isset($ancestry) && is_array($ancestry)) { - foreach($ancestry as $idx => $class) { - $classSingleton = singleton($class); - foreach($this->record as $fieldName => $value) { - if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->fieldExists($fieldName)) { - $manipulation[$class]['fields'][$fieldName] = $value ? ("'" . addslashes($value) . "'") : singleton($fieldType)->nullValue(); - } - } - - // Add the class name to the base object - if($idx == 0) { - $manipulation[$class]['fields']["LastEdited"] = "now()"; - if($dbCommand == 'insert') { - $manipulation[$class]['fields']["Created"] = "now()"; - //echo "
  • $this->class - " .get_class($this); - $manipulation[$class]['fields']["ClassName"] = "'$this->class'"; - } - } - - // In cases where there are no fields, this 'stub' will get picked up on - if(ClassInfo::hasTable($class)) { - $manipulation[$class]['command'] = $dbCommand; - $manipulation[$class]['id'] = $this->record['ID']; - } else { - unset($manipulation[$class]); + // Divvy up field saving into a number of database manipulations + if(isset($ancestry) && is_array($ancestry)) { + foreach($ancestry as $idx => $class) { + $classSingleton = singleton($class); + foreach($this->record as $fieldName => $value) { + if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->fieldExists($fieldName)) { + $manipulation[$class]['fields'][$fieldName] = $value ? ("'" . addslashes($value) . "'") : singleton($fieldType)->nullValue(); } } + + // Add the class name to the base object + if($idx == 0) { + $manipulation[$class]['fields']["LastEdited"] = "now()"; + if($dbCommand == 'insert') { + $manipulation[$class]['fields']["Created"] = "now()"; + //echo "
  • $this->class - " .get_class($this); + $manipulation[$class]['fields']["ClassName"] = "'$this->class'"; + } + } + + // In cases where there are no fields, this 'stub' will get picked up on + if(ClassInfo::hasTable($class)) { + $manipulation[$class]['command'] = $dbCommand; + $manipulation[$class]['id'] = $this->record['ID']; + } else { + unset($manipulation[$class]); + } } - - - $this->extend('augmentWrite', $manipulation); - // New records have their insert into the base data table done first, so that they can pass the - // generated ID on to the rest of the manipulation - if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) { - $manipulation[$baseTable]['command'] = 'update'; - } - DB::manipulate($manipulation); - - if(isset($isNewRecord) && $isNewRecord) { - DataObjectLog::addedObject($this); - } else { - DataObjectLog::changedObject($this); - } - - $this->changed = null; - } elseif ( $showDebug ) { - echo "Debug: no changes for DataObject
    "; } - // Clears the cache for this object so get_one returns the correct object. - $this->flushCache(); - if(!isset($this->record['Created'])) { - $this->record['Created'] = date('Y-m-d H:i:s'); + $this->extend('augmentWrite', $manipulation); + // New records have their insert into the base data table done first, so that they can pass the + // generated ID on to the rest of the manipulation + if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) { + $manipulation[$baseTable]['command'] = 'update'; } - $this->record['LastEdited'] = date('Y-m-d H:i:s'); + DB::manipulate($manipulation); + + if(isset($isNewRecord) && $isNewRecord) { + DataObjectLog::addedObject($this); + } else { + DataObjectLog::changedObject($this); + } + + $this->changed = null; + } elseif ( $showDebug ) { + echo "Debug: no changes for DataObject
    "; } + // Clears the cache for this object so get_one returns the correct object. + $this->flushCache(); + // Write ComponentSets as necessary if($this->components) { foreach($this->components as $component) { @@ -627,6 +587,11 @@ class DataObject extends ViewableData implements DataObjectInterface { } } + if(!isset($this->record['Created'])) { + $this->record['Created'] = date('Y-m-d H:i:s'); + } + $this->record['LastEdited'] = date('Y-m-d H:i:s'); + return $this->record['ID']; } @@ -765,42 +730,39 @@ class DataObject extends ViewableData implements DataObjectInterface { * @param string $sort A sort expression to be inserted into the ORDER BY clause. If omitted, the static field $default_sort on the component class will be used. * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned. * @param string $limit A limit expression to be inserted into the LIMIT clause + * @param string $having A filter to be inserted into the HAVING clause * * @return ComponentSet The components of the one-to-many relationship. */ - public function getComponents($componentName, $filter = "", $sort = "", $join = "", $limit = "") { - $result = null; - - $sum = md5("{$filter}_{$sort}_{$join}_{$limit}"); - if(isset($this->componentCache[$componentName . '_' . $sum]) && false != $this->componentCache[$componentName . '_' . $sum]) { - return $this->componentCache[$componentName . '_' . $sum]; - } + public function getComponents($componentName, $filter = "", $sort = "", $join = "", $limit = "", $having = "") { + $sum = md5("{$filter}_{$sort}_{$join}_{$limit}_{$having}"); + if(isset($this->componentCache[$componentName . '_' . $sum]) && false != $this->componentCache[$componentName . '_' . $sum]) { + return $this->componentCache[$componentName . '_' . $sum]; + } if(!$componentClass = $this->has_many($componentName)) { user_error("DataObject::getComponents(): Unknown 1-to-many component '$componentName' on class '$this->class'", E_USER_ERROR); } - + + $componentObj = singleton($componentClass); + $id = $this->getField("ID"); $joinField = $this->getComponentJoinField($componentName); - - if($this->isInDB()) { //Check to see whether we should query the db - $componentObj = singleton($componentClass); - $id = $this->getField("ID"); - - // get filter - $combinedFilter = "$joinField = '$id'"; - if($filter) $combinedFilter .= " AND {$filter}"; - - $result = $componentObj->instance_get($combinedFilter, $sort, $join, $limit, "ComponentSet"); - } - + + // get filter + $combinedFilter = "$joinField = '$id'"; + if($filter) $combinedFilter .= " AND {$filter}"; + + $result = $componentObj->instance_get($combinedFilter, $sort, $join, $limit, "ComponentSet", $having); if(!$result) { - // If this record isn't in the database, then we want to hold onto this specific ComponentSet, - // because it's the only copy of the data that we have. $result = new ComponentSet(); + } + $result->setComponentInfo("1-to-many", $this, null, null, $componentClass, $joinField); + + // If this record isn't in the database, then we want to hold onto this specific ComponentSet, + // because it's the only copy of the data that we have. + if(!$this->isInDB()) { $this->setComponent($componentName . '_' . $sum, $result); } - - $result->setComponentInfo("1-to-many", $this, null, null, $componentClass, $joinField); return $result; } @@ -859,13 +821,10 @@ class DataObject extends ViewableData implements DataObjectInterface { * @param string $componentName Name of the many-many component * @return ComponentSet The set of components * - * @todo Implement query-params + * TODO Implement query-params */ - public function getManyManyComponents($componentName, $filter = "", $sort = "", $join = "", $limit = "") { - $sum = md5("{$filter}_{$sort}_{$join}_{$limit}"); - if(isset($this->componentCache[$componentName . '_' . $sum]) && false != $this->componentCache[$componentName . '_' . $sum]) { - return $this->componentCache[$componentName . '_' . $sum]; - } + public function getManyManyComponents($componentName, $filter = "", $sort = "", $join = "", $limit = "", $having = "") { + if(isset($this->components[$componentName])) return $this->components[$componentName]; list($parentClass, $componentClass, $parentField, $componentField, $table) = $this->many_many($componentName); @@ -881,7 +840,8 @@ class DataObject extends ViewableData implements DataObjectInterface { "`$table`.$parentField = $this->ID", // filter $sort, $limit, - "INNER JOIN `$table` ON `$table`.$componentField = `$componentBaseClass`.ID" // join + "INNER JOIN `$table` ON `$table`.$componentField = `$componentBaseClass`.ID", // join + $having // having ); array_unshift($query->select, "`$table`.*"); @@ -899,12 +859,7 @@ class DataObject extends ViewableData implements DataObjectInterface { $result = new ComponentSet(); } $result->setComponentInfo("many-to-many", $this, $parentClass, $table, $componentClass); - - // If this record isn't in the database, then we want to hold onto this specific ComponentSet, - // because it's the only copy of the data that we have. - if(!$this->isInDB()) { - $this->setComponent($componentName . '_' . $sum, $result); - } + $this->components[$componentName] = $result; return $result; } @@ -1380,32 +1335,9 @@ class DataObject extends ViewableData implements DataObjectInterface { } $baseClass = array_shift($tableClasses); - $select = array("`$baseClass`.*"); - - // If sort contains a function call, let's move the sort clause into a separate selected field. - // Some versions of MySQL choke if you have a group function referenced directly in the ORDER BY - if($sort && strpos($sort,'(') !== false) { - // Sort can be "Col1 DESC|ASC, Col2 DESC|ASC", we need to handle that - $sortParts = explode(",", $sort); - foreach($sortParts as $i => $sortPart) { - $sortPart = trim($sortPart); - if(substr(strtolower($sortPart),-5) == ' desc') { - $select[] = substr($sortPart,0,-5) . " AS _SortColumn{$i}"; - $newSorts[] = "_SortColumn{$i} DESC"; - } else if(substr(strtolower($sortPart),-4) == ' asc') { - $select[] = substr($sortPart,0,-4) . " AS _SortColumn{$i}"; - $newSorts[] = "_SortColumn{$i} ASC"; - } else { - $select[] = "$sortPart AS _SortColumn{$i}"; - $newSorts[] = "_SortColumn{$i} ASC"; - } - } - - $sort = implode(", ", $newSorts); - } // Build our intial query - $query = new SQLQuery($select, "`$baseClass`", $filter, $sort); + $query = new SQLQuery(array("`$baseClass`.*"), "`$baseClass`", $filter, $sort); // Join all the tables if($tableClasses) { @@ -1469,10 +1401,7 @@ class DataObject extends ViewableData implements DataObjectInterface { } /** - * Get a bunch of fields in an HTML LI, like this: - * - name: value - * - name: value - * - name: value + * Get a bunch of fields in a list - a
      of
    • name: value
    • * * @return string The fields as an HTML unordered list */ @@ -1495,11 +1424,12 @@ class DataObject extends ViewableData implements DataObjectInterface { * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned. * @param string $limit A limit expression to be inserted into the LIMIT clause. * @param string $containerClass The container class to return the results in. + * @param string $having A filter to be inserted into the HAVING clause. * * @return mixed The objects matching the filter, in the class specified by $containerClass */ - public static function get($callerClass, $filter = "", $sort = "", $join = "", $limit = "", $containerClass = "DataObjectSet") { - return singleton($callerClass)->instance_get($filter, $sort, $join, $limit, $containerClass); + public static function get($callerClass, $filter = "", $sort = "", $join = "", $limit = "", $containerClass = "DataObjectSet", $having = "") { + return singleton($callerClass)->instance_get($filter, $sort, $join, $limit, $containerClass, $having); } /** @@ -1511,11 +1441,12 @@ class DataObject extends ViewableData implements DataObjectInterface { * @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned. * @param string $limit A limit expression to be inserted into the LIMIT clause. * @param string $containerClass The container class to return the results in. + * @param string $having A filter to be inserted into the HAVING clause. * * @return mixed The objects matching the filter, in the class specified by $containerClass */ - public function instance_get($filter = "", $sort = "", $join = "", $limit="", $containerClass = "DataObjectSet") { - $query = $this->extendedSQL($filter, $sort, $limit, $join); + public function instance_get($filter = "", $sort = "", $join = "", $limit="", $containerClass = "DataObjectSet", $having = "") { + $query = $this->extendedSQL($filter, $sort, $limit, $join, $having); $records = $query->execute(); $ret = $this->buildDataObjectSet($records, $containerClass, $query, $this->class); @@ -1559,6 +1490,8 @@ class DataObject extends ViewableData implements DataObjectInterface { * Return the first item matching the given query. * All calls to get_one() are cached. * + * TODO Caching doesn't respect sorting. + * * @param string $callerClass The class of objects to be returned * @param string $filter A filter to be inserted into the WHERE clause * @param boolean $cache Use caching @@ -1567,17 +1500,16 @@ class DataObject extends ViewableData implements DataObjectInterface { * @return DataObject The first item matching the query */ public static function get_one($callerClass, $filter = "", $cache = true, $orderby = "") { - $sum = md5("{$filter}_{$orderby}"); - if(!$cache || !isset(DataObject::$cache_get_one[$callerClass][$sum]) || !DataObject::$cache_get_one[$callerClass][$sum] || DataObject::$cache_get_one[$callerClass][$sum]->destroyed) { + if(!$cache || !isset(DataObject::$cache_get_one[$callerClass][$filter]) || isset(DataObject::$cache_get_one[$callerClass][$filter]->destroyed)) { $item = singleton($callerClass)->instance_get_one($filter, $orderby); if($cache) { - DataObject::$cache_get_one[$callerClass][$sum] = $item; - if(!DataObject::$cache_get_one[$callerClass][$sum]) { - DataObject::$cache_get_one[$callerClass][$sum] = false; + DataObject::$cache_get_one[$callerClass][$filter] = $item; + if(!DataObject::$cache_get_one[$callerClass][$filter]) { + DataObject::$cache_get_one[$callerClass][$filter] = false; } } } - return $cache ? DataObject::$cache_get_one[$callerClass][$sum] : $item; + return $cache ? DataObject::$cache_get_one[$callerClass][$filter] : $item; } /** @@ -1656,15 +1588,10 @@ class DataObject extends ViewableData implements DataObjectInterface { */ public static function get_by_id($callerClass, $id) { if(is_numeric($id)) { - if(singleton($callerClass) instanceof DataObject) { - $tableClasses = ClassInfo::dataClassesFor($callerClass); - $baseClass = array_shift($tableClasses); - return DataObject::get_one($callerClass,"`$baseClass`.`ID` = $id"); - - // This simpler code will be used by non-DataObject classes that implement DataObjectInterface - } else { - return DataObject::get_one($callerClass,"`ID` = $id"); - } + $tableClasses = ClassInfo::dataClassesFor($callerClass); + $baseClass = array_shift($tableClasses); + + return DataObject::get_one($callerClass,"`$baseClass`.`ID` = $id"); } else { user_error("DataObject::get_by_id passed a non-numeric ID #$id", E_USER_WARNING); } @@ -1903,15 +1830,6 @@ class DataObject extends ViewableData implements DataObjectInterface { /** * one-to-many relationship definitions. * This is a map from component name to data type. - * - * Caution: Because this doesn't define any data structure itself, you should - * specify a $has_one relationship on the other end of the relationship. - * Also, if the $has_one relationship on the other end has multiple - * definitions of this class (e.g. two different relationships to the Member - * object), then you need to write a custom accessor (e.g. overload the - * function from the key of this array), because sapphire won't know which - * to access. - * * @var array */ public static $has_many = null; diff --git a/core/model/DataObjectDecorator.php b/core/model/DataObjectDecorator.php index 39700684d..239d16c98 100755 --- a/core/model/DataObjectDecorator.php +++ b/core/model/DataObjectDecorator.php @@ -2,7 +2,7 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ @@ -10,8 +10,6 @@ * Plug-ins for additional functionality in your DataObjects * * DataObject decorators add extra functionality to your data objects. - * @package sapphire - * @subpackage model */ abstract class DataObjectDecorator extends Extension { diff --git a/core/model/DataObjectLog.php b/core/model/DataObjectLog.php index 8448dfcf9..d7076ab1f 100755 --- a/core/model/DataObjectLog.php +++ b/core/model/DataObjectLog.php @@ -2,15 +2,13 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** * A DataObjectLog is a log of changes that have been made to the database in this session. * It was designed to help with updates to the CMS tree, and could be used wherever an Ajax call * needs to update a complex on-screen representation of your data. - * @package sapphire - * @subpackage model */ class DataObjectLog extends Object { /** diff --git a/core/model/DataObjectSet.php b/core/model/DataObjectSet.php index 7da57579a..65a1331b3 100644 --- a/core/model/DataObjectSet.php +++ b/core/model/DataObjectSet.php @@ -2,14 +2,11 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** - * This class represents a set of {@link ViewableData} subclasses (mostly {@link DataObject} or {@link ArrayData}. - * It is used by the ORM-layer of Silverstripe to return query-results from {@link SQLQuery}. - * @package sapphire - * @subpackage model + * This class represents a set of database objects, such as the results of a query */ class DataObjectSet extends ViewableData implements Iterator { /** @@ -63,33 +60,17 @@ class DataObjectSet extends ViewableData implements Iterator { protected $paginationGetVar = "start"; /** - * Create a new DataObjectSet. If you pass one or more arguments, it will try to convert them into {@link ArrayData} objects. - * @todo Does NOT automatically convert objects with complex datatypes (e.g. converting arrays within an objects to its own DataObjectSet) - * - * @param ViewableData|array|mixed $items Parameters to use in this set, either as an associative array, object with simple properties, or as multiple parameters. + * Create a new DataObjectSet. + * @param array|DataObject,... $items The DataObjects to use in this set, either as an array or as multiple variables */ - public function __construct($items = null) { + public function __construct($items = null, $otherArg = null) { if($items) { - // if the first parameter is not an array, or we have more than one parameter, collate all parameters to an array - // otherwise use the passed array - $itemsArr = (!is_array($items) || count(func_get_args()) > 1) ? func_get_args() : $items; - - // We now have support for using the key of a data object set - foreach($itemsArr as $i => $item) { - if(is_subclass_of($item, 'ViewableData')) { - $this->items[$i] = $item; - } elseif(is_object($item) || ArrayLib::is_associative($item)) { - $this->items[$i] = new ArrayData($item); - } else { - user_error( - "DataObjectSet::__construct: Passed item #{$i} is not an object or associative array, - can't be properly iterated on in templates", - E_USER_WARNING - ); - $this->items[$i] = $item; - } + if (is_array($items)) { + // We now have support for using the key of a data object set + $this->items = $items; + } else if($allArgs = func_get_args()) { + $this->items = $allArgs; } - $this->current = $this->prepareItem(current($this->items)); } parent::__construct(); @@ -328,18 +309,6 @@ class DataObjectSet extends ViewableData implements Iterator { return $this->TotalPages() > 1; } - function FirstItem() { - return isset($this->pageStart) ? $this->pageStart + 1 : 1; - } - - function LastItem() { - if(isset($this->pageStart)) { - return min($this->pageStart + $this->pageLength, $this->totalSize); - } else { - return min($this->pageLength, $this->totalSize); - } - } - /** * Returns the URL of the previous page. * @return string @@ -390,8 +359,8 @@ class DataObjectSet extends ViewableData implements Iterator { * @param string $key Key to index this DataObject by. */ public function insertFirst($item, $key = null) { - if($key == null) { - array_unshift($this->items, $item); + if($key != null) { + array_shift($this->items, $item); } else { // Not very efficient :-( $newItems = array(); @@ -405,7 +374,6 @@ class DataObjectSet extends ViewableData implements Iterator { * @deprecated Use merge() */ public function append(DataObjectSet $doset){ - user_error('DataObjectSet::append() is deprecated. Use DataObjectSet::merge() instead.', E_USER_NOTICE); foreach($doset as $item){ $this->push($item); } @@ -643,7 +611,7 @@ class DataObjectSet extends ViewableData implements Iterator { /** * Returns the dataset as an array of ID => Title. * - * @todo Duplication from toDropdownMap() + * TODO Duplication from toDropdownMap() * * @param string $key The field you wish to use as a key for the array * @param string $value The field or method you wish to use to get values for the map @@ -1038,4 +1006,4 @@ function column_sort_callback_basic($a, $b) { return $result; } -?> +?> \ No newline at end of file diff --git a/core/model/Database.php b/core/model/Database.php index 9020f7669..a3907811b 100755 --- a/core/model/Database.php +++ b/core/model/Database.php @@ -2,14 +2,12 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** * Abstract database connectivity class. * Sub-classes of this implement the actual database connection libraries - * @package sapphire - * @subpackage model */ abstract class Database extends Object { /** @@ -51,20 +49,20 @@ abstract class Database extends Object { * Create the database and connect to it. This can be called if the * initial database connection is not successful because the database * does not exist. - * - * It takes no parameters, and should create the database from the information - * specified in the constructor. - * + * @param string $connect Connection string + * @param string $username Database username + * @param string $password Database Password + * @param string $database Database to which to create * @return boolean Returns true if successful */ - abstract function createDatabase(); + abstract function createDatabase($connect, $username, $password, $database); /** * Build the connection string from input * @param array $parameters The connection details * @return string $connect The connection string **/ - abstract function getConnect($parameters); + abstract function getConnect(); /** * Create a new table. @@ -309,38 +307,6 @@ abstract class Database extends Object { Profiler::unmark('createField'); Database::alteration_message("Field $table.$field: created as $spec","created"); } else if($this->fieldList[$table][$field] != $spec) { - // If enums are being modified, then we need to fix existing data in the table. - // Update any records where the enum is set to a legacy value to be set to the default. - // One hard-coded exception is SiteTree - the default for this is Page. - if(substr($spec, 0, 4) == "enum") { - $new = substr($spec, 5); - $old = substr($this->fieldList[$table][$field], 5); - $new = substr($new, 0, strpos($new, ')')); - $old = substr($old, 0, strpos($old, ')')); - $new = str_replace("'", '', $new); - $old = str_replace("'", '', $old); - $new = explode(',', $new); - $old = explode(',', $old); - $holder = array(); - foreach($old as $check) { - if(!in_array($check, $new)) { - $holder[] = $check; - } - } - if(count($holder)) { - $default = explode('default ', $spec); - $default = $default[1]; - if($default == "'SiteTree'") $default = "'Page'"; - $query = "UPDATE `$table` SET $field=$default WHERE $field IN ("; - for($i=0;$i+1transAlterField($table, $field, $spec); Profiler::unmark('alterField'); @@ -402,11 +368,11 @@ abstract class Database extends Object { } } - /** Replaces "\'\'" with "null", recursively walks through the given array. + /** Replaces "''" with "null", recursively walks through the given array. * @param string $array Array where the replacement should happen */ static function replace_with_null(&$array) { - $array = ereg_replace('= *\'\'', "= null", $array); + $array = str_replace('\'\'', "null", $array); if(is_array($array)) { foreach($array as $key => $value) { @@ -477,8 +443,6 @@ abstract class Database extends Object { * Primarily, the Query class takes care of the iterator plumbing, letting the subclasses focusing * on providing the specific data-access methods that are required: {@link nextRecord()}, {@link numRecords()} * and {@link seek()} - * @package sapphire - * @subpackage model */ abstract class Query extends Object implements Iterator { /** diff --git a/core/model/DatabaseAdmin.php b/core/model/DatabaseAdmin.php index 9aa8e7ebd..fe9357f36 100644 --- a/core/model/DatabaseAdmin.php +++ b/core/model/DatabaseAdmin.php @@ -4,7 +4,7 @@ * Database Administration * * @package sapphire - * @subpackage model + * @subpackage core */ @@ -20,19 +20,9 @@ require_once("core/model/DB.php"); * * Utility functions for administrating the database. These can be accessed * via URL, e.g. http://www.yourdomain.com/db/build. - * @package sapphire - * @subpackage model */ class DatabaseAdmin extends Controller { - /// SECURITY /// - static $allowed_actions = array( - 'build', - 'cleanup', - 'testinstall', - 'import' - ); - /** * Get the data classes, grouped by their root class * diff --git a/core/model/ErrorPage.php b/core/model/ErrorPage.php index ae775998f..b1602c04b 100755 --- a/core/model/ErrorPage.php +++ b/core/model/ErrorPage.php @@ -1,12 +1,12 @@ ErrorCode = 404; - $errorpage->Title = _t('ErrorPage.DEFAULTERRORPAGETITLE', 'Page not found'); + $errorpage->Title = "Page not found"; $errorpage->URLSegment = "page-not-found"; $errorpage->ShowInMenus = false; - $errorpage->Content = _t('ErrorPage.DEFAULTERRORPAGECONTENT', '

      Sorry, it seems you were trying to access a page that doesn\'t exist.

      Please check the spelling of the URL you were trying to access and try again.

      '); + $errorpage->Content = "

      Sorry, it seems you were trying to access a page that doesn't exist.

      Please check the spelling of the URL you were trying to access and try again.

      "; $errorpage->Status = "New page"; $errorpage->write(); // Don't publish, as the manifest may not be built yet @@ -50,29 +50,8 @@ class ErrorPage extends Page { "ErrorCode", _t('ErrorPage.CODE', "Error code"), array( - 400 => _t('ErrorPage.400', '400 - Bad Request'), - 401 => _t('ErrorPage.401', '401 - Unauthorized'), - 403 => _t('ErrorPage.403', '403 - Forbidden'), - 404 => _t('ErrorPage.404', '404 - Not Found'), - 405 => _t('ErrorPage.405', '405 - Method Not Allowed'), - 406 => _t('ErrorPage.406', '406 - Not Acceptable'), - 407 => _t('ErrorPage.407', '407 - Proxy Authentication Required'), - 408 => _t('ErrorPage.408', '408 - Request Timeout'), - 409 => _t('ErrorPage.409', '409 - Conflict'), - 410 => _t('ErrorPage.410', '410 - Gone'), - 411 => _t('ErrorPage.411', '411 - Length Required'), - 412 => _t('ErrorPage.412', '412 - Precondition Failed'), - 413 => _t('ErrorPage.413', '413 - Request Entity Too Large'), - 414 => _t('ErrorPage.414', '414 - Request-URI Too Long'), - 415 => _t('ErrorPage.415', '415 - Unsupported Media Type'), - 416 => _t('ErrorPage.416', '416 - Request Range Not Satisfiable'), - 417 => _t('ErrorPage.417', '417 - Expectation Failed'), - 500 => _t('ErrorPage.500', '500 - Internal Server Error'), - 501 => _t('ErrorPage.501', '501 - Not Implemented'), - 502 => _t('ErrorPage.502', '502 - Bad Gateway'), - 503 => _t('ErrorPage.503', '503 - Service Unavailable'), - 504 => _t('ErrorPage.504', '504 - Gateway Timeout'), - 505 => _t('ErrorPage.505', '505 - HTTP Version Not Supported'), + 404 => "404 - Page not found", + 500 => "500 - Server error" ) ), "Content" @@ -125,7 +104,6 @@ class ErrorPage extends Page { /** * Controller for ErrorPages. - * @package cms */ class ErrorPage_Controller extends Page_Controller { public function init() { diff --git a/core/model/GhostPage.php b/core/model/GhostPage.php index f9f74b307..801ee3660 100755 --- a/core/model/GhostPage.php +++ b/core/model/GhostPage.php @@ -1,13 +1,13 @@ . */ public function partialTreeAsUL($minCount = 50) { $children = $this->owner->AllChildren(); @@ -335,7 +333,7 @@ class Hierarchy extends DataObjectDecorator { continue; } $idList[] = $child->ID; - $child->extInstance('Hierarchy')->loadDescendantIDListInto($idList); + $child->loadDescendantIDListInto($idList); } } } @@ -524,7 +522,7 @@ class Hierarchy extends DataObjectDecorator { * Get the next node in the tree of the type. If there is no instance of the className descended from this node, * then search the parents. * - * @todo Write! + * TODO Write! */ public function naturalPrev( $className, $afterNode = null ) { return null; diff --git a/core/model/Image.php b/core/model/Image.php index de190de05..a426b5555 100755 --- a/core/model/Image.php +++ b/core/model/Image.php @@ -2,13 +2,11 @@ /** * @package sapphire - * @subpackage filesystem + * @subpackage core */ /** * Represents an image attached to a page. - * @package sapphire - * @subpackage filesystem */ class Image extends File { /** @@ -264,9 +262,9 @@ class Image extends File { * Generate an image on the specified format. It will save the image * at the location specified by cacheFilename(). The image will be generated * using the specific 'generate' method for the specified format. - * @param string $format Name of the format to generate. - * @param string $arg1 Argument to pass to the generate method. - * @param string $arg2 A second argument to pass to the generate method. + * @var string $format Name of the format to generate. + * @var string $arg1 Argument to pass to the generate method. + * @var string $arg2 A second argument to pass to the generate method. */ function generateFormattedImage($format, $arg1 = null, $arg2 = null) { $cacheFile = $this->cacheFilename($format, $arg1, $arg2); @@ -367,11 +365,7 @@ class Image extends File { } /** - * A resized / processed {@link Image} object. - * When Image object are processed or resized, a suitable Image_Cached object is returned, pointing to the - * cached copy of the processed image. - * @package sapphire - * @subpackage filesystem + * Image not stored in the database, that is just a cached resampled image */ class Image_Cached extends Image { /** @@ -399,12 +393,6 @@ class Image_Cached extends Image { } } -/** - * A db field type designed to help save images. - * @deprecated Use a has_one relationship pointing to the file table instead. - * @package sapphire - * @subpackage filesystem - */ class Image_Saver extends DBField { function saveInto($record) { $image = $record->getComponent($this->name); @@ -424,17 +412,14 @@ class Image_Saver extends DBField { } /** - * Uploader support for the uploading anything which is a File or subclass of File, eg Image. - * @package sapphire - * @subpackage filesystem + * Uploader support for the uploading anything which is a File or subclass of + * File, eg Image. */ class Image_Uploader extends Controller { /** * Ensures the css is loaded for the iframe. */ function iframe() { - if(!Permission::check('ADMIN')) Security::permissionFailure($this); - Requirements::css("cms/css/Image_iframe.css"); return array(); } @@ -605,25 +590,34 @@ class Image_Uploader extends Controller { _t('ImageUploader.DELETE', 'Delete %s', PR_MEDIUM, 'Delete file/image'), $type ); - $form = new Form( + return new Form( $this, 'DeleteImageForm', new FieldSet( new HiddenField("Class", null, $this->urlParams['Class']), new HiddenField("ID", null, $this->urlParams['ID']), - new HiddenField("Field", null, $this->urlParams['Field']) + new HiddenField("Field", null, $this->urlParams['Field']), + new HeaderField($title), + new LabelField( + sprintf( + _t( + 'ImageUploader.CLICKREMOVE', + "Click the button below to remove this %s.", + PR_MEDIUM, + '... this image/file' + ), + $type + ) + ) ), new FieldSet( - $deleteAction = new ConfirmedFormAction( + new ConfirmedFormAction( "delete", $title, sprintf(_t('ImageUploader.REALLYDELETE', "Do you really want to remove this %s?"), $type) ) ) ); - $deleteAction->addExtraClass('delete'); - - return $form; } } @@ -638,7 +632,7 @@ class Image_Uploader extends Controller { } $owner = DataObject::get_by_id($data['Class'], $data['ID']); $fieldName = $data['Field'] . 'ID'; - + if($data['ImageSource'] == 'existing') { if(!$data['ExistingFile']) { // No image has been selected @@ -651,14 +645,6 @@ class Image_Uploader extends Controller { // Edit the class name, if applicable $existingFile = DataObject::get_by_id("File", $data['ExistingFile']); $desiredClass = $owner->has_one($data['Field']); - - // Unless specifically asked, we don't want the user to be able - // to select a folder - if(is_a($existingFile, 'Folder') && $desiredClass != 'Folder') { - Director::redirectBack(); - return; - } - if(!is_a($existingFile, $desiredClass)) { $existingFile->ClassName = $desiredClass; $existingFile->write(); @@ -704,8 +690,6 @@ class Image_Uploader extends Controller { * Flush all of the generated images. */ function flush() { - if(!Permission::check('ADMIN')) Security::permissionFailure($this); - $images = DataObject::get("Image",""); $numItems = 0; $num = 0; @@ -726,8 +710,6 @@ class Image_Uploader extends Controller { * @deprecated This function is only used to migrate content from old databases. */ function transferlegacycontent() { - if(!Permission::check('ADMIN')) Security::permissionFailure($this); - $images = DB::query("SELECT * FROM _obsolete_Image"); echo "

      Transferring images

      "; foreach($images as $image) { diff --git a/core/model/MySQLDatabase.php b/core/model/MySQLDatabase.php index 3468d1a0b..d025a49dc 100644 --- a/core/model/MySQLDatabase.php +++ b/core/model/MySQLDatabase.php @@ -2,13 +2,11 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** * MySQL connector class. - * @package sapphire - * @subpackage model */ class MySQLDatabase extends Database { /** @@ -32,10 +30,10 @@ class MySQLDatabase extends Database { /** * Connect to a MySQL database. * @param array $parameters An map of parameters, which should include: - * - server: The server, eg, localhost - * - username: The username to log on with - * - password: The password to log on with - * - database: The database to connect to + *
      • server: The server, eg, localhost
      • + *
      • username: The username to log on with
      • + *
      • password: The password to log on with
      • + *
      • database: The database to connect to
      • */ public function __construct($parameters) { $this->dbConn = mysql_connect($parameters['server'], $parameters['username'], $parameters['password']); @@ -129,7 +127,7 @@ class MySQLDatabase extends Database { return $this->active ? true : false; } - public function createDatabase() { + public function createDatabase($connect, $username, $password, $db) { $this->query("CREATE DATABASE $this->database"); $this->query("USE $this->database"); @@ -392,8 +390,6 @@ class MySQLDatabase extends Database { /** * A result-set from a MySQL database. - * @package sapphire - * @subpackage model */ class MySQLQuery extends Query { /** diff --git a/core/model/PDODatabase.php b/core/model/PDODatabase.php index 4cfe24e30..81b1b12cd 100644 --- a/core/model/PDODatabase.php +++ b/core/model/PDODatabase.php @@ -2,20 +2,18 @@ /** * @package sapphire - * @subpackage model + * @subpackage core */ /** * PDO (general database) connector class. - * @package sapphire - * @subpackage model */ class PDODatabase extends Database { /** * Connection to the DBMS. * @var resource */ - private $dbConn; + private $dbConn=null; /** * True if we are connected to a database. @@ -40,7 +38,7 @@ class PDODatabase extends Database { * Parameters used for creating a connection * @var array */ - private $param; + protected $param; /** * Connect to a database (MySQL, PostgreSQL, or MS SQL). @@ -53,20 +51,22 @@ class PDODatabase extends Database { *
      • password: The password to log on with
      • *
      • database: The database to connect to
      */ - public function __construct($parameters) { + public function __construct($parameters) { $this->param = $parameters; - $connect = self::getConnect($parameters); - $connectWithDB = $connect . ';dbname=' . $parameters['database']; - try { // Try connect to the database, if it does not exist, create it + $connect = $this->getConnect(); + //$connect=$this->getConnect($parameters); + $connectWithDB = $connect . ';dbname=' . $parameters['database']; + echo 'connect with DB: ' . $connectWithDB . '
      '; + try { // Try connect to the database, if it does not exist, create it $this->dbConn = new PDO($connectWithDB, $parameters['username'], $parameters['password']); } catch (PDOException $e) { - // To do - this is an instance method, not a static method. Call it as such. if (!self::createDatabase($connect, $parameters['username'], $parameters['password'], $parameters['database'])) { $this->databaseError("Could not connect to the database, make sure the server is available and user credentials are correct"); } else { $this->dbConn = new PDO($connectWithDB, $parameters['username'], $parameters['password']); // After creating the database, connect to it } - } + } + parent::__construct(); } @@ -75,8 +75,12 @@ class PDODatabase extends Database { * @param array $parameters The connection details. * @return string $connect The connection string. **/ - public function getConnect($parameters) { - switch ($parameters['type']) { + /*public function getConnect($parameters) { + echo 'PDODatabase::getConnect:
      ';
      +		print_r($parameters);
      +		echo '
      '; + $type=$parameters['pdo_type']; + /*switch ($parameters['pdo_type']) { case "mysql": $port = '3306'; $type = 'mysql'; @@ -98,12 +102,25 @@ class PDODatabase extends Database { break; default: $this->databaseError("This database server is not available"); - } + }*/ + /* if (isset($parameters['port']) && is_numeric($parameters['port'])) { $port = $parameters['port']; + } else { + //assumes that a port is required for a database connection + $this->databaseError("This database server is not available"); } $connect = $type . ':host=' . $parameters['server'] . $instance . ';port=' . $port; return $connect; + }*/ + public function getConnect(){ + Debug::backtrace(); + user_error("PDODatabase subclasses need to implement getConnect", E_USER_ERROR); + //echo 'getting getConnect with these parameters:
      ';
      +		//print_r($parameters);
      +		//echo '
      '; + //return $this->getConnect($parameters); + } /** @@ -231,9 +248,11 @@ class PDODatabase extends Database { * @param string $password Database Password * @param string $database Database to which to create * @return boolean Returns true if successful - * @todo This shouldn't take any arguments; it should take the information given in the constructor instead. */ - public function createDatabase($connect, $username, $password, $database) { + public function createDatabase($connect, $username, $password, $database) { + echo 'connect:
      ';
      +		print_r($connect);
      +		echo '
      '; try { $dbh = new PDO($connect, $username, $password); $stmt = $dbh->prepare("CREATE DATABASE $database"); @@ -290,7 +309,7 @@ class PDODatabase extends Database { if ($fields) { foreach($fields as $k => $v) $fieldSchemas .= "`$k` $v,\n"; } - + echo 'boo!'; switch (self::getDatabaseServer()) { case "mysql": $stmt = $this->dbConn->prepare("CREATE TABLE $tableName (ID INT(11) NOT NULL AUTO_INCREMENT, $fieldSchemas PRIMARY KEY (ID)) TYPE=MyISAM"); @@ -313,11 +332,11 @@ class PDODatabase extends Database { /** * Alter fields and indexes in existing table. - * @param string $tableName The name of the table. - * @param string $newFields Fields to add. - * @param string $newIndexes Indexes to add. - * @param string $alteredFields Fields to change. - * @param string $alteredIndexes Indexes to change. + * @var string $tableName The name of the table. + * @var string $newFields Fields to add. + * @var string $newIndexes Indexes to add. + * @var string $alteredFields Fields to change. + * @var string $alteredIndexes Indexes to change. * @return void. */ public function alterTable($table, $newFields = null, $newIndexes = null, $alteredFields = null, $alteredIndexes = null) { @@ -353,8 +372,8 @@ class PDODatabase extends Database { /** * Rename an existing table, the TO is necessary for PostgreSQL and MS SQL. - * @param string $oldTableName The name of the existing table. - * @param string $newTableName How the table should be named from now on. + * @var string $oldTableName The name of the existing table. + * @var string $newTableName How the table should be named from now on. * @return void. */ public function renameTable($oldTableName, $newTableName) { @@ -368,7 +387,7 @@ class PDODatabase extends Database { * @return boolean Return true if the table has integrity after the method is complete. */ public function checkAndRepairTable($tableName) { - if ($parameters['type'] == "mysql") { + if ($parameters['pdo_type'] == "mysql") { if (!$this->runTableCheckCommand("CHECK TABLE `$tableName`")) { if(!Database::$supressOutput) { echo "
    • Table $tableName: repaired
    • "; @@ -567,7 +586,9 @@ class PDODatabase extends Database { * @param string $able Table of which to show the indexes. * Returns a map of indexes. */ - public function indexList($table) { + public function indexList($table) { + echo 'self::getDatabaseServer=' . self::getDatabaseServer() . '
      '; + switch (self::getDatabaseServer()) { case "mysql": foreach($this->dbConn->query("SHOW INDEXES IN '$table'") as $index) { @@ -656,8 +677,6 @@ class PDODatabase extends Database { /** * A result-set from a database query (array). - * @package sapphire - * @subpackage model */ class PDOQuery extends Query { private $database; @@ -719,4 +738,4 @@ class PDOQuery extends Query { } -?> +?> diff --git a/core/model/PageView.php b/core/model/PageView.php index 27ab6f120..da88ada3b 100644 --- a/core/model/PageView.php +++ b/core/model/PageView.php @@ -1,19 +1,11 @@ hitdata = $browscap->getBrowser(null, true); } - - /** - * gathers data for this page view and writes - * it to the data source. - */ + function record() { $this->init(); - $this->recordBrowser(); - $this->recordOS(); - $this->recordUserID(); - $this->recordPageID(); - $this->recordIP(); - $this->recordFromExternal(); - $this->recordReferrer(); + $this->setBrowser(); + $this->setOS(); + $this->setUserID(); + $this->setPageID(); + $this->setIP(); $this->write(true); } - private function recordFromExternal() { - $http_host = "http://".$_SERVER['HTTP_HOST']; - if (isset($_SERVER['HTTP_REFERER']) && !strstr($_SERVER['HTTP_REFERER'], $http_host) && $_SERVER['HTTP_REFERER'] != null) - $this->FromExternal = 1; + function sanitize($str) { + //TODO + return $str; } - private function recordBrowser() { - if (isset($this->hitdata['Browser'])) - $this->Browser = $this->hitdata['Browser']; + function setBrowser() { + if(isset($this->hitdata['Browser'])) + $this->setField('Browser', $this->hitdata['Browser']); - if (isset($this->hitdata['Version'])) - $this->BrowserVersion = $this->hitdata['Version']; - } - - private function recordReferrer() { - if(isset($_SERVER['HTTP_REFERER'])) $this->Referrer = $_SERVER['HTTP_REFERER']; + if(isset($this->hitdata['Version'])) + $this->setField('BrowserVersion', $this->hitdata['Version']); } - private function recordOS() { + function setOS() { if(isset($this->hitdata['Platform'])) - $this->OS = $this->hitdata['Platform']; + $this->setField('OS', $this->hitdata['Platform']); } - private function recordUserID() { + function setUserID() { $isLogged = Session::get('loggedInAs'); - $id = ($isLogged) ? $isLogged : -1; - $this->UserID = $id; + if($isLogged) { + $id = $isLogged; + } else { + $id = -1; + } + $this->setField('UserID', $id); } - private function recordPageID() { + function setPageID() { $currentPage = Director::currentPage(); - if ($currentPage) $this->PageID = $currentPage->ID; + if($currentPage) + $this->setField('PageID', $currentPage->ID); } - private function recordIP() { - $this->IP = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) - ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; + function setIP() { + if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else { + $ip = $_SERVER['REMOTE_ADDR']; + } + $this->setField('IP', $ip); } - + } + ?> \ No newline at end of file diff --git a/core/model/PostgreSQLDatabase.php b/core/model/PostgreSQLDatabase.php new file mode 100644 index 000000000..3bbe6cbea --- /dev/null +++ b/core/model/PostgreSQLDatabase.php @@ -0,0 +1,497 @@ +
    • server: The server, eg, localhost
    • + *
    • username: The username to log on with
    • + *
    • password: The password to log on with
    • + *
    • database: The database to connect to
    • + */ + + public function __construct($parameters) { + /*$this->dbConn = sql_connect($parameters['server'], $parameters['username'], $parameters['password']); + $this->active = mysql_select_db($parameters['database'], $this->dbConn); + $this->database = $parameters['database']; + if(!$this->dbConn) { + $this->databaseError("Couldn't connect to MySQL database"); + }*/ + //$parameters ['port'] = $this->port; + //$parameters ['pdo_type'] = $this->pdo_type; + //$parameters ['instance'] = $this->instance; + foreach($parameters as $key=>$value) + $this->$key=$value; + + parent::__construct ( $parameters ); + } + + /** + * This is a PostgreSQL-specific connection string. + * @param array $parameters The connection details. + * @return string $connect The connection string. + **/ + public function getConnect() { + echo 'PostgreSQLDatabase::getConnect:
      ';
      +		//Debug::show($parameters);
      +		echo '
      '; + + //if (isset ( $parameters ['port'] ) && is_numeric ( $parameters ['port'] )) + if(isset($this->port) && is_numeric($this->port)) + $port = ';port=' . $parameters ['port']; else + $port = ''; + + $connect = $this->pdo_type . ':host=' . $this->server . $this->instance . $port . '; user=' . $this->username . '; password=' . $this->password; + echo 'returning ' . $connect . '
      '; + return $connect; + } + +/** + * Returns true if this database supports collations + * @return boolean + */ +//public function supportsCollations() { +// return $this->getVersion() >= 4.1; +//} + + +/** + * The version of MySQL. + * @var float + */ +//private $mysqlVersion; + + +/** + * Get the version of MySQL. + * @return float + */ +//public function getVersion() { +// if(!$this->mysqlVersion) { +// $this->mysqlVersion = (float)$this->query("SELECT VERSION()")->value(); +// } +// return $this->mysqlVersion; +//} + + +/** + * Get the database server, namely mysql. + * @return string + */ +//public function getDatabaseServer() { +// return "mysql"; +//} + + +/*public function query($sql, $errorLevel = E_USER_ERROR) { + if(isset($_REQUEST['previewwrite']) && in_array(strtolower(substr($sql,0,strpos($sql,' '))), array('insert','update','delete','replace'))) { + Debug::message("Will execute: $sql"); + return; + } + + if(isset($_REQUEST['showqueries'])) { + $starttime = microtime(true); + } + + $handle = mysql_query($sql, $this->dbConn); + + if(isset($_REQUEST['showqueries'])) { + $endtime = round(microtime(true) - $starttime,4); + Debug::message("\n$sql\n{$endtime}ms\n", false); + } + + if(!$handle && $errorLevel) $this->databaseError("Couldn't run query: $sql | " . mysql_error($this->dbConn), $errorLevel); + return new MySQLQuery($this, $handle); + } + */ +//public function getGeneratedID($table) { +// return mysql_insert_id($this->dbConn); +//} + + +/** + * OBSOLETE: Get the ID for the next new record for the table. + * + * @var string $table The name od the table. + * @return int + */ +/* + public function getNextID($table) { + user_error('getNextID is OBSOLETE (and will no longer work properly)', E_USER_WARNING); + $result = $this->query("SELECT MAX(ID)+1 FROM `$table`")->value(); + return $result ? $result : 1; + }*/ +/* + public function isActive() { + return $this->active ? true : false; + }*/ +/* + public function createDatabase($connect, $username, $password, $db) { + $this->query("CREATE DATABASE $this->database"); + $this->query("USE $this->database"); + + $this->tableList = $this->fieldList = $this->indexList = null; + + if(mysql_select_db($this->database, $this->dbConn)) { + $this->active = true; + return true; + } + }*/ + +/** + * Drop the database that this object is currently connected to. + * Use with caution. + */ +/* + public function dropDatabase() { + $this->query("DROP DATABASE $this->database"); + }*/ + +/** + * Returns the name of the currently selected database + */ +/* + public function currentDatabase() { + return $this->database; + }*/ + +/** + * Switches to the given database. + * If the database doesn't exist, you should call createDatabase() after calling selectDatabase() + */ +/* + public function selectDatabase($dbname) { + $this->database = $dbname; + if($this->databaseExists($this->database)) mysql_select_db($this->database, $this->dbConn); + $this->tableList = $this->fieldList = $this->indexList = null; + }*/ + +/** + * Returns true if the named database exists. + */ +/* + public function databaseExists($name) { + $SQL_name = Convert::raw2sql($name); + return $this->query("SHOW DATABASES LIKE '$SQL_name'")->value() ? true : false; + }*/ +/* + public function createTable($tableName, $fields = null, $indexes = null) { + $fieldSchemas = $indexSchemas = ""; + if($fields) foreach($fields as $k => $v) $fieldSchemas .= "`$k` $v,\n"; + if($indexes) foreach($indexes as $k => $v) $fieldSchemas .= $this->getIndexSqlDefinition($k, $v) . ",\n"; + + $this->query("CREATE TABLE `$tableName` ( + ID int(11) not null auto_increment, + $fieldSchemas + $indexSchemas + primary key (ID) + ) TYPE=MyISAM"); + } + */ +/** + * Alter a table's schema. + * @param $table The name of the table to alter + * @param $newFields New fields, a map of field name => field schema + * @param $newIndexes New indexes, a map of index name => index type + * @param $alteredFields Updated fields, a map of field name => field schema + * @param $alteredIndexes Updated indexes, a map of index name => index type + */ +/* + public function alterTable($tableName, $newFields = null, $newIndexes = null, $alteredFields = null, $alteredIndexes = null) { + $fieldSchemas = $indexSchemas = ""; + + if($newFields) foreach($newFields as $k => $v) $alterList[] .= "ADD `$k` $v"; + if($newIndexes) foreach($newIndexes as $k => $v) $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v); + if($alteredFields) foreach($alteredFields as $k => $v) $alterList[] .= "CHANGE `$k` `$k` $v"; + if($alteredIndexes) foreach($alteredIndexes as $k => $v) { + $alterList[] .= "DROP INDEX `$k`"; + $alterList[] .= "ADD ". $this->getIndexSqlDefinition($k, $v); + } + + $alterations = implode(",\n", $alterList); + $this->query("ALTER TABLE `$tableName` " . $alterations); + }*/ +/* + public function renameTable($oldTableName, $newTableName) { + $this->query("ALTER TABLE `$oldTableName` RENAME `$newTableName`"); + } + */ + +/** + * Checks a table's integrity and repairs it if necessary. + * @var string $tableName The name of the table. + * @return boolean Return true if the table has integrity after the method is complete. + */ +/* + public function checkAndRepairTable($tableName) { + if(!$this->runTableCheckCommand("CHECK TABLE `$tableName`")) { + Database::alteration_message("Table $tableName: repaired","repaired"); + return $this->runTableCheckCommand("REPAIR TABLE `$tableName` USE_FRM"); + } else { + return true; + } + }*/ + +/** + * Helper function used by checkAndRepairTable. + * @param string $sql Query to run. + * @return boolean Returns if the query returns a successful result. + */ +/* + protected function runTableCheckCommand($sql) { + $testResults = $this->query($sql); + foreach($testResults as $testRecord) { + if(strtolower($testRecord['Msg_text']) != 'ok') { + return false; + } + } + return true; + } + */ +/* + public function createField($tableName, $fieldName, $fieldSpec) { + $this->query("ALTER TABLE `$tableName` ADD `$fieldName` $fieldSpec"); + } + */ +/** + * Change the database type of the given field. + * @param string $tableName The name of the tbale the field is in. + * @param string $fieldName The name of the field to change. + * @param string $fieldSpec The new field specification + */ +/* + public function alterField($tableName, $fieldName, $fieldSpec) { + // This wee function was built for MoT. It will preserve the binary format of the content, + // but change the character set + + //$changes = $this->query("SELECT ID, `$fieldName` FROM `$tableName`")->map(); + + + $this->query("ALTER TABLE `$tableName` CHANGE `$fieldName` `$fieldName` $fieldSpec"); + + // This wee function was built for MoT. It will preserve the binary format of the content, + // but change the character set + /* + echo "
    • Fixing " . sizeof($changes) . " page's contnet"; + foreach($changes as $id => $text) { + $SQL_text = Convert::raw2sql($text); + $this->query("UPDATE `$tableName` SET `$fieldName` = '$SQL_text' WHERE ID = '$id'"); + } + */ +//} +/* + public function fieldList($table) { + $fields = DB::query("SHOW FULL FIELDS IN `$table`"); + foreach($fields as $field) { + $fieldSpec = $field['Type']; + if(!$field['Null'] || $field['Null'] == 'NO') { + $fieldSpec .= ' not null'; + } + + if($field['Collation'] && $field['Collation'] != 'NULL') { + $collInfo = DB::query("SHOW COLLATION LIKE '$field[Collation]'")->record(); + $fieldSpec .= " character set $collInfo[Charset] collate $field[Collation]"; + } + + if($field['Default'] || $field['Default'] === "0") { + $fieldSpec .= " default '" . addslashes($field['Default']) . "'"; + } + if($field['Extra']) $fieldSpec .= " $field[Extra]"; + + $fieldList[$field['Field']] = $fieldSpec; + } + return $fieldList; + } + */ +/** + * Create an index on a table. + * @param string $tableName The name of the table. + * @param string $indexName The name of the index. + * @param string $indexSpec The specification of the index, see Database::requireIndex() for more details. + */ +/* + public function createIndex($tableName, $indexName, $indexSpec) { + $this->query("ALTER TABLE `$tableName` ADD " . $this->getIndexSqlDefinition($indexName, $indexSpec)); + }*/ +/* + protected function getIndexSqlDefinition($indexName, $indexSpec) { + $indexSpec = trim($indexSpec); + if($indexSpec[0] != '(') list($indexType, $indexFields) = explode(' ',$indexSpec,2); + else $indexFields = $indexSpec; + if(!isset($indexType)) { + $indexType = "index"; + } + return "$indexType `$indexName` $indexFields"; + }*/ + +/** + * Alter an index on a table. + * @param string $tableName The name of the table. + * @param string $indexName The name of the index. + * @param string $indexSpec The specification of the index, see Database::requireIndex() for more details. + */ +/* + public function alterIndex($tableName, $indexName, $indexSpec) { + $indexSpec = trim($indexSpec); + if($indexSpec[0] != '(') { + list($indexType, $indexFields) = explode(' ',$indexSpec,2); + } else { + $indexFields = $indexSpec; + } + + if(!$indexType) { + $indexType = "index"; + } + + $this->query("ALTER TABLE `$tableName` DROP INDEX `$indexName`"); + $this->query("ALTER TABLE `$tableName` ADD $indexType `$indexName` $indexFields"); + } + */ +/** + * Return the list of indexes in a table. + * @param string $table The table name. + * @return array + */ +/* + public function indexList($table) { + $indexes = DB::query("SHOW INDEXES IN `$table`"); + + foreach($indexes as $index) { + $groupedIndexes[$index['Key_name']]['fields'][$index['Seq_in_index']] = $index['Column_name']; + + if($index['Index_type'] == 'FULLTEXT') { + $groupedIndexes[$index['Key_name']]['type'] = 'fulltext '; + } else if(!$index['Non_unique']) { + $groupedIndexes[$index['Key_name']]['type'] = 'unique '; + } else { + $groupedIndexes[$index['Key_name']]['type'] = ''; + } + } + + foreach($groupedIndexes as $index => $details) { + ksort($details['fields']); + $indexList[$index] = $details['type'] . '(' . implode(',',$details['fields']) . ')'; + } + + return $indexList; + }*/ + +/** + * Returns a list of all the tables in the database. + * Table names will all be in lowercase. + * @return array + */ +/* + public function tableList() { + foreach($this->query("SHOW TABLES") as $record) { + $table = strtolower(reset($record)); + $tables[$table] = $table; + } + return isset($tables) ? $tables : null; + } + */ +/** + * Return the number of rows affected by the previous operation. + * @return int + */ +/* + public function affectedRows() { + return mysql_affected_rows($this->dbConn); + }*/ +} + +/** + * A result-set from a PostgreSQL database. + * Created by Geoff, 25 February 2008. Basically a pg_* conversion from the original MySQL version + */ +class PostgreSQLQuery extends Query { + /** + * The PostgreSQL object that created this result set. + * @var PostgreSQL + */ + private $database; + + /** + * The internal PostgreSQL handle that points to the result set. + * @var resource + */ + private $handle; + + /** + * Hook the result-set given into a Query class, suitable for use by sapphire. + * @param database The database object that created this query. + * @param handle the internal mysql handle that is points to the resultset. + */ + public function __construct(PostgreSQLDatabase $database, $handle) { + $this->database = $database; + $this->handle = $handle; + parent::__construct (); + } + + public function __destroy() { + pg_free_result ( $this->handle ); + } + + public function seek($row) { + return pg_fetch_row ( $this->handle, $row ); + } + + public function numRecords() { + return pg_num_rows ( $this->handle ); + } + + public function nextRecord() { + // Coalesce rather than replace common fields. + if ($data = pg_fetch_row ( $this->handle )) { + foreach ( $data as $columnIdx => $value ) { + $columnName = pg_field_name ( $this->handle, $columnIdx ); + // $value || !$ouput[$columnName] means that the *last* occurring value is shown + // !$ouput[$columnName] means that the *first* occurring value is shown + if (isset ( $value ) || ! isset ( $output [$columnName] )) { + $output [$columnName] = $value; + } + } + return $output; + } else { + return false; + } + } + +} + +?> diff --git a/core/model/RedirectorPage.php b/core/model/RedirectorPage.php index a38b88079..d0c45adbb 100755 --- a/core/model/RedirectorPage.php +++ b/core/model/RedirectorPage.php @@ -1,17 +1,10 @@ RedirectionType == 'External') { - return Convert::raw2att($this->ExternalURL); + return $this->ExternalURL; } else { $linkTo = $this->LinkToID ? DataObject::get_by_id("SiteTree", $this->LinkToID) : null; if($linkTo) { @@ -96,11 +89,6 @@ class RedirectorPage extends Page { } } -/** - * Controller for the {@link RedirectorPage}. - * @package cms - * @subpackage content - */ class RedirectorPage_Controller extends Page_Controller { function init() { if($this->RedirectionType == 'External') { diff --git a/core/model/SQLMap.php b/core/model/SQLMap.php index d2b67ec8b..292d97fb1 100755 --- a/core/model/SQLMap.php +++ b/core/model/SQLMap.php @@ -1,15 +1,8 @@ value pairs generated from database queries. * The query isn't actually executed until you need it. - * @package sapphire - * @subpackage model */ class SQLMap extends Object implements Iterator { /** diff --git a/core/model/SQLQuery.php b/core/model/SQLQuery.php index 2a2839cdb..ad05093d4 100755 --- a/core/model/SQLQuery.php +++ b/core/model/SQLQuery.php @@ -1,15 +1,8 @@ "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')", "Editors" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')", "ViewersGroup" => "Int", - "EditorsGroup" => "Int", - - // Simple task tracking - "ToDo" => "Text", + "EditorsGroup" => "Int" ); static $indexes = array( @@ -175,15 +171,7 @@ class SiteTree extends DataObject { static $extensions = array( "Hierarchy", "Translatable('Title', 'MenuTitle', 'Content', 'URLSegment', 'MetaTitle', 'MetaDescription', 'MetaKeywords', 'Status')", - "Versioned('Stage', 'Live')" - ); - - /** - * Delimit breadcrumb-links generated by BreadCrumbs() - * - * @var string - */ - public static $breadcrumbs_delimiter = " » "; + "Versioned('Stage', 'Live')" ); /** @@ -441,7 +429,7 @@ class SiteTree extends DataObject { $page = $page->Parent; } - return implode(self::$breadcrumbs_delimiter, array_reverse($parts)); + return implode(" » ", array_reverse($parts)); } @@ -711,8 +699,8 @@ class SiteTree extends DataObject { if(!DataObject::get_one("SiteTree", "URLSegment = 'home'")) { $homepage = new Page(); - $homepage->Title = _t('SiteTree.DEFAULTHOMETITLE', 'Home'); - $homepage->Content = _t('SiteTree.DEFAULTHOMECONTENT', '

      Welcome to SilverStripe! This is the default homepage. You can edit this page by opening the CMS. You can now access the developer documentation, or begin the tutorials.

      '); + $homepage->Title = "Home"; + $homepage->Content = "

      Welcome to SilverStripe! This is the default homepage. You can edit this page by opening the CMS. You can now access the developer documentation, or begin the tutorials.

      "; $homepage->URLSegment = "home"; $homepage->Status = "Published"; $homepage->write(); @@ -723,8 +711,8 @@ class SiteTree extends DataObject { if(DB::query("SELECT COUNT(*) FROM SiteTree")->value() == 1) { $aboutus = new Page(); - $aboutus->Title = _t('SiteTree.DEFAULTABOUTTITLE', 'About Us'); - $aboutus->Content = _t('SiteTree.DEFAULTABOUTCONTENT', '

      You can fill this page out with your own content, or delete it and create your own pages.

      '); + $aboutus->Title = "About Us"; + $aboutus->Content = "

      You can fill this page out with your own content, or delete it and create your own pages.

      "; $aboutus->URLSegment = "about-us"; $aboutus->Status = "Published"; $aboutus->write(); @@ -732,8 +720,8 @@ class SiteTree extends DataObject { Database::alteration_message("About Us created","created"); $contactus = new Page(); - $contactus->Title = _t('SiteTree.DEFAULTCONTACTTITLE', 'Contact Us'); - $contactus->Content = _t('SiteTree.DEFAULTCONTACTCONTENT', '

      You can fill this page out with your own content, or delete it and create your own pages.

      '); + $contactus->Title = "Contact Us"; + $contactus->Content = "

      You can fill this page out with your own content, or delete it and create your own pages.

      "; $contactus->URLSegment = "contact-us"; $contactus->Status = "Published"; $contactus->write(); @@ -777,7 +765,7 @@ class SiteTree extends DataObject { ''; $count = 1; - while(class_exists($this->URLSegment) || DataObject::get_one("SiteTree", "URLSegment = '$this->URLSegment' $idFilter")) { + while(DataObject::get_one("SiteTree", "URLSegment = '$this->URLSegment' $idFilter")) { $count++; $this->URLSegment = ereg_replace('-[0-9]+$','', $this->URLSegment) . "-$count"; } @@ -1072,10 +1060,6 @@ class SiteTree extends DataObject { _t('SiteTree.HOMEPAGEFORDOMAIN', "Domain(s)", PR_MEDIUM, 'Listing domains that should be used as homepage') ) ), - $tabToDo = new Tab($this->ToDo ? 'To-do **' : 'To-do', - new LiteralField("ToDoHelp", _t('SiteTree.TODOHELP', "

      You can use this to keep track of work that needs to be done to the content of your site. To see all your pages with to do information, open the 'Site Reports' window on the left and select 'To Do'

      ")), - new TextareaField("ToDo", "") - ), $tabReports = new TabSet('Reports', $tabBacklinks =new Tab('Backlinks', new LiteralField("Backlinks", $backlinks) @@ -1227,30 +1211,14 @@ class SiteTree extends DataObject { $instance = singleton($class); if((($instance instanceof HiddenClass) || !$instance->canCreate()) && ($class != $this->class)) continue; - /* $addAction = $instance->uninherited('add_action', true); - if(!$addAction) { - $addAction = $instance->singular_name(); - } - */ - $addAction = $instance->i18n_singular_name(); + if(!$addAction) $addAction = "a $class"; - if($class == $this->class) { - $currentClass = $class; - $currentAddAction = $addAction; - } else { - $result[$class] = ($class == $this->class) - ? _t('SiteTree.CURRENTLY', 'Currently').' '.$addAction - : _t('SiteTree.CHANGETO', 'Change to').' '.$addAction; - } + $result[$class] = ($class == $this->class) + ? "Currently $addAction" + : "Change to $addAction"; } - - // sort alphabetically, and put current on top - asort($result); - $result = array_reverse($result); - $result[$currentClass] = $currentAddAction.' ('._t('SiteTree.CURRENT','current').')'; - $result = array_reverse($result); - + return $result; } @@ -1374,26 +1342,13 @@ class SiteTree extends DataObject { "span title=\"" . _t('SiteTree.MODIFIEDONDRAFT', 'Modified on draft site') . "\" class=\"modified\"" : ""))); if($tag) { - return "<$tag>" . $this->MenuTitle . ""; + return "<$tag>" . $this->Title . ""; } else { - return $this->MenuTitle; + return $this->Title; } } - /** - * Returns the page in the current page stack of the given level. - * Level(1) will return the main menu item that we're currently inside, etc. - */ - public function Level($level) { - $parent = $this; - $stack = array($parent); - while($parent = $parent->Parent) { - array_unshift($stack, $parent); - } - return isset($stack[$level-1]) ? $stack[$level-1] : null; - } - /** * Return the CSS classes to apply to this node in the CMS tree * @@ -1415,9 +1370,6 @@ class SiteTree extends DataObject { if($controller->isCurrentPage($this)) $classes .= " current"; - if(!$this->canEdit() && !$this->canAddChildren()) - $classes .= " disabled"; - $classes .= $this->markingClasses(); return $classes; diff --git a/core/model/Staged.php b/core/model/Staged.php new file mode 100755 index 000000000..703ecfc28 --- /dev/null +++ b/core/model/Staged.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/core/model/Translatable.php b/core/model/Translatable.php index b7d9cd1b9..3958ad405 100755 --- a/core/model/Translatable.php +++ b/core/model/Translatable.php @@ -1,10 +1,5 @@ - * @package sapphire - * @subpackage misc + * */ class Translatable extends DataObjectDecorator { @@ -149,7 +143,7 @@ class Translatable extends DataObjectDecorator { /** * Set default language. * - * @param $lang String + * @paran $lang String */ static function set_default_lang($lang) { self::$default_lang = $lang; @@ -610,17 +604,17 @@ class Translatable extends DataObjectDecorator { } $fields->addFieldsToTab( 'Root', - new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), - new HeaderField(_t('Translatable.CREATE', 'Create new translation'), 2), - $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLangs), - $createButton = new InlineFormAction('createtranslation',_t('Translatable.CREATEBUTTON', 'Create')) + new Tab("Translations", + new HeaderField("Create new translation", 2), + $langDropdown = new LanguageDropdownField("NewTransLang", "New language", $alreadyTranslatedLangs), + $createButton = new InlineFormAction('createtranslation',"Create") ) ); if (count($alreadyTranslatedLangs)) { $fields->addFieldsToTab( 'Root.Translations', new FieldSet( - new HeaderField(_t('Translatable.EXISTING', 'Existing translations:'), 3), + new HeaderField("Existing translations:", 3), new LiteralField('existingtrans',implode(', ',$alreadyTranslatedLangs)) ) ); diff --git a/core/model/Versioned.php b/core/model/Versioned.php index ace049780..edfe012e4 100755 --- a/core/model/Versioned.php +++ b/core/model/Versioned.php @@ -1,15 +1,8 @@ owner->parentClass() == "DataObject") { $rootTable = true; } - if ($suffix && ($ext = $this->owner->extInstance($allSuffixes[$suffix]))) { + if ($suffix && ($ext = $this->owner->getExtension($allSuffixes[$suffix]))) { if (!$ext->isVersionedTable($table)) continue; $fields = $ext->fieldsInExtraTables($suffix); $indexes = $fields['indexes']; @@ -345,7 +338,7 @@ class Versioned extends DataObjectDecorator { function extendWithSuffix($table) { foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) { if ($this->owner->hasExtension($versionableExtension)) { - $table = $this->owner->extInstance($versionableExtension)->extendWithSuffix($table); + $table = $this->owner->getExtension($versionableExtension)->extendWithSuffix($table); } } return $table; @@ -473,7 +466,7 @@ class Versioned extends DataObjectDecorator { $fields = array_keys($fromRecord->getAllFields()); foreach($fields as $field) { - if(in_array($field, array("ID","Version","RecordID","AuthorID", "ParentID"))) continue; + if(in_array($field, array("ID","Version","RecordID","AuthorID"))) continue; $fromRecord->$field = Diff::compareHTML($fromRecord->$field, $toRecord->$field); } @@ -630,9 +623,6 @@ class Versioned extends DataObjectDecorator { * Return the latest version of the given page */ static function get_latest_version($class, $id) { - $oldStage = Versioned::$reading_stage; - Versioned::$reading_stage = null; - $baseTable = ClassInfo::baseDataClass($class); $query = singleton($class)->buildVersionSQL("`{$baseTable}`.RecordID = $id", "`{$baseTable}`.Version DESC"); $query->limit = 1; @@ -643,16 +633,10 @@ class Versioned extends DataObjectDecorator { Debug::show($record); user_error("Versioned::get_version: Couldn't get $class.$id, version $version", E_USER_ERROR); } - - Versioned::$reading_stage = $oldStage; - return new $className($record); } static function get_version($class, $id, $version) { - $oldStage = Versioned::$reading_stage; - Versioned::$reading_stage = null; - $baseTable = ClassInfo::baseDataClass($class); $query = singleton($class)->buildVersionSQL("`{$baseTable}`.RecordID = $id AND `{$baseTable}`.Version = $version"); $record = $query->execute()->record(); @@ -662,9 +646,6 @@ class Versioned extends DataObjectDecorator { Debug::show($record); user_error("Versioned::get_version: Couldn't get $class.$id, version $version", E_USER_ERROR); } - - Versioned::$reading_stage = $oldStage; - return new $className($record); } @@ -694,9 +675,6 @@ class Versioned extends DataObjectDecorator { /** * Represents a single version of a record. - * @package sapphire - * @subpackage model - * @see Versioned */ class Versioned_Version extends ViewableData { protected $record; diff --git a/core/model/VirtualPage.php b/core/model/VirtualPage.php index e8c79b52c..fff9db75b 100755 --- a/core/model/VirtualPage.php +++ b/core/model/VirtualPage.php @@ -1,17 +1,11 @@ name = $name; @@ -46,15 +29,12 @@ abstract class DBField extends ViewableData { function setVal($value) { return $this->setValue($value); } - function setValue($value) { $this->value = $value; } - function setTable($tableName) { $this->tableName = $tableName; } - function forTemplate() { return $this->value; } @@ -65,19 +45,15 @@ abstract class DBField extends ViewableData { function ATT() { return Convert::raw2att($this->value); } - function RAW() { return $this->value; } - function JS() { return Convert::raw2js($this->value); } - function HTML(){ return Convert::raw2xml($this->value); } - function XML(){ return Convert::raw2xml($this->value); } @@ -117,4 +93,5 @@ abstract class DBField extends ViewableData { DBG; } } + ?> \ No newline at end of file diff --git a/core/model/fieldtypes/Date.php b/core/model/fieldtypes/Date.php index 444388eae..6328dcf72 100644 --- a/core/model/fieldtypes/Date.php +++ b/core/model/fieldtypes/Date.php @@ -1,15 +1,5 @@ value)) $agoWord = _t("Date.AWAY", " away"); else $agoWord = _t("Date.AGO", " ago"); - return $this->TimeDiff() . ' ' . $agoWord; + return $this->TimeDiff() . $agoWord; } } @@ -139,46 +129,6 @@ class Date extends DBField { } } } - - /** - * Gets the time difference, but always returns it in a certain format - * @param string $format The format, could be one of these: - * 'seconds', 'minutes', 'hours', 'days', 'months', 'years'. - * - * @return string - */ - function TimeDiffIn($format) { - if($this->value) { - $ago = abs(time() - strtotime($this->value)); - - switch($format) { - case "seconds": - $span = $ago; - return ($span != 1) ? "{$span} seconds" : "{$span} second"; - break; - case "minutes": - $span = round($ago/60); - return ($span != 1) ? "{$span} minutes" : "{$span} minute"; - break; - case "hours": - $span = round($ago/3600); - return ($span != 1) ? "{$span} hours" : "{$span} hour"; - break; - case "days": - $span = round($ago/86400); - return ($span != 1) ? "{$span} days" : "{$span} day"; - break; - case "months": - $span = round($ago/86400/30); - return ($span != 1) ? "{$span} months" : "{$span} month"; - break; - case "years": - $span = round($ago/86400/365); - return ($span != 1) ? "{$span} years" : "{$span} year"; - break; - } - } - } function requireField() { DB::requireField($this->tableName, $this->name, "date"); diff --git a/core/model/fieldtypes/Datetime.php b/core/model/fieldtypes/Datetime.php index 2d4a58d12..dd3f97db5 100644 --- a/core/model/fieldtypes/Datetime.php +++ b/core/model/fieldtypes/Datetime.php @@ -1,21 +1,7 @@ value = date('Y-m-d H:i:s', strtotime($value)); diff --git a/core/model/fieldtypes/Decimal.php b/core/model/fieldtypes/Decimal.php index b8d5ea301..b7554a581 100644 --- a/core/model/fieldtypes/Decimal.php +++ b/core/model/fieldtypes/Decimal.php @@ -1,14 +1,6 @@ tableName, $this->name, "decimal($this->wholeSize,$this->decimalSize)"); - } - - function saveInto($dataObject) { - $fieldName = $this->name; - if($fieldName) { - $dataObject->$fieldName = (float)preg_replace('/[^0-9.]/', '', $this->value); - } else { - user_error("DBField::saveInto() Called on a nameless '" . get_class($this) . "' object", E_USER_ERROR); - } } } diff --git a/core/model/fieldtypes/Enum.php b/core/model/fieldtypes/Enum.php index ff398b009..eac34740d 100755 --- a/core/model/fieldtypes/Enum.php +++ b/core/model/fieldtypes/Enum.php @@ -1,15 +1,5 @@ 0) { - if(!in_array($tagName[1], $noClose)) { - $summary .= ""; - } - } + if(sizeof($tagName) > 0) + $summary .= ""; } return $summary; diff --git a/core/model/fieldtypes/HTMLVarchar.php b/core/model/fieldtypes/HTMLVarchar.php index dc8dd7503..97aae9efa 100755 --- a/core/model/fieldtypes/HTMLVarchar.php +++ b/core/model/fieldtypes/HTMLVarchar.php @@ -1,16 +1,8 @@ value ); } - - - } -?> +?> \ No newline at end of file diff --git a/core/model/fieldtypes/Percentage.php b/core/model/fieldtypes/Percentage.php index 65194aaa6..88c88df1f 100644 --- a/core/model/fieldtypes/Percentage.php +++ b/core/model/fieldtypes/Percentage.php @@ -1,15 +1,5 @@ value = date('Y-m-d H:i:s', strtotime($value)); diff --git a/core/model/fieldtypes/Text.php b/core/model/fieldtypes/Text.php index f4c1135f9..2e0ee8903 100644 --- a/core/model/fieldtypes/Text.php +++ b/core/model/fieldtypes/Text.php @@ -1,15 +1,5 @@ "HTMLText", @@ -67,34 +57,6 @@ class Text extends DBField { return $ret; } - - /** - * Limit sentences, can be controlled by passing an integer. - * @param int $sentCount The amount of sentences you want. - */ - function LimitSentences($sentCount = 2) { - $data = Convert::xml2raw($this->value); - $sentences = explode('.', $data); - if(count($sentences) == 1) { - return $sentences[0] . '.'; - } elseif(count($sentences) > 1) { - if(is_numeric($sentCount) && $sentCount != 0) { - if($sentCount == 1) { - $output = $sentences[0] . '. '; - } else { - for($i = 1; $i <= $sentCount-1; $i++) { - if($sentences[0]) { - $output .= $sentences[0] . '. '; - } - if($sentences[$i]) { - $output .= $sentences[$i] . '. '; - } - } - } - return $output; - } - } - } /** * Caution: Not XML/HTML-safe - does not respect closing tags. @@ -222,39 +184,6 @@ class Text extends DBField { } } - function ContextSummary($characters = 500, $string = false, $striphtml = true, $highlight = true) { - if(!$string) { - // If no string is supplied, use the string from a SearchForm - $string = $_REQUEST['Search']; - } - - // Remove HTML tags so we don't have to deal with matching tags - $text = $striphtml ? $this->NoHTML() : $this->value; - - // Find the search string - $position = (int) stripos($text, $string); - - // We want to search string to be in the middle of our block to give it some context - $position = max(0, $position - ($characters / 2)); - - - if($position > 0) { - // We don't want to start mid-word - $position = max((int) strrpos(substr($text, 0, $position), ' '), (int) strrpos(substr($text, 0, $position), "\n")); - } - - $summary = substr($text, $position, $characters); - - if($highlight) { - // Add a span around all occurences of the search term - $summary = str_ireplace($string, "$string", $summary); - } - - // trim it, because if we counted back and found a space then there will be an extra - // space at the front - return trim($summary); - } - /** * Allows a sub-class of TextParser to be rendered. @see TextParser for implementation details. */ diff --git a/core/model/fieldtypes/Time.php b/core/model/fieldtypes/Time.php index e859503e6..f6d9dc040 100755 --- a/core/model/fieldtypes/Time.php +++ b/core/model/fieldtypes/Time.php @@ -1,15 +1,8 @@ class; - $parentFolder = Folder::findOrMake($folderName); + $parentFolder = Folder::findOrMake("Uploads"); // Create a folder for uploading. if(!file_exists("$base/assets")){ mkdir("$base/assets", Filesystem::$folder_create_mask); } - if(!file_exists("$base/assets/$folderName")){ - mkdir("$base/assets/$folderName", Filesystem::$folder_create_mask); + if(!file_exists("$base/assets/Uploads")){ + mkdir("$base/assets/Uploads", Filesystem::$folder_create_mask); } // Generate default filename @@ -181,7 +173,7 @@ class File extends DataObject { $file = ereg_replace('-+', '-',$file); $file = basename($file); - $file = "assets/$folderName/$file"; + $file = "assets/Uploads/$file"; while(file_exists("$base/$file")) { $i = isset($i) ? ($i+1) : 2; @@ -240,41 +232,38 @@ class File extends DataObject { function loadallcontent() { ini_set("max_execution_time", 50000); - $allFiles = DataObject::get("File"); + // get all file objects(not folders) + $start = (int)$_GET[start]; + $allFiles = DataObject::get("File", "ClassName = 'File' AND Filename LIKE '%.pdf'", "", "", "$start, 5"); $total = $allFiles->TotalItems(); - $i = 0; + $i = $start; foreach($allFiles as $file) { $i++; $tmp = TEMP_FOLDER; `echo "$i / $total" > $tmp/progress`; - $file->write(); + $file->loadContent(); } + Director::redirect(HTTP::setGetVar("start", $start + 5)); + + // run loadcontent on each one } /** * Gets the content of this file and puts it in the field Content */ function loadContent() { - $filename = escapeshellarg($this->getFullPath()); + switch(strtolower($this->getExtension())){ case 'pdf': - $content = `pdftotext $filename -`; + $filename = escapeshellarg($this->getFullPath()); + + $content = `pstotext $filename`; //echo("
      Content for $this->Filename:\n$content
      "); $this->Content = $content; + $this->write(); break; - case 'doc': - $content = `catdoc $filename`; - $this->Content = $content; - break; - case 'ppt': - $content = `catppt $filename`; - $this->Content = $content; - break; - case 'txt'; - $content = file_get_contents($this->FileName); - $this->Content = $content; } } @@ -287,8 +276,7 @@ class File extends DataObject { } function TreeTitle() { - if($this->hasMethod('alternateTreeTitle')) return $this->alternateTreeTitle(); - else return $this->Title; + return $this->Title; } /** @@ -335,8 +323,6 @@ class File extends DataObject { $brokenPage->write(); } } - - $this->loadContent(); } /** @@ -523,7 +509,7 @@ class File extends DataObject { * legacy code. */ function getExtension() { - return strtolower(substr($this->getField('Filename'),strrpos($this->getField('Filename'),'.')+1)); + return strtolower(substr($this->getField('Name'),strrpos($this->getField('Name'),'.')+1)); } function getFileType() { $types = array( @@ -595,13 +581,6 @@ class File extends DataObject { echo "

      Done!"; } - - /** - * Select clause for DataObject::get('File') operations/ - * Stores an array, suitable for a {@link SQLQuery} object. - */ - private static $dataobject_select; - /** * We've overridden the DataObject::get function for File so that the very large content field * is excluded! @@ -615,23 +594,8 @@ class File extends DataObject { $query = $this->extendedSQL($filter, $sort, $limit, $join, $having); $baseTable = reset($query->from); - - // Work out which columns we're actually going to select - // In short, we select everything except File.Content - if(!self::$dataobject_select) { - self::$dataobject_select = array(); - foreach($query->select as $item) { - if($item == "`File`.*") { - $fileColumns = DB::query("SHOW FIELDS IN `File`")->column(); - $columnsToAdd = array_diff($fileColumns, array('Content')); - foreach($columnsToAdd as $otherItem) self::$dataobject_select[] = '`File`.' . $otherItem; - } else { - self::$dataobject_select[] = $item; - } - } - } - - $query->select = self::$dataobject_select; + + $query->select = array("$baseTable.ID","$baseTable.ClassName","$baseTable.Created","$baseTable.LastEdited","$baseTable.Name","$baseTable.Title","$baseTable.Content","$baseTable.ParentID","$baseTable.Filename","if($baseTable.ClassName,$baseTable.ClassName,'File') AS RecordClassName"); $records = $query->execute(); $ret = $this->buildDataObjectSet($records, $containerClass); diff --git a/filesystem/Filesystem.php b/filesystem/Filesystem.php index b875dc7f9..8af1f42e8 100755 --- a/filesystem/Filesystem.php +++ b/filesystem/Filesystem.php @@ -1,15 +1,5 @@ Name] = $dbChild; } + $unwantedDbChildren = $hasDbChild; } - $unwantedDbChildren = $hasDbChild; // Iterate through the actual children, correcting the database as necessary @@ -338,92 +325,6 @@ class Folder extends File { function cmsCleanup_parentChanged(){ } - - /** - * Return the FieldSet used to edit this folder in the CMS. - * You can modify this fieldset by subclassing folder, or by creating a {@link DataObjectDecorator} - * and implemeting updateCMSFields(FieldSet $fields) on that decorator. - */ - function getCMSFields() { - $nameField = ($this->ID > 0) ? new TextField("Name") : new HiddenField("Name"); - - $fileList = new AssetTableField( - $this, - "Files", - "File", - array("Title" => _t('AssetAdmin.TITLE', "Title"), "LinkedURL" => _t('AssetAdmin.FILENAME', "Filename")), - "" - ); - $fileList->setFolder($this); - $fileList->setPopupCaption(_t('AssetAdmin.VIEWEDITASSET', "View/Edit Asset")); - - $nameField = ($this->ID && $this->ID != "root") ? new TextField("Name", "Folder Name") : new HiddenField("Name"); - if( $this->userCanEdit() ) { - $deleteButton = new InlineFormAction('deletemarked',_t('AssetAdmin.DELSELECTED','Delete selected files'), 'delete'); - $deleteButton->includeDefaultJS(false); - } else { - $deleteButton = new HiddenField('deletemarked'); - } - - $fields = new FieldSet( - new HiddenField("Title"), - new TabSet("Root", - new Tab(_t('AssetAdmin.FILESTAB', "Files"), - $nameField, - $fileList, - $deleteButton, - new HiddenField("FileIDs"), - new HiddenField("DestFolderID") - ), - new Tab(_t('AssetAdmin.DETAILSTAB', "Details"), - new ReadonlyField("URL", _t('AssetAdmin.URL', 'URL')), - new ReadonlyField("ClassName", _t('AssetAdmin.TYPE','Type')), - new ReadonlyField("Created", _t('AssetAdmin.CREATED','First Uploaded')), - new ReadonlyField("LastEdited", _t('AssetAdmin.LASTEDITED','Last Updated')) - ), - new Tab(_t('AssetAdmin.UPLOADTAB', "Upload"), - new LiteralField("UploadIframe", - $this->getUploadIframe() - ) - )/* This has been disabled for now because of it's mass memory consumption - , - new Tab(_t('AssetAdmin.UNUSEDFILESTAB', "Unused files"), - new LiteralField("UnusedAssets", - "

      "._t('AssetAdmin.UNUSEDFILESTITLE', 'Unused files')."

      " - ), - $this->getAssetList(), - new LiteralField("UnusedThumbnails", - "
      -
      -

      "._t('AssetAdmin.UNUSEDTHUMBNAILSTITLE', 'Unused thumbnails')."

      - -
      " - ) - )*/ - ), - new HiddenField("ID") - ); - - $this->extend('updateCMSFields', $fields); - - return $fields; - } - - /** - * Display the upload form. Returns an iframe tag that will show admin/assets/uploadiframe. - */ - function getUploadIframe() { - return << - -HTML; - } - /** - * Since this is a folder, we don't have any content as such. - */ - function loadContent() { - return; - } } diff --git a/filesystem/GD.php b/filesystem/GD.php index 71aba79cd..3ecdbf72d 100755 --- a/filesystem/GD.php +++ b/filesystem/GD.php @@ -1,14 +1,7 @@ haveFormOptions){ $fields = new FieldSet( - new EmailField( "{$this->name}[EmailTo]", _t('FieldEditor.EMAILSUBMISSION', 'Email submission to:'), $this->form->getRecord()->EmailTo ), - new CheckboxField( "{$this->name}[EmailOnSubmit]", _t('FieldEditor.EMAILONSUBMIT', 'Email form on submit:'), $this->form->getRecord()->EmailOnSubmit ) + new EmailField( "{$this->name}[EmailTo]", "Email submission to:", $this->form->getRecord()->EmailTo ), + new CheckboxField( "{$this->name}[EmailOnSubmit]", "Email form on submit:", $this->form->getRecord()->EmailOnSubmit ) ); if( $this->form->getRecord()->hasMethod( 'customFormActions' ) ) { diff --git a/integration/XML.php b/integration/XML.php index e9ec94df8..95e7fa367 100755 --- a/integration/XML.php +++ b/integration/XML.php @@ -1,14 +1,7 @@ Make sure you enter your normalized OpenID/i-name credentials - here, i.e. with protocol and trailing slash for OpenID (e.g. http://openid.silverstripe.com/).

      '; -$lang['en_US']['Security']['OPENIDHEADER'] = 'OpenID/i-name credentials'; -$lang['en_US']['Security']['EDITOPENIDURL'] = 'OpenID URL/i-name (e.g. http://openid.silverstripe.com/)'; -$lang['en_US']['Security']['OPENIDURLNORMALIZATION'] = '

      Make sure you enter your normalized OpenID/i-name credentials - here, i.e. with protocol and trailing slash for OpenID (e.g. http://openid.silverstripe.com/).

      '; - -$lang['en_US']['TableListField']['CSVEXPORT'] = 'Export to CSV'; -$lang['en_US']['TableListField']['PRINT'] = 'Print'; - -$lang['en_US']['Permission']['FULLADMINRIGHTS'] = 'Full administrative rights'; - -$lang['en_US']['Page']['CLASSNAME'] = 'Page'; - -$lang['en_US']['Statistics']['TRENDS'] = 'Trends'; -$lang['en_US']['Statistics']['LEGEND'] = 'Legend'; -$lang['en_US']['Statistics']['BROWSERS'] = 'Browsers'; -$lang['en_US']['Statistics']['ID'] = 'ID'; -$lang['en_US']['Statistics']['EMAIL'] = 'Email'; -$lang['en_US']['Statistics']['JOINED'] = 'Joined'; -$lang['en_US']['Statistics']['REGISTEREDUSERS'] = 'Registered Users'; -$lang['en_US']['Statistics']['CSVEXPORT'] = 'Export as CSV'; - -$lang['en_US']['Statistics']['RECENTPAGEVIEWS'] = 'Recent Page Views'; -$lang['en_US']['Statistics']['TIME'] = 'Time'; -$lang['en_US']['Statistics']['BROWSER'] = 'Browser'; -$lang['en_US']['Statistics']['OSABREV'] = 'OS'; -$lang['en_US']['Statistics']['USER'] = 'User'; -$lang['en_US']['Statistics']['PAGE'] = 'Page'; -$lang['en_US']['Statistics']['PAGEVIEWS'] = 'Page Views'; -$lang['en_US']['Statistics']['OS'] = 'Operating Systems'; -$lang['en_US']['Statistics']['USERACTIVITY'] = 'User Activity'; - - ?> \ No newline at end of file diff --git a/lang/es_ES.php b/lang/es_ES.php index 9ee576e32..6300cbb4d 100644 --- a/lang/es_ES.php +++ b/lang/es_ES.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('es_ES', $lang) && is_array($lang['es_ES'])) { - $lang['es_ES'] = array_merge($lang['en_US'], $lang['es_ES']); -} else { - $lang['es_ES'] = $lang['en_US']; -} +$lang['es_ES'] = $lang['en_US']; $lang['es_ES']['BasicAuth']['ENTERINFO'] = 'Por favor introduzca su nombre de usuario y contraseña.'; $lang['es_ES']['BasicAuth']['ERRORNOTADMIN'] = 'Ese usuario no es un administrador.'; diff --git a/lang/fr_FR.php b/lang/fr_FR.php index 8e294f527..ee5478230 100644 --- a/lang/fr_FR.php +++ b/lang/fr_FR.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('fr_FR', $lang) && is_array($lang['fr_FR'])) { - $lang['fr_FR'] = array_merge($lang['en_US'], $lang['fr_FR']); -} else { - $lang['fr_FR'] = $lang['en_US']; -} +$lang['fr_FR'] = $lang['en_US']; $lang['fr_FR']['BasicAuth']['ENTERINFO'] = 'Entrer un identifiant et un mot de passe s\'il vous plaît.'; $lang['fr_FR']['BasicAuth']['ERRORNOTADMIN'] = 'Cet utilisateur n\'est pas un administrateur.'; @@ -26,7 +22,6 @@ $lang['fr_FR']['ComplexTableField.ss']['SORTASC'] = 'Tri croissant'; $lang['fr_FR']['ComplexTableField.ss']['SORTDESC'] = 'Tri décroissant'; $lang['fr_FR']['ComplexTableField_popup.ss']['NEXT'] = 'Suivant'; $lang['fr_FR']['ComplexTableField_popup.ss']['PREVIOUS'] = 'Précédent'; -$lang['fr_FR']['ContentController']['DRAFT_SITE_ACCESS_RESTRICTION'] = 'Vous devez vous authentifier avec votre mot de passe CMS afin de pouvoir consulter le contenu brouillon ou archivé. Cliquer ici pour revenir au site publié.'; $lang['fr_FR']['Controller']['FILE'] = 'Fichier'; $lang['fr_FR']['Controller']['IMAGE'] = 'Image'; $lang['fr_FR']['Date']['AGO'] = 'auparavant'; @@ -244,7 +239,6 @@ $lang['fr_FR']['SiteTree']['PAGETITLE'] = 'Nom de la page'; $lang['fr_FR']['SiteTree']['PAGETYPE'] = 'Type de page'; $lang['fr_FR']['SiteTree']['PRIORITYLEASTIMPORTANT'] = 'Moins importante'; $lang['fr_FR']['SiteTree']['PRIORITYMOSTIMPORTANT'] = 'Plus importante'; -$lang['fr_FR']['SiteTree']['PRIORITYNOTINDEXED'] = 'Non indexé'; $lang['fr_FR']['SiteTree']['REMOVEDFROMDRAFT'] = 'Supprimé du site brouillon'; $lang['fr_FR']['SiteTree']['SHOWINMENUS'] = 'Afficher dans les menus ?'; $lang['fr_FR']['SiteTree']['SHOWINSEARCH'] = 'Afficher dans les recherches ?'; diff --git a/lang/hr_HR.php b/lang/hr_HR.php index 332a06c34..fa9fb2f49 100644 --- a/lang/hr_HR.php +++ b/lang/hr_HR.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('hr_HR', $lang) && is_array($lang['hr_HR'])) { - $lang['hr_HR'] = array_merge($lang['en_US'], $lang['hr_HR']); -} else { - $lang['hr_HR'] = $lang['en_US']; -} +$lang['hr_HR'] = $lang['en_US']; $lang['hr_HR']['BasicAuth']['ENTERINFO'] = 'Unesite korisniÄko ime i lozinu'; $lang['hr_HR']['BasicAuth']['ERRORNOTADMIN'] = 'Korisnik nije administrator'; @@ -26,7 +22,6 @@ $lang['hr_HR']['ComplexTableField.ss']['SORTASC'] = 'Sortiraj (ascending)'; $lang['hr_HR']['ComplexTableField.ss']['SORTDESC'] = 'Sortiraj (descending)'; $lang['hr_HR']['ComplexTableField_popup.ss']['NEXT'] = 'Slijedeći'; $lang['hr_HR']['ComplexTableField_popup.ss']['PREVIOUS'] = 'Prethodni'; -$lang['hr_HR']['ContentController']['DRAFT_SITE_ACCESS_RESTRICTION'] = 'Morate biti prijavljeni sa vaÅ¡om CMS zaporkom kako bi ste mogli vidjeti privremeni ili arhivirani sadržaj. Kliknite kako bi ste se vratili na objavljen dio stranice'; $lang['hr_HR']['Controller']['FILE'] = 'Datoteka'; $lang['hr_HR']['Controller']['IMAGE'] = 'Slika'; $lang['hr_HR']['Date']['AGO'] = 'prije'; @@ -75,9 +70,6 @@ $lang['hr_HR']['HtmlEditorField']['BUTTONALIGNLEFT'] = 'Lijevo poravnanje'; $lang['hr_HR']['HtmlEditorField']['BUTTONALIGNRIGHT'] = 'Desno poravnanje'; $lang['hr_HR']['HtmlEditorField']['BUTTONBOLD'] = 'Bold (Ctrl+B)'; $lang['hr_HR']['HtmlEditorField']['BUTTONCANCEL'] = 'Otkaži'; -$lang['hr_HR']['HtmlEditorField']['BUTTONEDITIMAGE'] = 'Uredi sliku'; -$lang['hr_HR']['HtmlEditorField']['BUTTONINSERTFLASH'] = 'Umetni Flash'; -$lang['hr_HR']['HtmlEditorField']['BUTTONINSERTIMAGE'] = 'Umetni sliku'; $lang['hr_HR']['HtmlEditorField']['BUTTONINSERTLINK'] = 'Ubaci vezu'; $lang['hr_HR']['HtmlEditorField']['BUTTONITALIC'] = 'Italic (Ctrl+I)'; $lang['hr_HR']['HtmlEditorField']['BUTTONREMOVELINK'] = 'ObriÅ¡i vezu'; @@ -85,7 +77,6 @@ $lang['hr_HR']['HtmlEditorField']['BUTTONSTRIKE'] = 'strikethrough'; $lang['hr_HR']['HtmlEditorField']['BUTTONUNDERLINE'] = 'Underline (Ctrl+U)'; $lang['hr_HR']['HtmlEditorField']['CHARMAP'] = 'Ubaci simbol'; $lang['hr_HR']['HtmlEditorField']['COPY'] = 'Copy (Ctrl+C)'; -$lang['hr_HR']['HtmlEditorField']['CREATEFOLDER'] = 'izradite mapu ( direktorij )'; $lang['hr_HR']['HtmlEditorField']['CSSCLASS'] = 'Poravnanje / Stil'; $lang['hr_HR']['HtmlEditorField']['CSSCLASSCENTER'] = 'Centralno'; $lang['hr_HR']['HtmlEditorField']['CSSCLASSLEFT'] = 'Lijevo, sa okruženjem teksta.'; @@ -98,7 +89,6 @@ $lang['hr_HR']['HtmlEditorField']['EMAIL'] = 'Email adresa'; $lang['hr_HR']['HtmlEditorField']['FILE'] = 'Datoteka'; $lang['hr_HR']['HtmlEditorField']['FLASH'] = 'Ubaci flash'; $lang['hr_HR']['HtmlEditorField']['FOLDER'] = 'Direktorij'; -$lang['hr_HR']['HtmlEditorField']['FOLDERCANCEL'] = 'prekini'; $lang['hr_HR']['HtmlEditorField']['FORMATADDR'] = 'Adresa'; $lang['hr_HR']['HtmlEditorField']['FORMATH1'] = 'Naslov 1 (h1)'; $lang['hr_HR']['HtmlEditorField']['FORMATH2'] = 'Naslov 2 (h2)'; @@ -126,7 +116,6 @@ $lang['hr_HR']['HtmlEditorField']['LINKFILE'] = 'Downlad datoteke'; $lang['hr_HR']['HtmlEditorField']['LINKINTERNAL'] = 'Stranicu na ovom webu'; $lang['hr_HR']['HtmlEditorField']['LINKOPENNEWWIN'] = 'Otvori vezu (link) u novom prozoru?'; $lang['hr_HR']['HtmlEditorField']['LINKTO'] = 'Poveži na'; -$lang['hr_HR']['HtmlEditorField']['OK'] = 'uredu'; $lang['hr_HR']['HtmlEditorField']['OL'] = 'Numbered list (OL)'; $lang['hr_HR']['HtmlEditorField']['OUTDENT'] = 'Smanji uvlaÄenje'; $lang['hr_HR']['HtmlEditorField']['PAGE'] = 'Stranica'; @@ -134,7 +123,6 @@ $lang['hr_HR']['HtmlEditorField']['PASTE'] = 'Paste (Ctrl+V)'; $lang['hr_HR']['HtmlEditorField']['REDO'] = 'Redo (Ctrl+Y)'; $lang['hr_HR']['HtmlEditorField']['UNDO'] = 'Undo (Ctrl+Z)'; $lang['hr_HR']['HtmlEditorField']['UNLINK'] = 'ObriÅ¡i link'; -$lang['hr_HR']['HtmlEditorField']['UPLOAD'] = 'postavi'; $lang['hr_HR']['HtmlEditorField']['URL'] = 'URL'; $lang['hr_HR']['HtmlEditorField']['VISUALAID'] = 'Pokaži/Sakrij vodilice'; $lang['hr_HR']['ImageField']['NOTEADDIMAGES'] = 'Slike možete dodavati nakon Å¡to spremite prvi put.'; @@ -242,9 +230,6 @@ $lang['hr_HR']['SiteTree']['NOTEUSEASHOMEPAGE'] = 'Koristi ovu stranicu kao poÄ $lang['hr_HR']['SiteTree']['PAGESLINKING'] = 'Slijedeće stranice su vezane na ovu:'; $lang['hr_HR']['SiteTree']['PAGETITLE'] = 'Ime stranice'; $lang['hr_HR']['SiteTree']['PAGETYPE'] = 'Vrsta stranice'; -$lang['hr_HR']['SiteTree']['PRIORITYLEASTIMPORTANT'] = 'Nebitno'; -$lang['hr_HR']['SiteTree']['PRIORITYMOSTIMPORTANT'] = 'Najvažnije'; -$lang['hr_HR']['SiteTree']['PRIORITYNOTINDEXED'] = 'Nije zapisano ( Indeksirano )'; $lang['hr_HR']['SiteTree']['REMOVEDFROMDRAFT'] = 'Obrisano sa privremene stranice'; $lang['hr_HR']['SiteTree']['SHOWINMENUS'] = 'Pokaži u izbornicima?'; $lang['hr_HR']['SiteTree']['SHOWINSEARCH'] = 'Pokaži u tražilici?'; diff --git a/lang/hu_HU.php b/lang/hu_HU.php index e3ff4f3f4..b9ea5fdfd 100644 --- a/lang/hu_HU.php +++ b/lang/hu_HU.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('hu_HU', $lang) && is_array($lang['hu_HU'])) { - $lang['hu_HU'] = array_merge($lang['en_US'], $lang['hu_HU']); -} else { - $lang['hu_HU'] = $lang['en_US']; -} +$lang['hu_HU'] = $lang['en_US']; $lang['hu_HU']['BasicAuth']['ENTERINFO'] = 'Kérünk, ajd meg egy felhasználónevet és jelszót.'; $lang['hu_HU']['BasicAuth']['ERRORNOTADMIN'] = 'Ez a felhasználó nem adminisztrátor. '; diff --git a/lang/it_IT.php b/lang/it_IT.php index 499947386..e96e47aa8 100644 --- a/lang/it_IT.php +++ b/lang/it_IT.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('it_IT', $lang) && is_array($lang['it_IT'])) { - $lang['it_IT'] = array_merge($lang['en_US'], $lang['it_IT']); -} else { - $lang['it_IT'] = $lang['en_US']; -} +$lang['it_IT'] = $lang['en_US']; $lang['it_IT']['BasicAuth']['ENTERINFO'] = 'Per favore inserisci un nome utente e la password.'; $lang['it_IT']['BasicAuth']['ERRORNOTADMIN'] = 'Questo utente non è amministratore.'; diff --git a/lang/nl_NL.php b/lang/nl_NL.php index ac0dfc791..e37a61f03 100644 --- a/lang/nl_NL.php +++ b/lang/nl_NL.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('nl_NL', $lang) && is_array($lang['nl_NL'])) { - $lang['nl_NL'] = array_merge($lang['en_US'], $lang['nl_NL']); -} else { - $lang['nl_NL'] = $lang['en_US']; -} +$lang['nl_NL'] = $lang['en_US']; $lang['nl_NL']['BasicAuth']['ENTERINFO'] = 'Voer een gebruikers naam en wachtwoord in.'; $lang['nl_NL']['BasicAuth']['ERRORNOTADMIN'] = 'Die gebruiker is geen beheerder.'; diff --git a/lang/pl_PL.php b/lang/pl_PL.php index a811aeea1..66c9ea08a 100644 --- a/lang/pl_PL.php +++ b/lang/pl_PL.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('pl_PL', $lang) && is_array($lang['pl_PL'])) { - $lang['pl_PL'] = array_merge($lang['en_US'], $lang['pl_PL']); -} else { - $lang['pl_PL'] = $lang['en_US']; -} +$lang['pl_PL'] = $lang['en_US']; $lang['pl_PL']['BasicAuth']['ENTERINFO'] = 'Wprowadź username i hasÅ‚o'; $lang['pl_PL']['BasicAuth']['ERRORNOTADMIN'] = 'Ten użytkownik nie jest administratorem'; @@ -26,7 +22,6 @@ $lang['pl_PL']['ComplexTableField.ss']['SORTASC'] = 'Sortuj rosnÄ…co'; $lang['pl_PL']['ComplexTableField.ss']['SORTDESC'] = 'Sortuj malejÄ…co'; $lang['pl_PL']['ComplexTableField_popup.ss']['NEXT'] = 'NastÄ™pny'; $lang['pl_PL']['ComplexTableField_popup.ss']['PREVIOUS'] = 'Poprzedni'; -$lang['pl_PL']['ContentController']['DRAFT_SITE_ACCESS_RESTRICTION'] = 'Musisz zalogować siÄ™ za pomocÄ… swojego hasÅ‚a do CMSa, aby obejrzeć brudnopis i zarchiwizowanÄ… treść. Kliknij tutaj aby powrócić do opublikowanej strony.'; $lang['pl_PL']['Controller']['FILE'] = 'Plik'; $lang['pl_PL']['Controller']['IMAGE'] = 'Obraz'; $lang['pl_PL']['Date']['AGO'] = 'temu'; @@ -35,7 +30,7 @@ $lang['pl_PL']['Date']['DAY'] = 'dzieÅ„'; $lang['pl_PL']['Date']['DAYS'] = 'dni'; $lang['pl_PL']['Date']['HOUR'] = 'godzina'; $lang['pl_PL']['Date']['HOURS'] = 'godziny'; -$lang['pl_PL']['Date']['MIN'] = 'min'; +$lang['pl_PL']['Date']['MIN'] = 'minuta'; $lang['pl_PL']['Date']['MINS'] = 'minuty'; $lang['pl_PL']['Date']['MONTH'] = 'miesiÄ…c'; $lang['pl_PL']['Date']['MONTHS'] = 'miesiÄ…ce'; @@ -46,7 +41,7 @@ $lang['pl_PL']['Date']['YEARS'] = 'lata'; $lang['pl_PL']['DateField']['VALIDDATEFORMAT'] = 'ProszÄ™ podać prawidÅ‚owy format daty (DD/MM/RRRR).'; $lang['pl_PL']['DropdownField']['CHOOSE'] = '(wybierz)'; $lang['pl_PL']['EmailField']['VALIDATION'] = 'Wprowadź adres e-mail'; -$lang['pl_PL']['ErrorPage']['CODE'] = 'Kod bÅ‚Ä™du'; +$lang['pl_PL']['ErrorPage']['CODE'] = 'BÅ‚Ä…d kodu'; $lang['pl_PL']['FileIframeField']['NOTEADDFILES'] = 'Możesz dodać tylko jeden plik za pierwszym razem'; $lang['pl_PL']['ForgotPasswordEmail.ss']['HELLO'] = 'Cześć'; $lang['pl_PL']['Form']['DATENOTSET'] = '(brak ustawionej daty)'; @@ -55,7 +50,6 @@ $lang['pl_PL']['Form']['LANGAOTHER'] = 'Inny jÄ™zyk'; $lang['pl_PL']['Form']['LANGAVAIL'] = 'DostÄ™pne jÄ™zyki'; $lang['pl_PL']['Form']['NOTSET'] = '(nie ustawiono)'; $lang['pl_PL']['Form']['SAVECHANGES'] = 'Zachowaj zmiany'; -$lang['pl_PL']['Form']['VALIDATIONALLDATEVALUES'] = 'ProszÄ™ siÄ™ upewnić, czy wartoÅ›ci wszystkich dat zostaÅ‚y ustawione'; $lang['pl_PL']['Form']['VALIDATIONBANKACC'] = 'ProszÄ™ podać prawidÅ‚owy numer bankowy'; $lang['pl_PL']['Form']['VALIDATIONCREDITNUMBER'] = 'Upewnij siÄ™, że wprowadzono prawidÅ‚owy numer karty kredytowej %s'; $lang['pl_PL']['Form']['VALIDATIONFAILED'] = 'Walidacja nie powiodÅ‚a siÄ™'; @@ -63,8 +57,6 @@ $lang['pl_PL']['Form']['VALIDATIONNOTUNIQUE'] = 'Wprowadzona wartość nie jest $lang['pl_PL']['Form']['VALIDATIONPASSWORDSDONTMATCH'] = 'HasÅ‚a nie sÄ… takie same'; $lang['pl_PL']['Form']['VALIDATIONPASSWORDSNOTEMPTY'] = 'HasÅ‚o nie może być puste'; $lang['pl_PL']['Form']['VALIDATIONSTRONGPASSWORD'] = 'HasÅ‚o musi posiadać jeden unikalny znak'; -$lang['pl_PL']['Form']['VALIDCURRENCY'] = 'ProszÄ™ wpisać prawidÅ‚owÄ… walutÄ™.'; -$lang['pl_PL']['GhostPage']['NOLINKED'] = 'Ta wirtualna witryna nie jest poÅ‚Ä…czona z żadnÄ… stronÄ….'; $lang['pl_PL']['GSTNumberField']['VALIDATION'] = 'ProszÄ™ wprowadzić poprawny numer GST'; $lang['pl_PL']['HtmlEditorField']['ALTTEXT'] = 'Opis'; $lang['pl_PL']['HtmlEditorField']['ANCHOR'] = 'Wstaw/edytuj kotwicÄ™'; @@ -81,13 +73,12 @@ $lang['pl_PL']['HtmlEditorField']['BUTTONINSERTIMAGE'] = 'Wstaw obraz'; $lang['pl_PL']['HtmlEditorField']['BUTTONINSERTLINK'] = 'Wstaw link'; $lang['pl_PL']['HtmlEditorField']['BUTTONITALIC'] = 'Kursywa (Ctrl+I)'; $lang['pl_PL']['HtmlEditorField']['BUTTONREMOVELINK'] = 'ZmieÅ„ link'; -$lang['pl_PL']['HtmlEditorField']['BUTTONSTRIKE'] = 'przekreÅ›lenie'; +$lang['pl_PL']['HtmlEditorField']['BUTTONSTRIKE'] = 'przez uderzenie'; $lang['pl_PL']['HtmlEditorField']['BUTTONUNDERLINE'] = 'PodkreÅ›lenie (Ctrl+U)'; $lang['pl_PL']['HtmlEditorField']['CHARMAP'] = 'Wstaw symbol'; $lang['pl_PL']['HtmlEditorField']['COPY'] = 'Kopiuj (Ctrl+C)'; $lang['pl_PL']['HtmlEditorField']['CREATEFOLDER'] = 'utwórz folder'; $lang['pl_PL']['HtmlEditorField']['CSSCLASS'] = 'Wyrównanie/styl'; -$lang['pl_PL']['HtmlEditorField']['CSSCLASSCENTER'] = 'WyÅ›rodkowane'; $lang['pl_PL']['HtmlEditorField']['CSSCLASSLEFT'] = 'Tekst po lewej'; $lang['pl_PL']['HtmlEditorField']['CSSCLASSRIGHT'] = 'Tekst po prawej'; $lang['pl_PL']['HtmlEditorField']['CUT'] = 'Wytnij (Ctrl+X)'; @@ -112,7 +103,6 @@ $lang['pl_PL']['HtmlEditorField']['IMAGE'] = 'Wstaw obraz'; $lang['pl_PL']['HtmlEditorField']['IMAGEDIMENSIONS'] = 'Rozmiar'; $lang['pl_PL']['HtmlEditorField']['IMAGEHEIGHTPX'] = 'Wysokość (px)'; $lang['pl_PL']['HtmlEditorField']['IMAGEWIDTHPX'] = 'Szerokość (px)'; -$lang['pl_PL']['HtmlEditorField']['INDENT'] = 'ZwiÄ™ksz wciÄ™cie'; $lang['pl_PL']['HtmlEditorField']['INSERTCOLAFTER'] = 'Wstaw kolumnÄ™ później'; $lang['pl_PL']['HtmlEditorField']['INSERTCOLBEF'] = 'Wstaw kolumnÄ™ wczeÅ›niej'; $lang['pl_PL']['HtmlEditorField']['INSERTROWAFTER'] = 'Wstaw rzÄ…d później'; @@ -123,21 +113,20 @@ $lang['pl_PL']['HtmlEditorField']['LINKDESCR'] = 'Opis linku'; $lang['pl_PL']['HtmlEditorField']['LINKEMAIL'] = 'Adres e-mail'; $lang['pl_PL']['HtmlEditorField']['LINKEXTERNAL'] = 'Inna strona'; $lang['pl_PL']['HtmlEditorField']['LINKFILE'] = 'Pobierz plik'; -$lang['pl_PL']['HtmlEditorField']['LINKINTERNAL'] = 'Strona na tej witrynie'; +$lang['pl_PL']['HtmlEditorField']['LINKINTERNAL'] = 'Strona na Twojej stronie www'; $lang['pl_PL']['HtmlEditorField']['LINKOPENNEWWIN'] = 'Otworzyć link w nowym oknie?'; $lang['pl_PL']['HtmlEditorField']['LINKTO'] = 'Linkuj do'; $lang['pl_PL']['HtmlEditorField']['OK'] = 'ok'; -$lang['pl_PL']['HtmlEditorField']['OL'] = 'Lista numerowana'; -$lang['pl_PL']['HtmlEditorField']['OUTDENT'] = 'Zmniejsz odstÄ™p'; +$lang['pl_PL']['HtmlEditorField']['OL'] = 'Numeracja'; $lang['pl_PL']['HtmlEditorField']['PAGE'] = 'Strona'; $lang['pl_PL']['HtmlEditorField']['PASTE'] = 'Wklej (Ctrl+V)'; $lang['pl_PL']['HtmlEditorField']['REDO'] = 'Przywróć (Ctrl+Y)'; -$lang['pl_PL']['HtmlEditorField']['UNDO'] = 'Cofnij (Ctrl+Z)'; +$lang['pl_PL']['HtmlEditorField']['UNDO'] = 'CofniÄ™cie (Ctrl+Z)'; $lang['pl_PL']['HtmlEditorField']['UNLINK'] = 'ZmieÅ„ link'; $lang['pl_PL']['HtmlEditorField']['UPLOAD'] = 'wgraj'; $lang['pl_PL']['HtmlEditorField']['URL'] = 'URL'; $lang['pl_PL']['HtmlEditorField']['VISUALAID'] = 'Pokaż/schowaj wytyczne'; -$lang['pl_PL']['ImageField']['NOTEADDIMAGES'] = 'Po pierwszym zapisie można dodawać zdjÄ™cia.'; +$lang['pl_PL']['ImageField']['NOTEADDIMAGES'] = 'Możesz dodać jedno zdjÄ™cie zachowane za pierwszym razem'; $lang['pl_PL']['ImageUplaoder']['ONEFROMFILESTORE'] = 'W jednym z folderów strony'; $lang['pl_PL']['ImageUploader']['ATTACH'] = 'ZaÅ‚Ä…cz %s'; $lang['pl_PL']['ImageUploader']['DELETE'] = 'UsuÅ„ %s'; @@ -146,7 +135,6 @@ $lang['pl_PL']['ImageUploader']['FROMFILESTORE'] = 'Ze schowka plików'; $lang['pl_PL']['ImageUploader']['ONEFROMCOMPUTER'] = 'na jednym z twoich komputerów'; $lang['pl_PL']['ImageUploader']['REALLYDELETE'] = 'NaprawdÄ™ chcesz usunąć ten %s?'; $lang['pl_PL']['ImageUploader']['REPLACE'] = 'ZastÄ…p %s'; -$lang['pl_PL']['Image_iframe.ss']['TITLE'] = 'Åadowanie Zdjęć (Iframe)'; $lang['pl_PL']['Member']['ADDRESS'] = 'Adres'; $lang['pl_PL']['Member']['BUTTONCHANGEPASSWORD'] = 'ZmieÅ„ hasÅ‚o'; $lang['pl_PL']['Member']['BUTTONLOGIN'] = 'Zalogowany'; @@ -156,7 +144,7 @@ $lang['pl_PL']['Member']['CONFIRMNEWPASSWORD'] = 'Potwierdź nowe hasÅ‚o'; $lang['pl_PL']['Member']['CONFIRMPASSWORD'] = 'Potwierdź hasÅ‚o'; $lang['pl_PL']['Member']['CONTACTINFO'] = 'Informacja kontaktowa'; $lang['pl_PL']['Member']['EMAIL'] = 'E-mail'; -$lang['pl_PL']['Member']['EMAILPASSWORDAPPENDIX'] = 'Twoje hasÅ‚o zostaÅ‚o zmienione. Zatrzymaj tego maila do przyszÅ‚ych potwierdzeÅ„'; +$lang['pl_PL']['Member']['EMAILPASSWORDAPPENDIX'] = 'Twoje hasÅ‚o zostaÅ‚o zmienione. Zatrzyaj tego maila do przyszÅ‚ych potwierdzeÅ„'; $lang['pl_PL']['Member']['EMAILPASSWORDINTRO'] = 'Oto Twoje nowe hasÅ‚o'; $lang['pl_PL']['Member']['EMAILSIGNUPINTRO1'] = 'DziÄ™kujemy za rejestracjÄ™ jako nowy użytkownik, szczegóły możesz zobaczyć poniżej w celu przyszÅ‚ego potwierdzenia'; $lang['pl_PL']['Member']['EMAILSIGNUPINTRO2'] = 'Możesz sie zalogować na tÄ™ stronÄ™ używajÄ…c danych z listy poniżej'; @@ -186,7 +174,6 @@ $lang['pl_PL']['Member']['YOUROLDPASSWORD'] = 'Twoje stare hasÅ‚o'; $lang['pl_PL']['MemberAuthenticator']['TITLE'] = 'E-mail i HasÅ‚o'; $lang['pl_PL']['NumericField']['VALIDATION'] = '\'%s\' nie jest liczbÄ…, tylko liczby sÄ… akceptowane przez to pole'; $lang['pl_PL']['PhoneNumberField']['VALIDATION'] = 'Wprowadź poprawny numer telefonu'; -$lang['pl_PL']['RedirectorPage']['HASBEENSETUP'] = 'Strona przekierowujÄ…ca zostaÅ‚a ustawiona bez celu, do którego ma przekierowywać.'; $lang['pl_PL']['RedirectorPage']['HEADER'] = 'Ta strona przeniesie użytkowników na innÄ… stronÄ™'; $lang['pl_PL']['RedirectorPage']['OTHERURL'] = 'Inny adres URL strony'; $lang['pl_PL']['RedirectorPage']['REDIRECTTO'] = 'PrzenieÅ› do'; @@ -212,7 +199,6 @@ $lang['pl_PL']['SiteTree']['ACCESSLOGGEDIN'] = 'Tylko zarejestrowani użytkownic $lang['pl_PL']['SiteTree']['ACCESSONLYTHESE'] = 'Tylko Ci ludzie (wybierz z listy)'; $lang['pl_PL']['SiteTree']['ADDEDTODRAFT'] = 'Dodano do roboczej strony'; $lang['pl_PL']['SiteTree']['ALLOWCOMMENTS'] = 'Zezwolić na komentarze na stronie?'; -$lang['pl_PL']['SiteTree']['APPEARSVIRTUALPAGES'] = 'Ta zawartość pojawia sie także na wirtualnych stronach w sekcjach %s.'; $lang['pl_PL']['SiteTree']['BUTTONCANCELDRAFT'] = 'Anuluj wprowadzone zmiany'; $lang['pl_PL']['SiteTree']['BUTTONCANCELDRAFTDESC'] = 'UsuÅ„ zmiany i wróć do istniejÄ…cej wersji opublikowanej strony'; $lang['pl_PL']['SiteTree']['BUTTONSAVEPUBLISH'] = 'Zapisz i opublikuj'; @@ -230,14 +216,14 @@ $lang['pl_PL']['SiteTree']['LINKSCHANGEDTO'] = 'zmieniono %s na %s'; $lang['pl_PL']['SiteTree']['MENUTITLE'] = 'Sekcja nawigacji'; $lang['pl_PL']['SiteTree']['METAADVANCEDHEADER'] = 'Zaawansowane opcje ...'; $lang['pl_PL']['SiteTree']['METADESC'] = 'Opis'; -$lang['pl_PL']['SiteTree']['METAEXTRA'] = 'WÅ‚asne Meta Tagi'; -$lang['pl_PL']['SiteTree']['METAHEADER'] = 'Meta-tagi wyszukiwarki'; +$lang['pl_PL']['SiteTree']['METAEXTRA'] = 'StaÅ‚e Meta Tagi'; +$lang['pl_PL']['SiteTree']['METAHEADER'] = 'Mechanizm wyszukiwania meta-tagów'; $lang['pl_PL']['SiteTree']['METAKEYWORDS'] = 'SÅ‚owa kluczowe'; $lang['pl_PL']['SiteTree']['METANOTEPRIORITY'] = 'RÄ™czne wprowadzenie specyfikacji dla Google SiteMaps ważnoÅ›ci dla tej strony. To jest przewodnik dla Google, jak ważna jest strona: (wprowadź wartość od 0 do 1 gdzie 0 wprowadza stronÄ™ do indexu).'; $lang['pl_PL']['SiteTree']['METAPAGEPRIO'] = 'Priorytet Strony'; $lang['pl_PL']['SiteTree']['METATITLE'] = 'TytuÅ‚'; $lang['pl_PL']['SiteTree']['MODIFIEDONDRAFT'] = 'Zmodyfikowano na roboczej stronie'; -$lang['pl_PL']['SiteTree']['NOBACKLINKS'] = 'Do tej strony nie prowadzÄ… żadne odnoÅ›niki z innych stron.'; +$lang['pl_PL']['SiteTree']['NOBACKLINKS'] = 'Strona nie zostaÅ‚a zlinkowana do żadnej stron'; $lang['pl_PL']['SiteTree']['NOTEUSEASHOMEPAGE'] = 'Użyj tej strony jako \'strony startowej\' dla nastÄ™pujÄ…cych domen: (oddziel domeny cudzysÅ‚owem)'; $lang['pl_PL']['SiteTree']['PAGESLINKING'] = 'NastÄ™pujÄ…ce strony majÄ… adres:'; $lang['pl_PL']['SiteTree']['PAGETITLE'] = 'Nazwa strony'; @@ -246,8 +232,8 @@ $lang['pl_PL']['SiteTree']['PRIORITYLEASTIMPORTANT'] = 'Najmniej ważny'; $lang['pl_PL']['SiteTree']['PRIORITYMOSTIMPORTANT'] = 'Najważniejszy'; $lang['pl_PL']['SiteTree']['PRIORITYNOTINDEXED'] = 'Nie zindexowany'; $lang['pl_PL']['SiteTree']['REMOVEDFROMDRAFT'] = 'UsuniÄ™to z roboczej strony'; -$lang['pl_PL']['SiteTree']['SHOWINMENUS'] = 'Pokazuj w menu?'; -$lang['pl_PL']['SiteTree']['SHOWINSEARCH'] = 'Pokazuj w wyszukiwarce?'; +$lang['pl_PL']['SiteTree']['SHOWINMENUS'] = 'Pokazać w menu?'; +$lang['pl_PL']['SiteTree']['SHOWINSEARCH'] = 'Pokazać w wyszukiwarce?'; $lang['pl_PL']['SiteTree']['TABACCESS'] = 'DostÄ™p'; $lang['pl_PL']['SiteTree']['TABBACKLINKS'] = 'Linki zwrotne'; $lang['pl_PL']['SiteTree']['TABBEHAVIOUR'] = 'Zachowanie'; @@ -258,7 +244,6 @@ $lang['pl_PL']['SiteTree']['TABREPORTS'] = 'Raporty'; $lang['pl_PL']['SiteTree']['TOPLEVEL'] = 'Zawartość strony (Główny Poziom)'; $lang['pl_PL']['SiteTree']['URL'] = 'URL'; $lang['pl_PL']['SiteTree']['VALIDATIONURLSEGMENT1'] = 'Inna strona używa tego adresu URL. Adres URL musi być unikalny dla każdej strony.'; -$lang['pl_PL']['SiteTree']['VALIDATIONURLSEGMENT2'] = 'Adresy URL mogÄ… skÅ‚adać siÄ™ jedynie z liczb, cyfr oraz znaków \'-\'.'; $lang['pl_PL']['TableField']['ISREQUIRED'] = 'W %s \'%s\' jest wymagane'; $lang['pl_PL']['TableField.ss']['CSVEXPORT'] = 'Eksportuj do CSV'; $lang['pl_PL']['ToggleCompositeField.ss']['HIDE'] = 'Ukryj'; diff --git a/lang/pt_BR.php b/lang/pt_BR.php index 294c72f02..a71bedaa3 100644 --- a/lang/pt_BR.php +++ b/lang/pt_BR.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('pt_BR', $lang) && is_array($lang['pt_BR'])) { - $lang['pt_BR'] = array_merge($lang['en_US'], $lang['pt_BR']); -} else { - $lang['pt_BR'] = $lang['en_US']; -} +$lang['pt_BR'] = $lang['en_US']; $lang['pt_BR']['BasicAuth']['ENTERINFO'] = 'Por favor entre nome de usuário e senha.'; $lang['pt_BR']['BasicAuth']['ERRORNOTADMIN'] = 'Este usuário não é um administrador'; diff --git a/lang/pt_PT.php b/lang/pt_PT.php index 661a86614..20365ca57 100644 --- a/lang/pt_PT.php +++ b/lang/pt_PT.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('pt_PT', $lang) && is_array($lang['pt_PT'])) { - $lang['pt_PT'] = array_merge($lang['en_US'], $lang['pt_PT']); -} else { - $lang['pt_PT'] = $lang['en_US']; -} +$lang['pt_PT'] = $lang['en_US']; $lang['pt_PT']['BasicAuth']['ENTERINFO'] = 'Por favor insira um nome de utilizador e password.'; $lang['pt_PT']['BasicAuth']['ERRORNOTADMIN'] = 'Esse utilizador não é um administrador.'; @@ -271,391 +267,4 @@ $lang['pt_PT']['VirtualPage']['CHOOSE'] = 'Escolha uma página para onde redirec $lang['pt_PT']['VirtualPage']['EDITCONTENT'] = 'clique aqui para editar o conteúdo'; $lang['pt_PT']['VirtualPage']['HEADER'] = 'Esta é uma página virtual'; -// --- New New New - -// SiteTree.php -$lang['pt_PT']['SiteTree']['CHANGETO'] = 'Mudar para'; -$lang['pt_PT']['SiteTree']['CURRENTLY'] = 'Actualmente'; -$lang['pt_PT']['SiteTree']['CURRENT'] = 'Actual'; - -$lang['pt_PT']['Page']['SINGULARNAME'] = 'Página'; -$lang['pt_PT']['Page']['PLURALNAME'] = 'Páginas'; -$lang['pt_PT']['ErrorPage']['SINGULARNAME'] = 'Página de Erro'; -$lang['pt_PT']['ErrorPage']['PLURALNAME'] = 'Páginas de Erro'; -$lang['pt_PT']['UserDefinedForm']['SINGULARNAME'] = 'Formulário Definido pelo Utilizador'; -$lang['pt_PT']['UserDefinedForm']['PLURALNAME'] = 'Formulários Definidos pelo Utilizador'; -$lang['pt_PT']['RedirectorPage']['SINGULARNAME'] = 'Página de Redireccionamento'; -$lang['pt_PT']['RedirectorPage']['PLURALNAME'] = 'Páginas de Redireccionamento'; -$lang['pt_PT']['VirtualPage']['SINGULARNAME'] = 'Página Virtual'; -$lang['pt_PT']['VirtualPage']['PLURALNAME'] = 'Páginas Virtuais'; -$lang['pt_PT']['SubscribeForm']['SINGULARNAME'] = 'Página de Subscrição'; -$lang['pt_PT']['SubscribeForm']['PLURALNAME'] = 'Páginas de Subscrição'; - -// --- New New New New - -// forms/TreeSelectorField.php -$lang['pt_PT']['TreeSelectorField']['SAVE'] = 'gravar'; -$lang['pt_PT']['TreeSelectorField']['CANCEL'] = 'cancelar'; - -// forms/NumericField.php -$lang['pt_PT']['NumericField']['VALIDATIONJS'] = 'não é um número. Apenas números podem ser inseridos neste campo'; - -// forms/HtmlEditorField.php -$lang['pt_PT']['HtmlEditorField']['CLOSE'] = 'fechar'; -$lang['pt_PT']['HtmlEditorField']['LINK'] = 'Link'; -$lang['pt_PT']['HtmlEditorField']['IMAGE'] = 'Imagem'; -$lang['pt_PT']['HtmlEditorField']['FLASH'] = 'Flash'; - -// forms/GSTNumberField.php -$lang['pt_PT']['GSTNumberField']['VALIDATIONJS'] = 'Por favor insira um número GST válido'; - -// forms/Form.php -$lang['pt_PT']['Form']['VALIDATOR'] = 'Validador'; - -// forms/FormField.php -$lang['pt_PT']['FormField']['NONE'] = 'nenhum'; - -// forms/EmailField.php -$lang['pt_PT']['EmailField']['VALIDATIONJS'] = 'Por favor insira um endereço de email.'; - -// forms/EditableTextField.php -$lang['pt_PT']['EditableTextField']['TEXTBOXLENGTH'] = 'Tamanho da caixa de texto'; -$lang['pt_PT']['EditableTextField']['TEXTLENGTH'] = 'Comprimento do texto'; -$lang['pt_PT']['EditableTextField']['NUMBERROWS'] = 'Número de linhas'; -$lang['pt_PT']['EditableTextField']['DEFAULTTEXT'] = 'Texto pré-definido'; - -// forms/EditableFormField.php -$lang['pt_PT']['EditableFormField']['ENTERQUESTION'] = 'Insira a questão'; -$lang['pt_PT']['EditableFormField']['REQUIRED'] = 'Obrigatório?'; - -// forms/EditableEmailField.php -$lang['pt_PT']['EditableEmailField']['SENDCOPY'] = 'Enviar uma cópia do formulário para este email'; - -// forms/EditableCheckbox.php -$lang['pt_PT']['EditableCheckbox']['ANY'] = 'Qualquer um'; -$lang['pt_PT']['EditableCheckbox']['SELECTED'] = 'Seleccionado'; -$lang['pt_PT']['EditableCheckbox']['NOTSELECTED'] = 'Não Seleccionado'; - -// forms/DateField.php -$lang['pt_PT']['DateField']['VALIDATIONJS'] = 'Por favor insira uma data válida (DD/MM/AAAA).'; -$lang['pt_PT']['DateField']['NODATESET'] = 'Nenhuma data definida'; -$lang['pt_PT']['DateField']['TODAY'] = 'Hoje'; -$lang['pt_PT']['DateField']['NOTSET'] = 'Não definido'; - -// forms/DataReport.php -$lang['pt_PT']['DataReport']['EXPORTCSV'] = 'Exportar para CSV'; - -// forms/CurrencyField.php -$lang['pt_PT']['CurrencyField']['VALIDATIONJS'] = 'Por favor insira um valor monetário correcto.'; -$lang['pt_PT']['CurrencyField']['CURRENCYSYMBOL'] = '€'; - -// forms/CreditCardField.php -$lang['pt_PT']['CreditCardField']['VALIDATIONJS1'] = 'Por favor certifique-se que inseriu o'; -$lang['pt_PT']['CreditCardField']['VALIDATIONJS2'] = 'número correctamente'; -$lang['pt_PT']['CreditCardField']['FIRST'] = 'primeiro'; -$lang['pt_PT']['CreditCardField']['SECOND'] = 'segundo'; -$lang['pt_PT']['CreditCardField']['THIRD'] = 'terceiro'; -$lang['pt_PT']['CreditCardField']['FOURTH'] = 'quarto'; - -// forms/ConfirmedPasswordField.php -$lang['pt_PT']['ConfirmedPasswordField']['HAVETOMATCH'] = 'As passwords teem de coincidir.'; -$lang['pt_PT']['ConfirmedPasswordField']['NOEMPTY'] = 'A password não pode estar vazia.'; -$lang['pt_PT']['ConfirmedPasswordField']['BETWEEN'] = 'As passwords devem ter entre %s e %s caracteres'; -$lang['pt_PT']['ConfirmedPasswordField']['ATLEAST'] = 'As passwords devem ter no mínimo %s caracteres'; -$lang['pt_PT']['ConfirmedPasswordField']['MAXIMUM'] = 'As passwords podem ter no máximo %s caracteres'; -$lang['pt_PT']['ConfirmedPasswordField']['LEASTONE'] = 'As passwords devem conter pelo menos um numero e um caracter alfanumérico'; - -// forms/CompositeDateField.php -$lang['pt_PT']['CompositeDateField']['DAY'] = 'Dia'; -$lang['pt_PT']['CompositeDateField']['MONTH'] = 'Mês'; -$lang['pt_PT']['CompositeDateField']['VALIDATIONJS1'] = 'Por favor certifique-se que tem o'; -$lang['pt_PT']['CompositeDateField']['VALIDATIONJS2'] = 'correcto'; -$lang['pt_PT']['CompositeDateField']['DAYJS'] = 'dia'; -$lang['pt_PT']['CompositeDateField']['MONTHJS'] = 'mês'; -$lang['pt_PT']['CompositeDateField']['YEARJS'] = 'ano'; - -// forms/BankAccountField.php -$lang['pt_PT']['BankAccountField']['VALIDATIONJS'] = 'Por favor, insira um número bancário correcto'; - -// forms/editor/FieldEditor.php -$lang['pt_PT']['FieldEditor']['EMAILSUBMISSION'] = 'Enviar os dados para o email:'; -$lang['pt_PT']['FieldEditor']['EMAILONSUBMIT'] = 'Enviar email após submissão dos dados:'; - -// parsers/BBCodeParser.php -$lang['pt_PT']['BBCodeParser']['BOLD'] = 'Texto Negrito'; -$lang['pt_PT']['BBCodeParser']['BOLDEXAMPLE'] = 'Negrito'; -$lang['pt_PT']['BBCodeParser']['ITALIC'] = 'Texto Itálico'; -$lang['pt_PT']['BBCodeParser']['ITALICEXAMPLE'] = 'Itálico'; -$lang['pt_PT']['BBCodeParser']['UNDERLINE'] = 'Texto Sublinhado'; -$lang['pt_PT']['BBCodeParser']['UNDERLINEEXAMPLE'] = 'Sublinhado'; -$lang['pt_PT']['BBCodeParser']['STRUCK'] = 'Texto Rasurado'; -$lang['pt_PT']['BBCodeParser']['STRUCKEXAMPLE'] = 'Rasurado'; -$lang['pt_PT']['BBCodeParser']['COLORED'] = 'Texto Colorido'; -$lang['pt_PT']['BBCodeParser']['COLOREDEXAMPLE'] = 'texto azul'; -$lang['pt_PT']['BBCodeParser']['ALIGNEMENT'] = 'Alinhamento'; -$lang['pt_PT']['BBCodeParser']['ALIGNEMENTEXAMPLE'] = 'alinhado à direita'; -$lang['pt_PT']['BBCodeParser']['LINK'] = 'Link'; -$lang['pt_PT']['BBCodeParser']['LINKDESCRIPTION'] = 'Link para outro site'; -$lang['pt_PT']['BBCodeParser']['EMAILLINK'] = 'Link de Email'; -$lang['pt_PT']['BBCodeParser']['EMAILLINKDESCRIPTION'] = 'Criar um link para um endereço de email'; -$lang['pt_PT']['BBCodeParser']['IMAGE'] = 'Imagem'; -$lang['pt_PT']['BBCodeParser']['IMAGEDESCRIPTION'] = 'Mostrar uma imagem'; -$lang['pt_PT']['BBCodeParser']['CODE'] = 'Código'; -$lang['pt_PT']['BBCodeParser']['CODEDESCRIPTION'] = 'Bloco de texto não formatado'; -$lang['pt_PT']['BBCodeParser']['CODEEXAMPLE'] = 'Bloco de código'; -$lang['pt_PT']['BBCodeParser']['UNORDERED'] = 'Lista sem ordenação'; -$lang['pt_PT']['BBCodeParser']['UNORDEREDDESCRIPTION'] = 'Lista sem ordenação'; -$lang['pt_PT']['BBCodeParser']['UNORDEREDEXAMPLE1'] = 'item sem ordenação 1'; -$lang['pt_PT']['BBCodeParser']['UNORDEREDEXAMPLE2'] = 'item sem ordenação 2'; - -// search/AdvancedSearchForm.php -$lang['pt_PT']['AdvancedSearchForm']['SEARCHBY'] = 'PROCURAR POR'; -$lang['pt_PT']['AdvancedSearchForm']['ALLWORDS'] = 'Todas as palavras'; -$lang['pt_PT']['AdvancedSearchForm']['EXACT'] = 'Frase exacta'; -$lang['pt_PT']['AdvancedSearchForm']['ATLEAST'] = 'Pelo menos uma das palavras'; -$lang['pt_PT']['AdvancedSearchForm']['WITHOUT'] = 'Sem as palavras'; -$lang['pt_PT']['AdvancedSearchForm']['SORTBY'] = 'ORDENAR POR'; -$lang['pt_PT']['AdvancedSearchForm']['RELEVANCE'] = 'Relevância'; -$lang['pt_PT']['AdvancedSearchForm']['LASTUPDATED'] = 'Última actualização'; -$lang['pt_PT']['AdvancedSearchForm']['PAGETITLE'] = 'Título da Página'; -$lang['pt_PT']['AdvancedSearchForm']['LASTUPDATEDHEADER'] = 'ÚLTIMA ACTUALIZAÇÂO'; -$lang['pt_PT']['AdvancedSearchForm']['FROM'] = 'De'; -$lang['pt_PT']['AdvancedSearchForm']['TO'] = 'Até'; -$lang['pt_PT']['AdvancedSearchForm']['GO'] = 'Ir'; - -// search/SearchForm.php -$lang['pt_PT']['SearchForm']['SEARCH'] = 'Procurar'; -$lang['pt_PT']['SearchForm']['GO'] = 'Ir'; - -// security/Security.php -$lang['pt_PT']['Security']['LOGIN'] = 'Autenticação'; -$lang['pt_PT']['Security']['PERMFAILURE'] = 'Esta página requer autenticação e previlégios de administrador. -Insira as sua credenciais abaixo para continuar.'; -$lang['pt_PT']['Security']['ENCDISABLED1'] = 'Encriptação de passwords desligada!'; -$lang['pt_PT']['Security']['ENCDISABLED2'] = 'Para encriptas as passwords, insira a seguinte linha'; -$lang['pt_PT']['Security']['ENCDISABLED3'] = 'em mysite/_config.php'; -$lang['pt_PT']['Security']['NOTHINGTOENCRYPT1'] = 'Sem passwords para encriptar'; -$lang['pt_PT']['Security']['NOTHINGTOENCRYPT2'] = 'Todos os membros teem as passwords encriptadas!'; -$lang['pt_PT']['Security']['ENCRYPT'] = 'Encriptar todas as passwords'; -$lang['pt_PT']['Security']['ENCRYPTWITH'] = 'As passwords serão encriptadas com o algoritmo "%s"'; -$lang['pt_PT']['Security']['ENCRYPTWITHSALT'] = 'com uma chave para aumentar a segurança'; -$lang['pt_PT']['Security']['ENCRYPTWITHOUTSALT'] = 'sem chave para aumentar a segurança'; -$lang['pt_PT']['Security']['ENCRYPTEDMEMBERS'] = 'Password encriptada para o membro'; -$lang['pt_PT']['Security']['EMAIL'] = 'Email:'; -$lang['pt_PT']['Security']['ID'] = 'ID:'; - -// security/Permission.php -$lang['pt_PT']['Permission']['FULLADMINRIGHTS'] = 'Previlégios de Administrador'; -$lang['pt_PT']['Permission']['PERMSDEFINED'] = 'Estão definidas as seguintes permissões'; - -// core/model/Translatable.php -$lang['pt_PT']['Translatable']['TRANSLATIONS'] = 'Traduções'; -$lang['pt_PT']['Translatable']['CREATE'] = 'Criar nova tradução'; -$lang['pt_PT']['Translatable']['NEWLANGUAGE'] = 'Nova Língua'; -$lang['pt_PT']['Translatable']['CREATEBUTTON'] = 'Criar'; -$lang['pt_PT']['Translatable']['EXISTING'] = 'Traduções existentes'; - -// core/model/SiteTree.php -$lang['pt_PT']['SiteTree']['DEFAULTHOMETITLE'] = 'Início'; -$lang['pt_PT']['SiteTree']['DEFAULTHOMECONTENT'] = '

      Bem-vindo ao Silverstripe! Esta é a página inicial pré-definida. Pode editar esta página no CMS. Pode vêr a documentação de desenvolvimento, ou os tutoriais.

      '; -$lang['pt_PT']['SiteTree']['DEFAULTABOUTTITLE'] = 'Sobre'; -$lang['pt_PT']['SiteTree']['DEFAULTABOUTCONTENT'] = '

      Pode inserir o seu conteúdo nesta página ou apaga-la e criar novas.

      '; -$lang['pt_PT']['SiteTree']['DEFAULTCONTACTTITLE'] = 'Contacte-nos'; -$lang['pt_PT']['SiteTree']['DEFAULTCONTACTCONTENT'] = '

      Pode inserir o seu conteúdo nesta página ou apaga-la e criar novas.

      '; - -// core/model/ErrorPage.php -$lang['pt_PT']['ErrorPage']['DEFAULTERRORPAGETITLE'] = 'Página de Erro'; -$lang['pt_PT']['ErrorPage']['DEFAULTERRORPAGECONTENT'] = '

      Pedimos desculpa, mas aparentemente tentou aceder a uma página que não existe.

      Verifique o URL que utilizou e tente novamente.

      '; -$lang['pt_PT']['ErrorPage']['404'] = '404 - Página não encontrada'; -$lang['pt_PT']['ErrorPage']['500'] = '500 - Erro do servidor'; - -// SubmittedFormReportField.ss -$lang['pt_PT']['SubmittedFormReportField.ss']['SUBMITTED'] = 'Inserido em'; - -// RelationComplexTableField.ss -$lang['pt_PT']['RelationComplexTableField.ss']['ADD'] = 'Adicionar'; -$lang['pt_PT']['RelationComplexTableField.ss']['SHOW'] = 'Mostrar'; -$lang['pt_PT']['RelationComplexTableField.ss']['EDIT'] = 'Editar'; -$lang['pt_PT']['RelationComplexTableField.ss']['DELETE'] = 'Apagar'; -$lang['pt_PT']['RelationComplexTableField.ss']['NOTFOUND'] = 'Nenhum item encontrado'; - -// FieldEditor.ss -$lang['pt_PT']['FieldEditor.ss']['ADD'] = 'Adicionar'; -$lang['pt_PT']['FieldEditor.ss']['TEXTTITLE'] = 'Adicionar campo de texto'; -$lang['pt_PT']['FieldEditor.ss']['TEXT'] = 'Texto'; -$lang['pt_PT']['FieldEditor.ss']['CHECKBOXTITLE'] = 'Adicionar caixa de tick'; -$lang['pt_PT']['FieldEditor.ss']['CHECKBOX'] = 'Caixa de Tick'; -$lang['pt_PT']['FieldEditor.ss']['DROPDOWNTITLE'] = 'Adicionar caixa de selecção'; -$lang['pt_PT']['FieldEditor.ss']['DROPDOWN'] = 'Caixa de selecção'; -$lang['pt_PT']['FieldEditor.ss']['RADIOSETTITLE'] = 'Adicionar conjunto de botões de rádio'; -$lang['pt_PT']['FieldEditor.ss']['RADIOSET'] = 'Conjunto de Botões de Rádio'; -$lang['pt_PT']['FieldEditor.ss']['EMAILTITLE'] = 'Adicionar campo de email'; -$lang['pt_PT']['FieldEditor.ss']['EMAIL'] = 'Campo de email'; -$lang['pt_PT']['FieldEditor.ss']['FORMHEADINGTITLE'] = 'Adicionar cabeçalho'; -$lang['pt_PT']['FieldEditor.ss']['FORMHEADING'] = 'Cabeçalho'; -$lang['pt_PT']['FieldEditor.ss']['DATETITLE'] = 'Adicionar Campo de Data'; -$lang['pt_PT']['FieldEditor.ss']['DATE'] = 'Data'; -$lang['pt_PT']['FieldEditor.ss']['FILETITLE'] = 'Adicionar Campo de envio de ficheiro'; -$lang['pt_PT']['FieldEditor.ss']['FILE'] = 'Ficheiro'; -$lang['pt_PT']['FieldEditor.ss']['CHECKBOXGROUPTITLE'] = 'Adicionar Grupo de caixas de tick'; -$lang['pt_PT']['FieldEditor.ss']['CHECKBOXGROUP'] = 'Grupo de Caixas de tick'; -$lang['pt_PT']['FieldEditor.ss']['MEMBERTITLE'] = 'Adicionar Selecção de Membros'; -$lang['pt_PT']['FieldEditor.ss']['MEMBER'] = 'Selecção de Membros'; - -// EditableTextField.ss -$lang['pt_PT']['EditableTextField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableTextField.ss']['TEXTFIELD'] = 'Campo de texto'; -$lang['pt_PT']['EditableTextField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableTextField.ss']['DELETE'] = 'Apagar este campo'; - -// EditableRadioOption.ss -$lang['pt_PT']['EditableRadioOption.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableRadioOption.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableRadioOption.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; - -// EditableRadioField.ss -$lang['pt_PT']['EditableRadioField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableRadioField.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableRadioField.ss']['SET'] = 'Conjunto de botões de rádio'; -$lang['pt_PT']['EditableRadioField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableRadioField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableRadioField.ss']['REQUIRED'] = 'Este campo é obrigatório para este formulário e não pode ser apagado.'; -$lang['pt_PT']['EditableRadioField.ss']['ADD'] = 'Adicionar opção'; - -// EditableFormHeading.ss -$lang['pt_PT']['EditableFormHeading.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableFormHeading.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableFormHeading.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableFormHeading.ss']['HEADING'] = 'Cabeçalho'; - -// EditableFormField.ss -$lang['pt_PT']['EditableFormField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableFormField.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableFormField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableFormField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableFormField.ss']['REQUIRED'] = 'Este campo é obrigatório para este formulário e não pode ser apagado.'; - -// EditableRadioOption.ss -$lang['pt_PT']['EditableFormFieldOption.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableFormFieldOption.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableFormFieldOption.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; - -// EditableFileField.ss -$lang['pt_PT']['EditableFileField.ss']['DRAG'] = 'Arraste para reordenar os campos'; - -// EditableFileField.ss -$lang['pt_PT']['EditableFileField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableFileField.ss']['FILE'] = 'Campo de envio de ficheiro'; -$lang['pt_PT']['EditableFileField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableFileField.ss']['DELETE'] = 'Remover esta opção'; - -// EditableEmailField.ss -$lang['pt_PT']['EditableEmailField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableEmailField.ss']['EMAIL'] = 'Campo de email'; -$lang['pt_PT']['EditableEmailField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableEmailField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableEmailField.ss']['REQUIRED'] = 'Este campo é obrigatório para este formulário e não pode ser apagado.'; - -// EditableDropdown.ss -$lang['pt_PT']['EditableDropdown.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableDropdown.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableDropdown.ss']['DROPDOWN'] = 'Lista de Selecção'; -$lang['pt_PT']['EditableDropdown.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableDropdown.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableDropdown.ss']['REQUIRED'] = 'Este campo é obrigatório para este formulário e não pode ser apagado.'; - -// EditableDropdownOption.ss -$lang['pt_PT']['EditableDropdownOption.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableDropdownOption.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableDropdownOption.ss']['DELETE'] = 'Remover esta opção'; - -// EditableDateField.ss -$lang['pt_PT']['EditableDateField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableDateField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableDateField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableDateField.ss']['DATE'] = 'Campo de Data'; - -// EditableCheckbox.ss -$lang['pt_PT']['EditableCheckbox.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableCheckbox.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableCheckbox.ss']['CHECKBOX'] = 'Caixa de tick'; -$lang['pt_PT']['EditableCheckbox.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableCheckbox.ss']['DELETE'] = 'Remover esta opção'; - -// EditableCheckboxOption.ss -$lang['pt_PT']['EditableCheckboxOption.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableCheckboxOption.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableCheckboxOption.ss']['DELETE'] = 'Remover esta opção'; - -// EditableCheckboxGroupField.ss -$lang['pt_PT']['EditableCheckboxGroupField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['DATE'] = 'Campo de Data'; - -// EditableCheckboxGroupField.ss -$lang['pt_PT']['EditableCheckboxGroupField.ss']['LOCKED'] = 'Estes campos não podem ser alterados'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['DRAG'] = 'Arraste para reordenar os campos'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['CHECKBOXGROUP'] = 'Grupo de Caixas de tick'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['MORE'] = 'Mais opções'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['DELETE'] = 'Remover esta opção'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['REQUIRED'] = 'Este campo é obrigatório para este formulário e não pode ser apagado.'; -$lang['pt_PT']['EditableCheckboxGroupField.ss']['ADD'] = 'Adicionar opção'; - -// ForgotPasswordEmail.ss -$lang['pt_PT']['ForgotPasswordEmail.ss']['TEXT1'] = 'Aqui está o seu'; -$lang['pt_PT']['ForgotPasswordEmail.ss']['TEXT2'] = 'link de reset da password'; -$lang['pt_PT']['ForgotPasswordEmail.ss']['TEXT3'] = 'para'; - -// TableListField_PageControls.ss -$lang['pt_PT']['TableListField_PageControls.ss']['VIEWLAST'] = 'Ver último'; -$lang['pt_PT']['TableListField_PageControls.ss']['VIEWFIRST'] = 'Ver primeiro'; -$lang['pt_PT']['TableListField_PageControls.ss']['VIEWPREVIOUS'] = 'Ver anterior'; -$lang['pt_PT']['TableListField_PageControls.ss']['VIEWNEXT'] = 'Ver próximo'; -$lang['pt_PT']['TableListField_PageControls.ss']['DISPLAYING'] = 'A Mostrar'; -$lang['pt_PT']['TableListField_PageControls.ss']['TO'] = 'até'; -$lang['pt_PT']['TableListField_PageControls.ss']['OF'] = 'de'; - -// New2 - -$lang['pt_PT']['TableField.ss']['ADD'] = 'Adicionar nova linha'; -$lang['pt_PT']['TableField.ss']['ADDITEM'] = 'Adicionar'; -$lang['pt_PT']['TableField.ss']['DELETEROW'] = 'Apagar esta linha'; -$lang['pt_PT']['TableField.ss']['DELETE'] = 'apagar'; - -$lang['pt_PT']['Security']['OPENIDHEADER'] = 'Credenciais OpenID/i-name'; -$lang['pt_PT']['Security']['MEMBERALREADYEXISTS'] = 'Já existe um utilizador com esta identidade'; -$lang['pt_PT']['Security']['OPENIDURL'] = 'OpenID URL/i-name'; -$lang['pt_PT']['Security']['OPENIDDESC'] = '

      Certifique-se que inseriu aqui as suas credenciais OpenID/i-name normalizadas - , p.ex. com protocolo e barra para a direita para o OpenID (ex. http://openid.silverstripe.com/).

      '; -$lang['pt_PT']['Security']['EDITOPENIDURL'] = 'OpenID URL/i-name (ex. http://openid.silverstripe.com/)'; -$lang['pt_PT']['Security']['OPENIDURLNORMALIZATION'] = '

      Certifique-se que inseriu aqui as suas credenciais OpenID/i-name normalizadas - , p.ex. com protocolo e barra para a direita para o OpenID (ex. http://openid.silverstripe.com/).

      '; - -$lang['pt_PT']['TableListField']['CSVEXPORT'] = 'Exportar para CSV'; -$lang['pt_PT']['TableListField']['PRINT'] = 'Imprimir'; - -$lang['pt_PT']['Permission']['FULLADMINRIGHTS'] = 'Permissões de administração total'; - -$lang['pt_PT']['Page']['CLASSNAME'] = 'Página'; - -$lang['pt_PT']['Statistics']['TRENDS'] = 'Tendências'; -$lang['pt_PT']['Statistics']['LEGEND'] = 'Legenda'; -$lang['pt_PT']['Statistics']['BROWSERS'] = 'Browsers'; -$lang['pt_PT']['Statistics']['ID'] = 'ID'; -$lang['pt_PT']['Statistics']['EMAIL'] = 'Email'; -$lang['pt_PT']['Statistics']['JOINED'] = 'Creado em'; -$lang['pt_PT']['Statistics']['REGISTEREDUSERS'] = 'Utilizadores Registados'; -$lang['pt_PT']['Statistics']['CSVEXPORT'] = 'Exportar como CSV'; -$lang['pt_PT']['Statistics']['RECENTPAGEVIEWS'] = 'Visualização Recente de Páginas'; -$lang['pt_PT']['Statistics']['TIME'] = 'Data/Hora'; -$lang['pt_PT']['Statistics']['BROWSER'] = 'Browser'; -$lang['pt_PT']['Statistics']['OSABREV'] = 'SO'; -$lang['pt_PT']['Statistics']['USER'] = 'Utilizador'; -$lang['pt_PT']['Statistics']['PAGE'] = 'Página'; -$lang['pt_PT']['Statistics']['PAGEVIEWS'] = 'Visualizações'; -$lang['pt_PT']['Statistics']['OS'] = 'Sistemas Operativos'; -$lang['pt_PT']['Statistics']['USERACTIVITY'] = 'Actividade dos Utilizadores'; - - ?> \ No newline at end of file diff --git a/lang/ru_RU.php b/lang/ru_RU.php index 7d84623d7..ccc9fe114 100644 --- a/lang/ru_RU.php +++ b/lang/ru_RU.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('ru_RU', $lang) && is_array($lang['ru_RU'])) { - $lang['ru_RU'] = array_merge($lang['en_US'], $lang['ru_RU']); -} else { - $lang['ru_RU'] = $lang['en_US']; -} +$lang['ru_RU'] = $lang['en_US']; $lang['ru_RU']['BasicAuth']['ENTERINFO'] = 'ПожалуйÑта, введите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль.'; $lang['ru_RU']['BasicAuth']['ERRORNOTADMIN'] = 'Такой пользователь не ÑвлÑетÑÑ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором.'; diff --git a/lang/sk_SK.php b/lang/sk_SK.php index e94e4c75a..a7dc41158 100644 --- a/lang/sk_SK.php +++ b/lang/sk_SK.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('sk_SK', $lang) && is_array($lang['sk_SK'])) { - $lang['sk_SK'] = array_merge($lang['en_US'], $lang['sk_SK']); -} else { - $lang['sk_SK'] = $lang['en_US']; -} +$lang['sk_SK'] = $lang['en_US']; $lang['sk_SK']['BasicAuth']['ENTERINFO'] = 'Prosím zadajte používateľské meno a heslo.'; $lang['sk_SK']['BasicAuth']['ERRORNOTADMIN'] = 'Tento používateľ nie je administrátor.'; diff --git a/lang/sv_SE.php b/lang/sv_SE.php index cf1b81574..e57077290 100644 --- a/lang/sv_SE.php +++ b/lang/sv_SE.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('sv_SE', $lang) && is_array($lang['sv_SE'])) { - $lang['sv_SE'] = array_merge($lang['en_US'], $lang['sv_SE']); -} else { - $lang['sv_SE'] = $lang['en_US']; -} +$lang['sv_SE'] = $lang['en_US']; $lang['sv_SE']['BasicAuth']['ENTERINFO'] = 'Var god ange användarnamn och lösenord'; $lang['sv_SE']['BasicAuth']['ERRORNOTADMIN'] = 'Den användaren är ingen administratör'; @@ -128,7 +124,6 @@ $lang['sv_SE']['HtmlEditorField']['LINKOPENNEWWIN'] = 'Öppna länk i nytt föns $lang['sv_SE']['HtmlEditorField']['LINKTO'] = 'Länka till'; $lang['sv_SE']['HtmlEditorField']['OK'] = 'ok'; $lang['sv_SE']['HtmlEditorField']['OL'] = 'Numrerad lista'; -$lang['sv_SE']['HtmlEditorField']['OUTDENT'] = 'Minska indrag'; $lang['sv_SE']['HtmlEditorField']['PAGE'] = 'Sida'; $lang['sv_SE']['HtmlEditorField']['PASTE'] = 'Klistra in'; $lang['sv_SE']['HtmlEditorField']['REDO'] = 'Gör om'; @@ -215,7 +210,6 @@ $lang['sv_SE']['SiteTree']['APPEARSVIRTUALPAGES'] = 'Det här innehÃ¥llet finns $lang['sv_SE']['SiteTree']['BUTTONCANCELDRAFT'] = 'Upphäv utkast-ändringar'; $lang['sv_SE']['SiteTree']['BUTTONCANCELDRAFTDESC'] = 'Radera ditt utkast och Ã¥tergÃ¥ till den publicerade sidan'; $lang['sv_SE']['SiteTree']['BUTTONSAVEPUBLISH'] = 'Spara & publicera'; -$lang['sv_SE']['SiteTree']['BUTTONUNPUBLISH'] = 'Avpublicera'; $lang['sv_SE']['SiteTree']['BUTTONUNPUBLISHDESC'] = 'Ta bort den här sidan frÃ¥n den publicerade sajten'; $lang['sv_SE']['SiteTree']['EDITANYONE'] = 'Alla som kan logga in'; $lang['sv_SE']['SiteTree']['EDITHEADER'] = 'Vem kan redigera den här sidan frÃ¥n CMS:et'; @@ -232,7 +226,6 @@ $lang['sv_SE']['SiteTree']['METADESC'] = 'Beskrivning'; $lang['sv_SE']['SiteTree']['METAEXTRA'] = 'Egna meta-taggar'; $lang['sv_SE']['SiteTree']['METAHEADER'] = 'Meta-taggar för sökmotorer'; $lang['sv_SE']['SiteTree']['METAKEYWORDS'] = 'Nyckelord'; -$lang['sv_SE']['SiteTree']['METAPAGEPRIO'] = 'Sidprioritet'; $lang['sv_SE']['SiteTree']['METATITLE'] = 'Titel'; $lang['sv_SE']['SiteTree']['MODIFIEDONDRAFT'] = 'Modifierad pÃ¥ utkast-sajten'; $lang['sv_SE']['SiteTree']['NOBACKLINKS'] = 'Den här sidan har inte blivit länkad frÃ¥n nÃ¥gon annan sida.'; diff --git a/lang/tr_TR.php b/lang/tr_TR.php index 26891fd81..5f86eb2aa 100644 --- a/lang/tr_TR.php +++ b/lang/tr_TR.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('tr_TR', $lang) && is_array($lang['tr_TR'])) { - $lang['tr_TR'] = array_merge($lang['en_US'], $lang['tr_TR']); -} else { - $lang['tr_TR'] = $lang['en_US']; -} +$lang['tr_TR'] = $lang['en_US']; $lang['tr_TR']['BasicAuth']['ENTERINFO'] = 'Lütfen kullanıcı adı ve ÅŸifrenizi giriniz.'; $lang['tr_TR']['BasicAuth']['ERRORNOTADMIN'] = 'O kullanıcı, yönetici deÄŸildir'; diff --git a/lang/zh_CN.php b/lang/zh_CN.php index bbae345bc..f921c9d08 100644 --- a/lang/zh_CN.php +++ b/lang/zh_CN.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('zh_CN', $lang) && is_array($lang['zh_CN'])) { - $lang['zh_CN'] = array_merge($lang['en_US'], $lang['zh_CN']); -} else { - $lang['zh_CN'] = $lang['en_US']; -} +$lang['zh_CN'] = $lang['en_US']; $lang['zh_CN']['BasicAuth']['ENTERINFO'] = '请输入用户å和密ç '; $lang['zh_CN']['BasicAuth']['ERRORNOTADMIN'] = '此用户没有管ç†å‘˜æƒé™ã€‚'; diff --git a/lang/zh_TW.php b/lang/zh_TW.php index 185bc97f2..52bf81cd1 100644 --- a/lang/zh_TW.php +++ b/lang/zh_TW.php @@ -4,11 +4,7 @@ i18n::include_locale_file('sapphire', 'en_US'); global $lang; -if(array_key_exists('zh_TW', $lang) && is_array($lang['zh_TW'])) { - $lang['zh_TW'] = array_merge($lang['en_US'], $lang['zh_TW']); -} else { - $lang['zh_TW'] = $lang['en_US']; -} +$lang['zh_TW'] = $lang['en_US']; $lang['zh_TW']['BasicAuth']['ENTERINFO'] = '請輸入帳號密碼。'; $lang['zh_TW']['BasicAuth']['ERRORNOTADMIN'] = '那個使用者ä¸æ˜¯ç®¡ç†å“¡ã€‚'; diff --git a/main.php b/main.php index a7eeaafc8..a0ba8615e 100644 --- a/main.php +++ b/main.php @@ -2,50 +2,9 @@ /** * Main file that handles every page request. - * - * The main.php does a number of set-up activities for the request. - * - * - Includes the first one of the following files that it finds: (root)/_ss_environment.php, (root)/../_ss_environment.php, or (root)/../../_ss_environment.php - * - Gets an up-to-date manifest from {@link ManifestBuilder} - * - Sets up error handlers with {@link Debug::loadErrorHandlers()} - * - Calls {@link DB::connect()}, passing it the global variable $databaseConfig that should be defined in an _config.php - * - Sets up the default director rules using {@link Director::addRules()} - * - * After that, it calls {@link Director::direct()}, which is responsible for doing most of the real work. - * - * Finally, main.php will use {@link Profiler} to show a profile if the querystring variable "debug_profile" is set. - * - * CONFIGURING THE WEBSERVER - * - * To use Sapphire, every request that doesn't point directly to a file should be rewritten to sapphire/main.php?url=(url). - * For example, http://www.example.com/about-us/rss would be rewritten to http://www.example.com/sapphire/main.php?url=about-us/rss - * - * It's important that requests that point directly to a file aren't rewritten; otherwise, visitors won't be able to download - * any CSS, JS, image files, or other downloads. - * - * On Apache, RewriteEngine can be used to do this. - * - * @package sapphire - * @subpackage core - * @see Director::direct() */ -/** - * Include _ss_environment.php file - */ -$envFiles = array('../_ss_environment.php', '../../_ss_environment.php', '../../../_ss_environment.php'); -foreach($envFiles as $envFile) { - if(@file_exists($envFile)) { - include($envFile); - break; - } -} - -/** - * Include Sapphire's core code - */ require_once("core/Core.php"); - header("Content-type: text/html; charset=\"utf-8\""); if(function_exists('mb_http_output')) { mb_http_output('UTF-8'); @@ -61,27 +20,6 @@ if(isset($_REQUEST['trace'])) { apd_set_pprof_trace(); } -// Ensure we have enough memory -$memString = ini_get("memory_limit"); -switch(strtolower(substr($memString,-1))) { - case "k": - $memory = round(substr($memString,0,-1)*1024); - break; - case "m": - $memory = round(substr($memString,0,-1)*1024*1024); - break; - case "g": - $memory = round(substr($memString,0,-1)*1024*1024*1024); - break; - default: - $memory = round($memString); -} -// Check we have at least 32M -if($memory < (32 * 1024 * 1024)) { - // Increase memory limit - ini_set('memory_limit', '32M'); -} - require_once("core/ManifestBuilder.php"); require_once("core/ClassInfo.php"); @@ -97,6 +35,14 @@ if(Director::isDev()) { Session::start(); +$envFiles = array('../_ss_environment.php', '../../_ss_environment.php', '../../../_ss_environment.php'); +foreach($envFiles as $envFile) { + if(@file_exists($envFile)) { + include($envFile); + break; + } +} + if(isset($_GET['url'])) { $url = $_GET['url']; @@ -141,6 +87,7 @@ Debug::loadErrorHandlers(); require_once("core/model/DB.php"); if(isset($_GET['debug_profile'])) Profiler::mark('DB::connect'); +Debug::show($databaseConfig); DB::connect($databaseConfig); if(isset($_GET['debug_profile'])) Profiler::unmark('DB::connect'); diff --git a/main.php5 b/main.php5 index ba13e4946..028277385 100644 --- a/main.php5 +++ b/main.php5 @@ -1,10 +1,3 @@ \ No newline at end of file diff --git a/misc/Browscap.php b/misc/Browscap.php index f07279b32..e41a4a1e0 100644 --- a/misc/Browscap.php +++ b/misc/Browscap.php @@ -1,10 +1,5 @@ * @copyright Copyright (c) 2006 Jonathan Stoppani * @version 0.7 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License * @link http://garetjax.info/projects/browscap/ - * @package sapphire - * @subpackage misc */ class Browscap { @@ -95,7 +89,7 @@ class Browscap * $updateMethod: The method to use to update the file, has to be a value of * an UPDATE_* constant, null or false. */ - public $remoteIniUrl = 'http://browsers.garykeith.com/stream.asp?Lite_BrowsCapINI'; + public $remoteIniUrl = 'http://browsers.garykeith.com/stream.asp?BrowsCapINI'; public $remoteVerUrl = 'http://browsers.garykeith.com/version-date.asp'; public $timeout = 5; public $updateInterval = 432000; // 5 days @@ -273,7 +267,7 @@ class Browscap $browser = $value = $browser + $this->_browsers[$key]; - while (array_key_exists(3, $value) && $value[3] != null && $value[3] != '') { + while (array_key_exists(3, $value)) { $value = $this->_browsers[$value[3]]; $browser += $value; } @@ -662,12 +656,11 @@ class Browscap /** * Browscap.ini parsing class exception * + * @package Browscap * @author Jonathan Stoppani * @copyright Copyright (c) 2006 Jonathan Stoppani * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License * @link http://garetjax.info/projects/browscap/ - * @package sapphire - * @subpackage misc */ class Browscap_Exception extends Exception {} diff --git a/misc/GoogleSitemap.php b/misc/GoogleSitemap.php index 4083970b6..80213d470 100755 --- a/misc/GoogleSitemap.php +++ b/misc/GoogleSitemap.php @@ -1,17 +1,10 @@ -

      {$trendstrl}

      +

      Trends

      -
      {$legendtrl}
      +
      Legend