commit 369954c713a1b7b0eeac571b4a7cf7e8bcfa1335 Author: Andrew Davidson Date: Thu Dec 11 22:04:34 2014 -0500 initial commit diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..eb650fd --- /dev/null +++ b/.htaccess @@ -0,0 +1,8 @@ +Options +FollowSymLinks +RewriteEngine On + +RewriteBase / + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^(.*)$ index.php?/$1 [L] \ No newline at end of file diff --git a/.svn/all-wcprops b/.svn/all-wcprops new file mode 100644 index 0000000..71d38f0 --- /dev/null +++ b/.svn/all-wcprops @@ -0,0 +1,29 @@ +K 25 +svn:wc:ra_dav:version-url +V 23 +/svn/!svn/ver/124/trunk +END +license.txt +K 25 +svn:wc:ra_dav:version-url +V 35 +/svn/!svn/ver/124/trunk/license.txt +END +.htaccess +K 25 +svn:wc:ra_dav:version-url +V 33 +/svn/!svn/ver/117/trunk/.htaccess +END +index.php +K 25 +svn:wc:ra_dav:version-url +V 32 +/svn/!svn/ver/70/trunk/index.php +END +favicon.ico +K 25 +svn:wc:ra_dav:version-url +V 34 +/svn/!svn/ver/22/trunk/favicon.ico +END diff --git a/.svn/entries b/.svn/entries new file mode 100644 index 0000000..b5b2f00 --- /dev/null +++ b/.svn/entries @@ -0,0 +1,170 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +license.txt +file + + + + +2009-09-15T00:18:34.000000Z +3a2341294d3e46142c79542e316da02b +2008-12-22T02:10:08.113778Z +124 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5326 + +system +dir + +.htaccess +file + + + + +2009-09-15T00:18:34.000000Z +781fdf0fd635748fda3268f24548b328 +2008-10-05T07:25:02.976982Z +117 +yongfook + + + + + + + + + + + + + + + + + + + + + +165 + +index.php +file + + + + +2009-09-15T00:18:34.000000Z +d2f2d19a28f9a5145744217210550a51 +2008-09-01T02:27:50.235233Z +70 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3267 + +public +dir + +favicon.ico +file + + + + +2009-09-15T00:18:34.000000Z +a5f1a691bab04269a95d74e45d8d3ff0 +2008-08-28T08:25:40.070317Z +22 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1150 + diff --git a/.svn/prop-base/favicon.ico.svn-base b/.svn/prop-base/favicon.ico.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/.svn/prop-base/favicon.ico.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/.svn/prop-base/index.php.svn-base b/.svn/prop-base/index.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/.svn/prop-base/index.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/.svn/prop-base/license.txt.svn-base b/.svn/prop-base/license.txt.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/.svn/prop-base/license.txt.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/.svn/text-base/.htaccess.svn-base b/.svn/text-base/.htaccess.svn-base new file mode 100644 index 0000000..eb650fd --- /dev/null +++ b/.svn/text-base/.htaccess.svn-base @@ -0,0 +1,8 @@ +Options +FollowSymLinks +RewriteEngine On + +RewriteBase / + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^(.*)$ index.php?/$1 [L] \ No newline at end of file diff --git a/.svn/text-base/favicon.ico.svn-base b/.svn/text-base/favicon.ico.svn-base new file mode 100644 index 0000000..19d0f4e Binary files /dev/null and b/.svn/text-base/favicon.ico.svn-base differ diff --git a/.svn/text-base/index.php.svn-base b/.svn/text-base/index.php.svn-base new file mode 100644 index 0000000..34dad29 --- /dev/null +++ b/.svn/text-base/index.php.svn-base @@ -0,0 +1,116 @@ + \ No newline at end of file diff --git a/.svn/text-base/license.txt.svn-base b/.svn/text-base/license.txt.svn-base new file mode 100644 index 0000000..b665f81 --- /dev/null +++ b/.svn/text-base/license.txt.svn-base @@ -0,0 +1,118 @@ +Sweetcron +The Free & Open Source Automated Lifestream Software +http://www.sweetcron.com + +Developed by Yongfook +http://www.yongfook.com + +Written in CodeIgniter +http://www.codeigniter.com + +Sweetcron is Copyright (c) 2008, Egg & Co. +All rights reserved. + +This license is a legal agreement between you and Edible Inc. for the use +of Sweetcron Software (the "Software"). By obtaining the Software you +agree to comply with the terms and conditions of this license. + +PERMITTED USE +You are permitted to use, copy, modify, and distribute the Software and its +documentation, with or without modification, for any purpose, provided that +the following conditions are met: + +1. A copy of this license agreement must be included with the distribution. + +2. Redistributions of source code must retain the above copyright notice in + all source code files. + +3. Redistributions in binary form must reproduce the above copyright notice + in the documentation and/or other materials provided with the distribution. + +4. Any files that have been modified must carry notices stating the nature + of the change and the names of those who changed them. + +5. Products derived from the Software must include an acknowledgment that + they are derived from Sweetcron in their documentation and/or other + materials provided with the distribution. + +6. Products derived from the Software may not be called "Sweetcron", + nor may "Sweetcron" appear in their name, without prior written + permission from Egg & Co. + +INDEMNITY +You agree to indemnify and hold harmless the authors of the Software and +any contributors for any direct, indirect, incidental, or consequential +third-party claims, actions or suits, as well as any related expenses, +liabilities, damages, settlements or fees arising from your use or misuse +of the Software, or a violation of any terms of this license. + +DISCLAIMER OF WARRANTY +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF QUALITY, PERFORMANCE, +NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. + +LIMITATIONS OF LIABILITY +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE LIABLE +FOR CLAIMS, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE. LICENSE HOLDERS ARE SOLELY RESPONSIBLE FOR DETERMINING THE +APPROPRIATENESS OF USE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE, INCLUDING +BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF +DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. + +----------------------------------------------------------------------------------------------------------------------- + +###Original CodeIgniter License Below### + +Copyright (c) 2006, EllisLab, Inc. +All rights reserved. + +This license is a legal agreement between you and EllisLab Inc. for the use +of CodeIgniter Software (the "Software"). By obtaining the Software you +agree to comply with the terms and conditions of this license. + +PERMITTED USE +You are permitted to use, copy, modify, and distribute the Software and its +documentation, with or without modification, for any purpose, provided that +the following conditions are met: + +1. A copy of this license agreement must be included with the distribution. + +2. Redistributions of source code must retain the above copyright notice in + all source code files. + +3. Redistributions in binary form must reproduce the above copyright notice + in the documentation and/or other materials provided with the distribution. + +4. Any files that have been modified must carry notices stating the nature + of the change and the names of those who changed them. + +5. Products derived from the Software must include an acknowledgment that + they are derived from CodeIgniter in their documentation and/or other + materials provided with the distribution. + +6. Products derived from the Software may not be called "CodeIgniter", + nor may "CodeIgniter" appear in their name, without prior written + permission from EllisLab, Inc. + + +INDEMNITY +You agree to indemnify and hold harmless the authors of the Software and +any contributors for any direct, indirect, incidental, or consequential +third-party claims, actions or suits, as well as any related expenses, +liabilities, damages, settlements or fees arising from your use or misuse +of the Software, or a violation of any terms of this license. + +DISCLAIMER OF WARRANTY +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF QUALITY, PERFORMANCE, +NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. + +LIMITATIONS OF LIABILITY +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE LIABLE +FOR CLAIMS, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE. LICENSE HOLDERS ARE SOLELY RESPONSIBLE FOR DETERMINING THE +APPROPRIATENESS OF USE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE, INCLUDING +BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF +DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..19d0f4e Binary files /dev/null and b/favicon.ico differ diff --git a/index.php b/index.php new file mode 100755 index 0000000..34dad29 --- /dev/null +++ b/index.php @@ -0,0 +1,116 @@ + \ No newline at end of file diff --git a/license.txt b/license.txt new file mode 100755 index 0000000..b665f81 --- /dev/null +++ b/license.txt @@ -0,0 +1,118 @@ +Sweetcron +The Free & Open Source Automated Lifestream Software +http://www.sweetcron.com + +Developed by Yongfook +http://www.yongfook.com + +Written in CodeIgniter +http://www.codeigniter.com + +Sweetcron is Copyright (c) 2008, Egg & Co. +All rights reserved. + +This license is a legal agreement between you and Edible Inc. for the use +of Sweetcron Software (the "Software"). By obtaining the Software you +agree to comply with the terms and conditions of this license. + +PERMITTED USE +You are permitted to use, copy, modify, and distribute the Software and its +documentation, with or without modification, for any purpose, provided that +the following conditions are met: + +1. A copy of this license agreement must be included with the distribution. + +2. Redistributions of source code must retain the above copyright notice in + all source code files. + +3. Redistributions in binary form must reproduce the above copyright notice + in the documentation and/or other materials provided with the distribution. + +4. Any files that have been modified must carry notices stating the nature + of the change and the names of those who changed them. + +5. Products derived from the Software must include an acknowledgment that + they are derived from Sweetcron in their documentation and/or other + materials provided with the distribution. + +6. Products derived from the Software may not be called "Sweetcron", + nor may "Sweetcron" appear in their name, without prior written + permission from Egg & Co. + +INDEMNITY +You agree to indemnify and hold harmless the authors of the Software and +any contributors for any direct, indirect, incidental, or consequential +third-party claims, actions or suits, as well as any related expenses, +liabilities, damages, settlements or fees arising from your use or misuse +of the Software, or a violation of any terms of this license. + +DISCLAIMER OF WARRANTY +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF QUALITY, PERFORMANCE, +NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. + +LIMITATIONS OF LIABILITY +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE LIABLE +FOR CLAIMS, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE. LICENSE HOLDERS ARE SOLELY RESPONSIBLE FOR DETERMINING THE +APPROPRIATENESS OF USE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE, INCLUDING +BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF +DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. + +----------------------------------------------------------------------------------------------------------------------- + +###Original CodeIgniter License Below### + +Copyright (c) 2006, EllisLab, Inc. +All rights reserved. + +This license is a legal agreement between you and EllisLab Inc. for the use +of CodeIgniter Software (the "Software"). By obtaining the Software you +agree to comply with the terms and conditions of this license. + +PERMITTED USE +You are permitted to use, copy, modify, and distribute the Software and its +documentation, with or without modification, for any purpose, provided that +the following conditions are met: + +1. A copy of this license agreement must be included with the distribution. + +2. Redistributions of source code must retain the above copyright notice in + all source code files. + +3. Redistributions in binary form must reproduce the above copyright notice + in the documentation and/or other materials provided with the distribution. + +4. Any files that have been modified must carry notices stating the nature + of the change and the names of those who changed them. + +5. Products derived from the Software must include an acknowledgment that + they are derived from CodeIgniter in their documentation and/or other + materials provided with the distribution. + +6. Products derived from the Software may not be called "CodeIgniter", + nor may "CodeIgniter" appear in their name, without prior written + permission from EllisLab, Inc. + + +INDEMNITY +You agree to indemnify and hold harmless the authors of the Software and +any contributors for any direct, indirect, incidental, or consequential +third-party claims, actions or suits, as well as any related expenses, +liabilities, damages, settlements or fees arising from your use or misuse +of the Software, or a violation of any terms of this license. + +DISCLAIMER OF WARRANTY +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF QUALITY, PERFORMANCE, +NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. + +LIMITATIONS OF LIABILITY +YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE LIABLE +FOR CLAIMS, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE. LICENSE HOLDERS ARE SOLELY RESPONSIBLE FOR DETERMINING THE +APPROPRIATENESS OF USE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE, INCLUDING +BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF +DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. diff --git a/public/.svn/all-wcprops b/public/.svn/all-wcprops new file mode 100644 index 0000000..73d2468 --- /dev/null +++ b/public/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 29 +/svn/!svn/ver/65/trunk/public +END diff --git a/public/.svn/entries b/public/.svn/entries new file mode 100644 index 0000000..4d2dfd7 --- /dev/null +++ b/public/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:12:40.450252Z +65 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +images +dir + +scripts +dir + +css +dir + diff --git a/public/css/.svn/all-wcprops b/public/css/.svn/all-wcprops new file mode 100644 index 0000000..46177ba --- /dev/null +++ b/public/css/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 33 +/svn/!svn/ver/64/trunk/public/css +END +admin.css +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/!svn/ver/64/trunk/public/css/admin.css +END +reset.css +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/!svn/ver/22/trunk/public/css/reset.css +END diff --git a/public/css/.svn/entries b/public/css/.svn/entries new file mode 100644 index 0000000..3126357 --- /dev/null +++ b/public/css/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/css +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:02:40.078308Z +64 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +admin.css +file + + + + +2009-09-15T00:18:34.000000Z +b0b92c73f4adbed3cd6083f9a0a06b38 +2008-08-31T15:02:40.078308Z +64 +yongfook + + + + + + + + + + + + + + + + + + + + + +10673 + +reset.css +file + + + + +2009-09-15T00:18:34.000000Z +e28325e63ae9afb38f8795e17cf29365 +2008-08-28T08:25:40.070317Z +22 +yongfook + + + + + + + + + + + + + + + + + + + + + +543 + diff --git a/public/css/.svn/text-base/admin.css.svn-base b/public/css/.svn/text-base/admin.css.svn-base new file mode 100644 index 0000000..0fbe4f7 --- /dev/null +++ b/public/css/.svn/text-base/admin.css.svn-base @@ -0,0 +1,598 @@ +/* SWEETCRON ADMIN CSS + + Table of Contents: + Reset + Typography + Positioning + Buttons + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +@import "reset.css"; + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Helvetica, Arial, sans serif; + font-size: 12px; + color: black; + line-height: 1.5em; +} + +p.permalink, p.item_count, p#button_explain, span.input_explain { + font-size: 10px; +} + +p.icon, ul.tags, ul.item_tools, p.tip, ul.feed_tools { + font-size: 11px; +} + +table.generic_table { + font-size: 12px; +} + +ul#nav, p.title, p#pagination { + font-size: 15px; +} + +input.text_input, form.item_search input, textarea.text_input { + font-size: 14px; +} + +span.under_input, span.added, ul.admin_list ul li, p.feed_action, p.icon, ul.item_tools a, ul#nav a, ul#sub_nav a, div#user_info p, p.permalink a, p.item_count, p#button_explain, p.tip, ul.feed_tools a, span.input_explain, div.content blockquote, a.show_all_tags { + color: #999; +} + +div.content, ul.item_tools a:hover { + color: #333; +} + +a, li.expand a { + color: #3399ff; +} + +a:hover, li.expand a:hover { + color: #003366; +} + +div.error { + color: #CC0000; +} + +div.success { + color: green; +} + +span.option label { + color: #486d9b; +} + +ul#nav li.current_item a, ul#nav a:hover, p.tip strong, ul#sub_nav li.current_item a, ul#sub_nav a:hover, span.input_explain strong { + color: black; +} + +label.title, div#footer, div#footer a, ul.feed_tools a:hover, li.item_delete a:hover { + color: white; +} + +div.content strong, ul#nav, div.error, div.success, label.title, p.feed_title, p.title, li.title, p#pagination, p.tip strong, li.expand a, p#breadcrumb a, ul#sub_nav, span.input_explain strong { + font-weight: bold; +} + +div.content em { + font-style: italic; +} + +ul#nav a, p.permalink a, ul#sub_nav a { + text-decoration: none; +} + +div#user_info { + line-height: 1.4em; +} + +p.title { + line-height: 1.6em; +} + +p.icon { + line-height: 16px; +} + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body, html { + height: 100%; +} + +body { + background: white; + border: 5px solid #0458a3; + border-style: solid none none none; +} + +div#footer { + padding: 10px; + background: #0458a3; +} + +div#header { + padding: 20px; +} + +p#logo a { + display: block; + width: 254px; + height: 42px; + background: transparent url(../images/system/logo.gif); +} + +div#user_info { + position: absolute; + top: 36px; + left: 285px; +} + +div#nav_container, div#sub_nav_container { + position: relative; + border: 1px solid #CCC; + border-style: none none solid none; + margin: 35px 0 0 0; +} + +div#nav_container.login { + margin: 5px 0 0 0; +} + +div#sub_nav_container { + margin: 30px 0 20px 0; +} + +ul#nav, ul#sub_nav { + float: left; + width: 100%; + position: absolute; + bottom: -1px; +} + +ul#sub_nav { + border: 1px solid #CCC; + border-style: none none none solid; +} + +ul#nav li, ul#nav li a, ul#sub_nav li, ul#sub_nav li a { + float: left; +} + +ul#nav li a, ul#sub_nav li a { + background: #EEE; + padding: 7px 15px; + border: 1px solid #CCC; + border-style: solid solid solid none; +} + +ul#sub_nav li a { + padding: 5px 10px; +} + +ul#nav li#nav_dashboard { + margin-left: 20px; +} + +ul#nav li#nav_dashboard a { + border: 1px solid #CCC; +} + +ul#nav li.current_item a, ul#nav li#nav_dashboard.current_item a, ul#sub_nav li.current_item a { + background: white; + border-color: #CCC #CCC white #CCC; +} + +div#breadcrumb_container { + background: #006699; + position: relative; + border: 1px solid #CCC; + border-style: none none solid none; +} + +div#main_content { + padding: 20px 20px 0 20px; + width: 588px; + position: relative; + float: left; +} + +div#side_content { + width: 200px; + float: left; + padding: 20px; + border: 1px solid #CCC; + border-style: none none none dashed; +} + +p#button_explain { + clear: both; + padding: 5px 0 0 0; +} + +div#main_content p, div.error, div.success, table.generic_table { + margin-bottom: 20px; +} + +div#main_content div.error p, div#main_content table.generic_table p { + margin: 0; +} + +div.error, div.success { + background: #FFCCCC; + padding: 8px; +} + +div.success { + background: #ccffcc; +} + +label.title { + background: #999; + padding: 2px 5px; +} + +input.text_input, form.item_search input, textarea.text_input { + border: 1px solid #999; + background: #fefee2; + width: 570px; + display: block; + padding: 5px; +} + +textarea.text_input { + height: 300px; +} + +form.item_search input { + width: 187px; +} + +table.generic_table { + width: 100%; + clear: both; +} + +table.generic_table td { + border: 1px solid #EEE; + padding: 8px; +} + +form.generic { + padding-bottom: 20px; + float: left; +} + +p.icon { + background-repeat: no-repeat; + background-position: 5px center; + background-color: #F9F9F9; + height: 16px; + padding: 5px 0 5px 25px; + border: 1px solid #EEE; + border-style: none none solid none; +} + +div#main_content ul.activity_list p, div#main_content ul.feed_list p { + margin: 0; +} + +div#main_content ul.activity_list p.permalink { + margin-bottom: 3px; +} + +div.image img { + display: block; + border: 1px solid #CCC; + padding: 5px; +} + +div.image { + margin: 5px 0; +} + +ul.activity_list li.item { + margin-bottom: 20px; + border: 1px solid #999; + position: relative; +} + +ul.item_tools, ul.feed_tools { + position: absolute; + right: 10px; + top: 4px; +} + +ul.item_tools li, ul.feed_tools li { + display: inline; + padding: 0 0 0 5px; +} + +ul.item_tools li.expand { + background: transparent url(../images/system/icons/silk/bullet_arrow_right.png) 0 center no-repeat; + padding-left: 15px; +} + +ul.item_tools li.expand.expanded { + background: transparent url(../images/system/icons/silk/bullet_arrow_down.png) 0 center no-repeat; +} + +div.item_container { + padding: 8px 12px 10px 12px; +} + +div#main_content ul.activity_list div.content p, div.content ul, div.content ol { + margin-bottom: 10px; +} + +div.content ul, div.content ol { + margin-left: 20px; + list-style-type: disc; +} + +div.content ol { + list-style-type: decimal +} + +div.content blockquote { + margin-left: 20px; + border: 3px solid #CCC; + border-style: none none none solid; + padding-left: 10px; +} + +ul.tags li { + display: inline; + padding: 0 5px 0 0; +} + +div.hideshow, ul.item_tools li.expand { + display: none; +} + +ul.activity_list li.publish li.publish_this, ul.activity_list li.draft li.unpublish_this { + display: none; +} + +ul.activity_list li.draft li.publish_this, ul.activity_list li.publish li.unpublish_this { + display: inline; +} + +ul.activity_list li div.item_container { + position: relative; +} + +ul.activity_list li.draft { + opacity: 0.4; + -moz-opacity: 0.4; + filter: alpha(opacity=40); +} + +ul.feed_list p.title { + background-repeat: no-repeat; + background-position: left center; +} + +ul.feed_list p { + padding: 0 0 0 22px; +} + +ul.feed_list { + border: 1px solid #EEE; + border-style: solid none none none; + margin-bottom: 20px; +} + +ul.feed_list li.feed { + border: 1px solid #EEE; + border-style: none solid solid solid; + padding: 10px; + background: transparent url(../images/system/dither.gif) bottom left repeat-x; + position: relative; +} + +li.feed_delete a, li.item_delete a { + padding: 1px 2px; +} + +li.feed_delete a:hover, li.item_delete a:hover { + background: red; +} + +div.clear { + clear: both; +} + +p#pagination { + padding: 15px 10px; + background: #F8F8F8; +} + +p#pagination a { + background: white; + padding: 5px 8px; + border: 1px solid #EEE; +} + +p#pagination a:hover { + border: 1px solid #CCC; +} + +h4.side_title { + margin: 15px 0 8px 0; + border: 1px solid #EEE; + border-style: none none solid none; + padding: 0 0 3px 0; +} + +ul.tag_list li { + display: inline; + padding: 0 0 5px 0; +} + +span.highlight { + background: #FFFFCC; +} + +span.option_container { + border: 1px solid #999; + padding: 8px 10px 3px 10px; + display: block; +} + +span.option { + display: block; + margin-bottom: 5px; +} + +span.option label { + background: #f1f5fa; + padding: 1px 2px; + cursor: pointer; +} + +span.input_explain { + display: block; + margin-top: -15px; + margin-bottom: 15px; +} + +a.reset_cron_key { + position: absolute; + right: 25px; +} + +ul.tag_list.all { + display: none; +} + +ul.active_feeds li { + padding-left: 22px; + margin-bottom: 5px; +} + +a.change_password { + background: transparent url(../images/system/icons/silk/bullet_arrow_right.png) 0 center no-repeat; + padding-left: 15px; +} + +a.change_password.toggle { + background: transparent url(../images/system/icons/silk/bullet_arrow_down.png) 0 center no-repeat; +} + +div#change_password_container { + display: none; +} + +/* Buttons +---------------------------------------------------------------------------------------- */ + +.buttons a, .buttons button{ + display:block; + float:left; + margin:0 7px 0 0; + background-color:#f5f5f5; + border:1px solid #dedede; + border-top:1px solid #eee; + border-left:1px solid #eee; + font-size:100%; + line-height:130%; + text-decoration:none; + font-weight:bold; + color:#565656; + cursor:pointer; + padding:5px 10px 6px 7px; /* Links */ +} + +.buttons button{ + width:auto; + overflow:visible; + padding:4px 10px 3px 7px; /* IE6 */ +} + +.buttons button[type]{ + padding:5px 10px 5px 7px; /* Firefox */ + line-height:17px; /* Safari */ +} + +*:first-child+html button[type]{ + padding:4px 10px 3px 7px; /* IE7 */ +} + +.buttons button img, .buttons a img{ + margin:0 3px -3px 0 !important; + padding:0; + border:none; + width:16px; + height:16px; +} + +/* STANDARD */ + +button:hover, .buttons a:hover{ + background-color:#dff4ff; + border:1px solid #c2e1ef; + color:#336699; +} +.buttons a:active{ + background-color:#6299c5; + border:1px solid #6299c5; + color:#fff; +} + +/* POSITIVE */ + +button.positive, .buttons a.positive{ + color:#529214; +} +.buttons a.positive:hover, button.positive:hover{ + background-color:#E6EFC2; + border:1px solid #C6D880; + color:#529214; +} +.buttons a.positive:active{ + background-color:#529214; + border:1px solid #529214; + color:#fff; +} + +/* NEGATIVE */ + +.buttons a.negative, button.negative{ + color:#d12f19; +} +.buttons a.negative:hover, button.negative:hover{ + background:#fbe3e4; + border:1px solid #fbc2c4; + color:#d12f19; +} +.buttons a.negative:active{ + background-color:#d12f19; + border:1px solid #d12f19; + color:#fff; +} + +/* Teh IE haxx +---------------------------------------------------------------------------------------- */ + +* html div#nav_container { + height: 38px; +} \ No newline at end of file diff --git a/public/css/.svn/text-base/reset.css.svn-base b/public/css/.svn/text-base/reset.css.svn-base new file mode 100644 index 0000000..aadfe54 --- /dev/null +++ b/public/css/.svn/text-base/reset.css.svn-base @@ -0,0 +1,14 @@ +/* +Copyright (c) 2006, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 0.10.0 +*/ +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;} +table{border-collapse:collapse;border-spacing:0;} +fieldset,img{border:0;} +address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;} +ol,ul {list-style:none;} +caption,th {text-align:left;} +h1,h2,h3,h4,h5,h6{font-size:100%;} +q:before,q:after{content:'';} \ No newline at end of file diff --git a/public/css/admin.css b/public/css/admin.css new file mode 100644 index 0000000..0fbe4f7 --- /dev/null +++ b/public/css/admin.css @@ -0,0 +1,598 @@ +/* SWEETCRON ADMIN CSS + + Table of Contents: + Reset + Typography + Positioning + Buttons + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +@import "reset.css"; + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Helvetica, Arial, sans serif; + font-size: 12px; + color: black; + line-height: 1.5em; +} + +p.permalink, p.item_count, p#button_explain, span.input_explain { + font-size: 10px; +} + +p.icon, ul.tags, ul.item_tools, p.tip, ul.feed_tools { + font-size: 11px; +} + +table.generic_table { + font-size: 12px; +} + +ul#nav, p.title, p#pagination { + font-size: 15px; +} + +input.text_input, form.item_search input, textarea.text_input { + font-size: 14px; +} + +span.under_input, span.added, ul.admin_list ul li, p.feed_action, p.icon, ul.item_tools a, ul#nav a, ul#sub_nav a, div#user_info p, p.permalink a, p.item_count, p#button_explain, p.tip, ul.feed_tools a, span.input_explain, div.content blockquote, a.show_all_tags { + color: #999; +} + +div.content, ul.item_tools a:hover { + color: #333; +} + +a, li.expand a { + color: #3399ff; +} + +a:hover, li.expand a:hover { + color: #003366; +} + +div.error { + color: #CC0000; +} + +div.success { + color: green; +} + +span.option label { + color: #486d9b; +} + +ul#nav li.current_item a, ul#nav a:hover, p.tip strong, ul#sub_nav li.current_item a, ul#sub_nav a:hover, span.input_explain strong { + color: black; +} + +label.title, div#footer, div#footer a, ul.feed_tools a:hover, li.item_delete a:hover { + color: white; +} + +div.content strong, ul#nav, div.error, div.success, label.title, p.feed_title, p.title, li.title, p#pagination, p.tip strong, li.expand a, p#breadcrumb a, ul#sub_nav, span.input_explain strong { + font-weight: bold; +} + +div.content em { + font-style: italic; +} + +ul#nav a, p.permalink a, ul#sub_nav a { + text-decoration: none; +} + +div#user_info { + line-height: 1.4em; +} + +p.title { + line-height: 1.6em; +} + +p.icon { + line-height: 16px; +} + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body, html { + height: 100%; +} + +body { + background: white; + border: 5px solid #0458a3; + border-style: solid none none none; +} + +div#footer { + padding: 10px; + background: #0458a3; +} + +div#header { + padding: 20px; +} + +p#logo a { + display: block; + width: 254px; + height: 42px; + background: transparent url(../images/system/logo.gif); +} + +div#user_info { + position: absolute; + top: 36px; + left: 285px; +} + +div#nav_container, div#sub_nav_container { + position: relative; + border: 1px solid #CCC; + border-style: none none solid none; + margin: 35px 0 0 0; +} + +div#nav_container.login { + margin: 5px 0 0 0; +} + +div#sub_nav_container { + margin: 30px 0 20px 0; +} + +ul#nav, ul#sub_nav { + float: left; + width: 100%; + position: absolute; + bottom: -1px; +} + +ul#sub_nav { + border: 1px solid #CCC; + border-style: none none none solid; +} + +ul#nav li, ul#nav li a, ul#sub_nav li, ul#sub_nav li a { + float: left; +} + +ul#nav li a, ul#sub_nav li a { + background: #EEE; + padding: 7px 15px; + border: 1px solid #CCC; + border-style: solid solid solid none; +} + +ul#sub_nav li a { + padding: 5px 10px; +} + +ul#nav li#nav_dashboard { + margin-left: 20px; +} + +ul#nav li#nav_dashboard a { + border: 1px solid #CCC; +} + +ul#nav li.current_item a, ul#nav li#nav_dashboard.current_item a, ul#sub_nav li.current_item a { + background: white; + border-color: #CCC #CCC white #CCC; +} + +div#breadcrumb_container { + background: #006699; + position: relative; + border: 1px solid #CCC; + border-style: none none solid none; +} + +div#main_content { + padding: 20px 20px 0 20px; + width: 588px; + position: relative; + float: left; +} + +div#side_content { + width: 200px; + float: left; + padding: 20px; + border: 1px solid #CCC; + border-style: none none none dashed; +} + +p#button_explain { + clear: both; + padding: 5px 0 0 0; +} + +div#main_content p, div.error, div.success, table.generic_table { + margin-bottom: 20px; +} + +div#main_content div.error p, div#main_content table.generic_table p { + margin: 0; +} + +div.error, div.success { + background: #FFCCCC; + padding: 8px; +} + +div.success { + background: #ccffcc; +} + +label.title { + background: #999; + padding: 2px 5px; +} + +input.text_input, form.item_search input, textarea.text_input { + border: 1px solid #999; + background: #fefee2; + width: 570px; + display: block; + padding: 5px; +} + +textarea.text_input { + height: 300px; +} + +form.item_search input { + width: 187px; +} + +table.generic_table { + width: 100%; + clear: both; +} + +table.generic_table td { + border: 1px solid #EEE; + padding: 8px; +} + +form.generic { + padding-bottom: 20px; + float: left; +} + +p.icon { + background-repeat: no-repeat; + background-position: 5px center; + background-color: #F9F9F9; + height: 16px; + padding: 5px 0 5px 25px; + border: 1px solid #EEE; + border-style: none none solid none; +} + +div#main_content ul.activity_list p, div#main_content ul.feed_list p { + margin: 0; +} + +div#main_content ul.activity_list p.permalink { + margin-bottom: 3px; +} + +div.image img { + display: block; + border: 1px solid #CCC; + padding: 5px; +} + +div.image { + margin: 5px 0; +} + +ul.activity_list li.item { + margin-bottom: 20px; + border: 1px solid #999; + position: relative; +} + +ul.item_tools, ul.feed_tools { + position: absolute; + right: 10px; + top: 4px; +} + +ul.item_tools li, ul.feed_tools li { + display: inline; + padding: 0 0 0 5px; +} + +ul.item_tools li.expand { + background: transparent url(../images/system/icons/silk/bullet_arrow_right.png) 0 center no-repeat; + padding-left: 15px; +} + +ul.item_tools li.expand.expanded { + background: transparent url(../images/system/icons/silk/bullet_arrow_down.png) 0 center no-repeat; +} + +div.item_container { + padding: 8px 12px 10px 12px; +} + +div#main_content ul.activity_list div.content p, div.content ul, div.content ol { + margin-bottom: 10px; +} + +div.content ul, div.content ol { + margin-left: 20px; + list-style-type: disc; +} + +div.content ol { + list-style-type: decimal +} + +div.content blockquote { + margin-left: 20px; + border: 3px solid #CCC; + border-style: none none none solid; + padding-left: 10px; +} + +ul.tags li { + display: inline; + padding: 0 5px 0 0; +} + +div.hideshow, ul.item_tools li.expand { + display: none; +} + +ul.activity_list li.publish li.publish_this, ul.activity_list li.draft li.unpublish_this { + display: none; +} + +ul.activity_list li.draft li.publish_this, ul.activity_list li.publish li.unpublish_this { + display: inline; +} + +ul.activity_list li div.item_container { + position: relative; +} + +ul.activity_list li.draft { + opacity: 0.4; + -moz-opacity: 0.4; + filter: alpha(opacity=40); +} + +ul.feed_list p.title { + background-repeat: no-repeat; + background-position: left center; +} + +ul.feed_list p { + padding: 0 0 0 22px; +} + +ul.feed_list { + border: 1px solid #EEE; + border-style: solid none none none; + margin-bottom: 20px; +} + +ul.feed_list li.feed { + border: 1px solid #EEE; + border-style: none solid solid solid; + padding: 10px; + background: transparent url(../images/system/dither.gif) bottom left repeat-x; + position: relative; +} + +li.feed_delete a, li.item_delete a { + padding: 1px 2px; +} + +li.feed_delete a:hover, li.item_delete a:hover { + background: red; +} + +div.clear { + clear: both; +} + +p#pagination { + padding: 15px 10px; + background: #F8F8F8; +} + +p#pagination a { + background: white; + padding: 5px 8px; + border: 1px solid #EEE; +} + +p#pagination a:hover { + border: 1px solid #CCC; +} + +h4.side_title { + margin: 15px 0 8px 0; + border: 1px solid #EEE; + border-style: none none solid none; + padding: 0 0 3px 0; +} + +ul.tag_list li { + display: inline; + padding: 0 0 5px 0; +} + +span.highlight { + background: #FFFFCC; +} + +span.option_container { + border: 1px solid #999; + padding: 8px 10px 3px 10px; + display: block; +} + +span.option { + display: block; + margin-bottom: 5px; +} + +span.option label { + background: #f1f5fa; + padding: 1px 2px; + cursor: pointer; +} + +span.input_explain { + display: block; + margin-top: -15px; + margin-bottom: 15px; +} + +a.reset_cron_key { + position: absolute; + right: 25px; +} + +ul.tag_list.all { + display: none; +} + +ul.active_feeds li { + padding-left: 22px; + margin-bottom: 5px; +} + +a.change_password { + background: transparent url(../images/system/icons/silk/bullet_arrow_right.png) 0 center no-repeat; + padding-left: 15px; +} + +a.change_password.toggle { + background: transparent url(../images/system/icons/silk/bullet_arrow_down.png) 0 center no-repeat; +} + +div#change_password_container { + display: none; +} + +/* Buttons +---------------------------------------------------------------------------------------- */ + +.buttons a, .buttons button{ + display:block; + float:left; + margin:0 7px 0 0; + background-color:#f5f5f5; + border:1px solid #dedede; + border-top:1px solid #eee; + border-left:1px solid #eee; + font-size:100%; + line-height:130%; + text-decoration:none; + font-weight:bold; + color:#565656; + cursor:pointer; + padding:5px 10px 6px 7px; /* Links */ +} + +.buttons button{ + width:auto; + overflow:visible; + padding:4px 10px 3px 7px; /* IE6 */ +} + +.buttons button[type]{ + padding:5px 10px 5px 7px; /* Firefox */ + line-height:17px; /* Safari */ +} + +*:first-child+html button[type]{ + padding:4px 10px 3px 7px; /* IE7 */ +} + +.buttons button img, .buttons a img{ + margin:0 3px -3px 0 !important; + padding:0; + border:none; + width:16px; + height:16px; +} + +/* STANDARD */ + +button:hover, .buttons a:hover{ + background-color:#dff4ff; + border:1px solid #c2e1ef; + color:#336699; +} +.buttons a:active{ + background-color:#6299c5; + border:1px solid #6299c5; + color:#fff; +} + +/* POSITIVE */ + +button.positive, .buttons a.positive{ + color:#529214; +} +.buttons a.positive:hover, button.positive:hover{ + background-color:#E6EFC2; + border:1px solid #C6D880; + color:#529214; +} +.buttons a.positive:active{ + background-color:#529214; + border:1px solid #529214; + color:#fff; +} + +/* NEGATIVE */ + +.buttons a.negative, button.negative{ + color:#d12f19; +} +.buttons a.negative:hover, button.negative:hover{ + background:#fbe3e4; + border:1px solid #fbc2c4; + color:#d12f19; +} +.buttons a.negative:active{ + background-color:#d12f19; + border:1px solid #d12f19; + color:#fff; +} + +/* Teh IE haxx +---------------------------------------------------------------------------------------- */ + +* html div#nav_container { + height: 38px; +} \ No newline at end of file diff --git a/public/css/reset.css b/public/css/reset.css new file mode 100644 index 0000000..aadfe54 --- /dev/null +++ b/public/css/reset.css @@ -0,0 +1,14 @@ +/* +Copyright (c) 2006, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 0.10.0 +*/ +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;} +table{border-collapse:collapse;border-spacing:0;} +fieldset,img{border:0;} +address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;} +ol,ul {list-style:none;} +caption,th {text-align:left;} +h1,h2,h3,h4,h5,h6{font-size:100%;} +q:before,q:after{content:'';} \ No newline at end of file diff --git a/public/images/.svn/all-wcprops b/public/images/.svn/all-wcprops new file mode 100644 index 0000000..7500d23 --- /dev/null +++ b/public/images/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 36 +/svn/!svn/ver/65/trunk/public/images +END diff --git a/public/images/.svn/entries b/public/images/.svn/entries new file mode 100644 index 0000000..8f7e135 --- /dev/null +++ b/public/images/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/images +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:12:40.450252Z +65 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +system +dir + diff --git a/public/images/system/.svn/all-wcprops b/public/images/system/.svn/all-wcprops new file mode 100644 index 0000000..ba30fa0 --- /dev/null +++ b/public/images/system/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/!svn/ver/65/trunk/public/images/system +END +dither.gif +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/22/trunk/public/images/system/dither.gif +END +logo.gif +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/22/trunk/public/images/system/logo.gif +END +disable.gif +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/22/trunk/public/images/system/disable.gif +END diff --git a/public/images/system/.svn/entries b/public/images/system/.svn/entries new file mode 100644 index 0000000..f2f679d --- /dev/null +++ b/public/images/system/.svn/entries @@ -0,0 +1,133 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/images/system +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:12:40.450252Z +65 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +dither.gif +file + + + + +2009-09-15T00:18:31.000000Z +00b7ff90a4d931ca43ee3e6f63ecc91f +2008-08-28T08:25:40.070317Z +22 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +119 + +logo.gif +file + + + + +2009-09-15T00:18:31.000000Z +ab628778fed40fd506bd5b86a7f6fda2 +2008-08-28T08:25:40.070317Z +22 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3591 + +disable.gif +file + + + + +2009-09-15T00:18:31.000000Z +4857c0d2e46abc6b09fd43e42f303989 +2008-08-28T08:25:40.070317Z +22 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +44 + +icons +dir + diff --git a/public/images/system/.svn/prop-base/disable.gif.svn-base b/public/images/system/.svn/prop-base/disable.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/public/images/system/.svn/prop-base/disable.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/.svn/prop-base/dither.gif.svn-base b/public/images/system/.svn/prop-base/dither.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/public/images/system/.svn/prop-base/dither.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/.svn/prop-base/logo.gif.svn-base b/public/images/system/.svn/prop-base/logo.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/public/images/system/.svn/prop-base/logo.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/.svn/text-base/disable.gif.svn-base b/public/images/system/.svn/text-base/disable.gif.svn-base new file mode 100644 index 0000000..9f8c673 Binary files /dev/null and b/public/images/system/.svn/text-base/disable.gif.svn-base differ diff --git a/public/images/system/.svn/text-base/dither.gif.svn-base b/public/images/system/.svn/text-base/dither.gif.svn-base new file mode 100644 index 0000000..656cbac Binary files /dev/null and b/public/images/system/.svn/text-base/dither.gif.svn-base differ diff --git a/public/images/system/.svn/text-base/logo.gif.svn-base b/public/images/system/.svn/text-base/logo.gif.svn-base new file mode 100644 index 0000000..422f524 Binary files /dev/null and b/public/images/system/.svn/text-base/logo.gif.svn-base differ diff --git a/public/images/system/disable.gif b/public/images/system/disable.gif new file mode 100644 index 0000000..9f8c673 Binary files /dev/null and b/public/images/system/disable.gif differ diff --git a/public/images/system/dither.gif b/public/images/system/dither.gif new file mode 100644 index 0000000..656cbac Binary files /dev/null and b/public/images/system/dither.gif differ diff --git a/public/images/system/icons/.svn/all-wcprops b/public/images/system/icons/.svn/all-wcprops new file mode 100644 index 0000000..ff6ea20 --- /dev/null +++ b/public/images/system/icons/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/65/trunk/public/images/system/icons +END diff --git a/public/images/system/icons/.svn/entries b/public/images/system/icons/.svn/entries new file mode 100644 index 0000000..2a6ab09 --- /dev/null +++ b/public/images/system/icons/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/images/system/icons +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:12:40.450252Z +65 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +silk +dir + diff --git a/public/images/system/icons/silk/.svn/all-wcprops b/public/images/system/icons/silk/.svn/all-wcprops new file mode 100644 index 0000000..facaeff --- /dev/null +++ b/public/images/system/icons/silk/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/65/trunk/public/images/system/icons/silk +END +page_white.png +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/65/trunk/public/images/system/icons/silk/page_white.png +END +cog_go.png +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/32/trunk/public/images/system/icons/silk/cog_go.png +END +bullet_arrow_right.png +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/!svn/ver/36/trunk/public/images/system/icons/silk/bullet_arrow_right.png +END +accept.png +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/32/trunk/public/images/system/icons/silk/accept.png +END +add.png +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/32/trunk/public/images/system/icons/silk/add.png +END +key.png +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/32/trunk/public/images/system/icons/silk/key.png +END +bullet_arrow_down.png +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/!svn/ver/36/trunk/public/images/system/icons/silk/bullet_arrow_down.png +END diff --git a/public/images/system/icons/silk/.svn/entries b/public/images/system/icons/silk/.svn/entries new file mode 100644 index 0000000..0ae045d --- /dev/null +++ b/public/images/system/icons/silk/.svn/entries @@ -0,0 +1,266 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/images/system/icons/silk +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:12:40.450252Z +65 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +page_white.png +file + + + + +2009-09-15T00:18:31.000000Z +a3112ba7e266938321394347e2a6e107 +2008-08-31T15:12:40.450252Z +65 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +294 + +cog_go.png +file + + + + +2009-09-15T00:18:31.000000Z +142d11b5225a02229478dd1370092db0 +2008-08-28T13:03:46.682478Z +32 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +859 + +bullet_arrow_right.png +file + + + + +2009-09-15T00:18:31.000000Z +d66c161eb603177fc8fedf70c3224581 +2008-08-28T14:39:55.799261Z +36 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +259 + +accept.png +file + + + + +2009-09-15T00:18:31.000000Z +8bfed48756f192ed7afe6eaa4799aae4 +2008-08-28T13:03:46.682478Z +32 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +781 + +add.png +file + + + + +2009-09-15T00:18:31.000000Z +1988c3cc1384a3ac9b9a4129183248f3 +2008-08-28T13:03:46.682478Z +32 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +733 + +key.png +file + + + + +2009-09-15T00:18:31.000000Z +70ecb91f3ae79ec3c40ac74c5468a392 +2008-08-28T13:03:46.682478Z +32 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +612 + +bullet_arrow_down.png +file + + + + +2009-09-15T00:18:31.000000Z +6817b10435d889646ce9b3b22b9c16cb +2008-08-28T14:39:55.799261Z +36 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +201 + diff --git a/public/images/system/icons/silk/.svn/prop-base/accept.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/accept.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/accept.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/add.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/add.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/add.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_down.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_down.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_down.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_right.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_right.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/bullet_arrow_right.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/cog_go.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/cog_go.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/cog_go.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/key.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/key.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/key.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/prop-base/page_white.png.svn-base b/public/images/system/icons/silk/.svn/prop-base/page_white.png.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/public/images/system/icons/silk/.svn/prop-base/page_white.png.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/public/images/system/icons/silk/.svn/text-base/accept.png.svn-base b/public/images/system/icons/silk/.svn/text-base/accept.png.svn-base new file mode 100644 index 0000000..89c8129 Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/accept.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/add.png.svn-base b/public/images/system/icons/silk/.svn/text-base/add.png.svn-base new file mode 100644 index 0000000..6332fef Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/add.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/bullet_arrow_down.png.svn-base b/public/images/system/icons/silk/.svn/text-base/bullet_arrow_down.png.svn-base new file mode 100644 index 0000000..9b23c06 Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/bullet_arrow_down.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/bullet_arrow_right.png.svn-base b/public/images/system/icons/silk/.svn/text-base/bullet_arrow_right.png.svn-base new file mode 100644 index 0000000..97a5115 Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/bullet_arrow_right.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/cog_go.png.svn-base b/public/images/system/icons/silk/.svn/text-base/cog_go.png.svn-base new file mode 100644 index 0000000..3262767 Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/cog_go.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/key.png.svn-base b/public/images/system/icons/silk/.svn/text-base/key.png.svn-base new file mode 100644 index 0000000..4ec1a92 Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/key.png.svn-base differ diff --git a/public/images/system/icons/silk/.svn/text-base/page_white.png.svn-base b/public/images/system/icons/silk/.svn/text-base/page_white.png.svn-base new file mode 100644 index 0000000..8b8b1ca Binary files /dev/null and b/public/images/system/icons/silk/.svn/text-base/page_white.png.svn-base differ diff --git a/public/images/system/icons/silk/accept.png b/public/images/system/icons/silk/accept.png new file mode 100755 index 0000000..89c8129 Binary files /dev/null and b/public/images/system/icons/silk/accept.png differ diff --git a/public/images/system/icons/silk/add.png b/public/images/system/icons/silk/add.png new file mode 100755 index 0000000..6332fef Binary files /dev/null and b/public/images/system/icons/silk/add.png differ diff --git a/public/images/system/icons/silk/bullet_arrow_down.png b/public/images/system/icons/silk/bullet_arrow_down.png new file mode 100755 index 0000000..9b23c06 Binary files /dev/null and b/public/images/system/icons/silk/bullet_arrow_down.png differ diff --git a/public/images/system/icons/silk/bullet_arrow_right.png b/public/images/system/icons/silk/bullet_arrow_right.png new file mode 100644 index 0000000..97a5115 Binary files /dev/null and b/public/images/system/icons/silk/bullet_arrow_right.png differ diff --git a/public/images/system/icons/silk/cog_go.png b/public/images/system/icons/silk/cog_go.png new file mode 100755 index 0000000..3262767 Binary files /dev/null and b/public/images/system/icons/silk/cog_go.png differ diff --git a/public/images/system/icons/silk/key.png b/public/images/system/icons/silk/key.png new file mode 100755 index 0000000..4ec1a92 Binary files /dev/null and b/public/images/system/icons/silk/key.png differ diff --git a/public/images/system/icons/silk/page_white.png b/public/images/system/icons/silk/page_white.png new file mode 100755 index 0000000..8b8b1ca Binary files /dev/null and b/public/images/system/icons/silk/page_white.png differ diff --git a/public/images/system/logo.gif b/public/images/system/logo.gif new file mode 100644 index 0000000..422f524 Binary files /dev/null and b/public/images/system/logo.gif differ diff --git a/public/scripts/.svn/all-wcprops b/public/scripts/.svn/all-wcprops new file mode 100644 index 0000000..cf44c0e --- /dev/null +++ b/public/scripts/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 37 +/svn/!svn/ver/64/trunk/public/scripts +END +main.js +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/!svn/ver/22/trunk/public/scripts/main.js +END +admin.js +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/!svn/ver/64/trunk/public/scripts/admin.js +END +jquery.js +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/22/trunk/public/scripts/jquery.js +END diff --git a/public/scripts/.svn/entries b/public/scripts/.svn/entries new file mode 100644 index 0000000..991e155 --- /dev/null +++ b/public/scripts/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/public/scripts +http://sweetcron.googlecode.com/svn + + + +2008-08-31T15:02:40.078308Z +64 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +main.js +file + + + + +2009-09-15T00:18:34.000000Z +d41d8cd98f00b204e9800998ecf8427e +2008-08-28T08:25:40.070317Z +22 +yongfook + + + + + + + + + + + + + + + + + + + + + +0 + +admin.js +file + + + + +2009-09-15T00:18:34.000000Z +a255440ac63270a2a125ed2893ebf547 +2008-08-31T15:02:40.078308Z +64 +yongfook + + + + + + + + + + + + + + + + + + + + + +3013 + +jquery.js +file + + + + +2009-09-15T00:18:34.000000Z +7447d985396a9b7b507d5841c28dd7f8 +2008-08-28T08:25:40.070317Z +22 +yongfook + + + + + + + + + + + + + + + + + + + + + +31033 + diff --git a/public/scripts/.svn/text-base/admin.js.svn-base b/public/scripts/.svn/text-base/admin.js.svn-base new file mode 100644 index 0000000..ada7903 --- /dev/null +++ b/public/scripts/.svn/text-base/admin.js.svn-base @@ -0,0 +1,113 @@ +$(document).ready(function(){ + + var base_url = $('input[name=base_url]').val(); + + $('a.change_password').click(function(){ + $('div#change_password_container').toggle(); + $('a.change_password').toggleClass('toggle'); + }); + + //show all tags + $('a.show_all_tags').click(function(){ + if ($('ul.tag_list.some').is(':visible')) { + $('ul.tag_list.some').slideUp('normal', function(){ + $('ul.tag_list.all').slideDown('normal'); + $('a.show_all_tags').html('Show Some Tags'); + }); + } else { + $('ul.tag_list.all').slideUp('normal', function(){ + $('ul.tag_list.some').slideDown('normal'); + $('a.show_all_tags').html('Show All Tags'); + }); + } + }); + + //reset cron key + $('a.reset_cron_key').click(function(){ + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/reset_cron_key", + success: function(msg){ + $('span#cron_key').html(msg); + } + }); + }); + + //cron url display + $('form#options_form').change(function(){ + if ($('input#radio_true').is(':checked')) { + $('span#cron_url').show(); + } else { + $('span#cron_url').hide(); + } + }); + + //save draft button + $('a.draft_button').click(function(){ + $('input[name=draft]').val('true'); + $('form').submit(); + }); + + //must confirm link + $('a.confirm_first').click(function(){ + if (confirm('Sure?')) { + return true; + } else { + return false; + } + }); + + //unpublish button + $('ul.activity_list li.unpublish_this a').click(function(){ + var id = $(this).parents('li.item').attr('id').replace('item_',''); + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/unpublish_item", + data: "id=" + id, + success: function(){ + $('li#item_' + id).removeClass('publish'); + $('li#item_' + id).addClass('draft'); + } + }); + }); + + //publish button + $('ul.activity_list li.publish_this a').click(function(){ + var id = $(this).parents('li.item').attr('id').replace('item_',''); + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/publish_item", + data: "id=" + id, + success: function(){ + $('li#item_' + id).removeClass('draft'); + $('li#item_' + id).addClass('publish'); + } + }); + }); + + //external links, xhtml friendly + $('a[rel=external]').click(function(){ + //open new window + var myurl = $(this).attr('href'); + window.open(myurl, 'external'); + return false; + }); + + if ($('li.item div.hideshow:parent').length) { + $('li.item div.hideshow:parent').each(function(){ + $(this).parents('li.item').children('ul.item_tools').children('li.expand').css({display: 'inline'}); + }); + } + + $('li.expand a').click(function(){ + $(this).parents('li.item').children('div.item_container').children('div.hideshow').slideToggle(); + if ($(this).parents('li').hasClass('expanded')) { + $(this).parents('li').removeClass('expanded'); + $(this).html('Expand'); + } else { + $(this).parents('li').addClass('expanded'); + $(this).html('Collapse'); + } + }); + +}); \ No newline at end of file diff --git a/public/scripts/.svn/text-base/jquery.js.svn-base b/public/scripts/.svn/text-base/jquery.js.svn-base new file mode 100644 index 0000000..95dd013 --- /dev/null +++ b/public/scripts/.svn/text-base/jquery.js.svn-base @@ -0,0 +1,11 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ + */ +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(H(){J w=1b.4M,3m$=1b.$;J D=1b.4M=1b.$=H(a,b){I 2B D.17.5j(a,b)};J u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,62=/^.[^:#\\[\\.]*$/,12;D.17=D.44={5j:H(d,b){d=d||S;G(d.16){7[0]=d;7.K=1;I 7}G(1j d=="23"){J c=u.2D(d);G(c&&(c[1]||!b)){G(c[1])d=D.4h([c[1]],b);N{J a=S.61(c[3]);G(a){G(a.2v!=c[3])I D().2q(d);I D(a)}d=[]}}N I D(b).2q(d)}N G(D.1D(d))I D(S)[D.17.27?"27":"43"](d);I 7.6Y(D.2d(d))},5w:"1.2.6",8G:H(){I 7.K},K:0,3p:H(a){I a==12?D.2d(7):7[a]},2I:H(b){J a=D(b);a.5n=7;I a},6Y:H(a){7.K=0;2p.44.1p.1w(7,a);I 7},P:H(a,b){I D.P(7,a,b)},5i:H(b){J a=-1;I D.2L(b&&b.5w?b[0]:b,7)},1K:H(c,a,b){J d=c;G(c.1q==56)G(a===12)I 7[0]&&D[b||"1K"](7[0],c);N{d={};d[c]=a}I 7.P(H(i){R(c 1n d)D.1K(b?7.V:7,c,D.1i(7,d[c],b,i,c))})},1g:H(b,a){G((b==\'2h\'||b==\'1Z\')&&3d(a)<0)a=12;I 7.1K(b,a,"2a")},1r:H(b){G(1j b!="49"&&b!=U)I 7.4E().3v((7[0]&&7[0].2z||S).5F(b));J a="";D.P(b||7,H(){D.P(7.3t,H(){G(7.16!=8)a+=7.16!=1?7.76:D.17.1r([7])})});I a},5z:H(b){G(7[0])D(b,7[0].2z).5y().39(7[0]).2l(H(){J a=7;1B(a.1x)a=a.1x;I a}).3v(7);I 7},8Y:H(a){I 7.P(H(){D(7).6Q().5z(a)})},8R:H(a){I 7.P(H(){D(7).5z(a)})},3v:H(){I 7.3W(19,M,Q,H(a){G(7.16==1)7.3U(a)})},6F:H(){I 7.3W(19,M,M,H(a){G(7.16==1)7.39(a,7.1x)})},6E:H(){I 7.3W(19,Q,Q,H(a){7.1d.39(a,7)})},5q:H(){I 7.3W(19,Q,M,H(a){7.1d.39(a,7.2H)})},3l:H(){I 7.5n||D([])},2q:H(b){J c=D.2l(7,H(a){I D.2q(b,a)});I 7.2I(/[^+>] [^+>]/.11(b)||b.1h("..")>-1?D.4r(c):c)},5y:H(e){J f=7.2l(H(){G(D.14.1f&&!D.4n(7)){J a=7.6o(M),5h=S.3h("1v");5h.3U(a);I D.4h([5h.4H])[0]}N I 7.6o(M)});J d=f.2q("*").5c().P(H(){G(7[E]!=12)7[E]=U});G(e===M)7.2q("*").5c().P(H(i){G(7.16==3)I;J c=D.L(7,"3w");R(J a 1n c)R(J b 1n c[a])D.W.1e(d[i],a,c[a][b],c[a][b].L)});I f},1E:H(b){I 7.2I(D.1D(b)&&D.3C(7,H(a,i){I b.1k(a,i)})||D.3g(b,7))},4Y:H(b){G(b.1q==56)G(62.11(b))I 7.2I(D.3g(b,7,M));N b=D.3g(b,7);J a=b.K&&b[b.K-1]!==12&&!b.16;I 7.1E(H(){I a?D.2L(7,b)<0:7!=b})},1e:H(a){I 7.2I(D.4r(D.2R(7.3p(),1j a==\'23\'?D(a):D.2d(a))))},3F:H(a){I!!a&&D.3g(a,7).K>0},7T:H(a){I 7.3F("."+a)},6e:H(b){G(b==12){G(7.K){J c=7[0];G(D.Y(c,"2A")){J e=c.64,63=[],15=c.15,2V=c.O=="2A-2V";G(e<0)I U;R(J i=2V?e:0,2f=2V?e+1:15.K;i<2f;i++){J d=15[i];G(d.2W){b=D.14.1f&&!d.at.2x.an?d.1r:d.2x;G(2V)I b;63.1p(b)}}I 63}N I(7[0].2x||"").1o(/\\r/g,"")}I 12}G(b.1q==4L)b+=\'\';I 7.P(H(){G(7.16!=1)I;G(b.1q==2p&&/5O|5L/.11(7.O))7.4J=(D.2L(7.2x,b)>=0||D.2L(7.34,b)>=0);N G(D.Y(7,"2A")){J a=D.2d(b);D("9R",7).P(H(){7.2W=(D.2L(7.2x,a)>=0||D.2L(7.1r,a)>=0)});G(!a.K)7.64=-1}N 7.2x=b})},2K:H(a){I a==12?(7[0]?7[0].4H:U):7.4E().3v(a)},7b:H(a){I 7.5q(a).21()},79:H(i){I 7.3s(i,i+1)},3s:H(){I 7.2I(2p.44.3s.1w(7,19))},2l:H(b){I 7.2I(D.2l(7,H(a,i){I b.1k(a,i,a)}))},5c:H(){I 7.1e(7.5n)},L:H(d,b){J a=d.1R(".");a[1]=a[1]?"."+a[1]:"";G(b===12){J c=7.5C("9z"+a[1]+"!",[a[0]]);G(c===12&&7.K)c=D.L(7[0],d);I c===12&&a[1]?7.L(a[0]):c}N I 7.1P("9u"+a[1]+"!",[a[0],b]).P(H(){D.L(7,d,b)})},3b:H(a){I 7.P(H(){D.3b(7,a)})},3W:H(g,f,h,d){J e=7.K>1,3x;I 7.P(H(){G(!3x){3x=D.4h(g,7.2z);G(h)3x.9o()}J b=7;G(f&&D.Y(7,"1T")&&D.Y(3x[0],"4F"))b=7.3H("22")[0]||7.3U(7.2z.3h("22"));J c=D([]);D.P(3x,H(){J a=e?D(7).5y(M)[0]:7;G(D.Y(a,"1m"))c=c.1e(a);N{G(a.16==1)c=c.1e(D("1m",a).21());d.1k(b,a)}});c.P(6T)})}};D.17.5j.44=D.17;H 6T(i,a){G(a.4d)D.3Y({1a:a.4d,31:Q,1O:"1m"});N D.5u(a.1r||a.6O||a.4H||"");G(a.1d)a.1d.37(a)}H 1z(){I+2B 8J}D.1l=D.17.1l=H(){J b=19[0]||{},i=1,K=19.K,4x=Q,15;G(b.1q==8I){4x=b;b=19[1]||{};i=2}G(1j b!="49"&&1j b!="H")b={};G(K==i){b=7;--i}R(;i-1}},6q:H(b,c,a){J e={};R(J d 1n c){e[d]=b.V[d];b.V[d]=c[d]}a.1k(b);R(J d 1n c)b.V[d]=e[d]},1g:H(d,e,c){G(e=="2h"||e=="1Z"){J b,3X={30:"5x",5g:"1G",18:"3I"},35=e=="2h"?["5e","6k"]:["5G","6i"];H 5b(){b=e=="2h"?d.8f:d.8c;J a=0,2C=0;D.P(35,H(){a+=3d(D.2a(d,"57"+7,M))||0;2C+=3d(D.2a(d,"2C"+7+"4b",M))||0});b-=29.83(a+2C)}G(D(d).3F(":4j"))5b();N D.6q(d,3X,5b);I 29.2f(0,b)}I D.2a(d,e,c)},2a:H(f,l,k){J e,V=f.V;H 3E(b){G(!D.14.2k)I Q;J a=3P.54(b,U);I!a||a.52("3E")==""}G(l=="1y"&&D.14.1f){e=D.1K(V,"1y");I e==""?"1":e}G(D.14.2G&&l=="18"){J d=V.50;V.50="0 7Y 7W";V.50=d}G(l.1I(/4i/i))l=y;G(!k&&V&&V[l])e=V[l];N G(3P.54){G(l.1I(/4i/i))l="4i";l=l.1o(/([A-Z])/g,"-$1").3y();J c=3P.54(f,U);G(c&&!3E(f))e=c.52(l);N{J g=[],2E=[],a=f,i=0;R(;a&&3E(a);a=a.1d)2E.6h(a);R(;i<2E.K;i++)G(3E(2E[i])){g[i]=2E[i].V.18;2E[i].V.18="3I"}e=l=="18"&&g[2E.K-1]!=U?"2F":(c&&c.52(l))||"";R(i=0;i]*?)\\/>/g,H(b,a,c){I c.1I(/^(aK|4f|7E|aG|4T|7A|aB|3n|az|ay|av)$/i)?b:a+">"});J f=D.3k(d).3y(),1v=h.3h("1v");J e=!f.1h("",""]||!f.1h("",""]||f.1I(/^<(aq|22|am|ak|ai)/)&&[1,"<1T>",""]||!f.1h("<4F")&&[2,"<1T><22>",""]||(!f.1h("<22><4F>",""]||!f.1h("<7E")&&[2,"<1T><22><7q>",""]||D.14.1f&&[1,"1v<1v>",""]||[0,"",""];1v.4H=e[1]+d+e[2];1B(e[0]--)1v=1v.5T;G(D.14.1f){J g=!f.1h("<1T")&&f.1h("<22")<0?1v.1x&&1v.1x.3t:e[1]=="<1T>"&&f.1h("<22")<0?1v.3t:[];R(J j=g.K-1;j>=0;--j)G(D.Y(g[j],"22")&&!g[j].3t.K)g[j].1d.37(g[j]);G(/^\\s/.11(d))1v.39(h.5F(d.1I(/^\\s*/)[0]),1v.1x)}d=D.2d(1v.3t)}G(d.K===0&&(!D.Y(d,"3V")&&!D.Y(d,"2A")))I;G(d[0]==12||D.Y(d,"3V")||d.15)k.1p(d);N k=D.2R(k,d)});I k},1K:H(d,f,c){G(!d||d.16==3||d.16==8)I 12;J e=!D.4n(d),40=c!==12,1f=D.14.1f;f=e&&D.3X[f]||f;G(d.2j){J g=/5Q|4d|V/.11(f);G(f=="2W"&&D.14.2k)d.1d.64;G(f 1n d&&e&&!g){G(40){G(f=="O"&&D.Y(d,"4T")&&d.1d)7p"O a3 a1\'t 9V 9U";d[f]=c}G(D.Y(d,"3V")&&d.7i(f))I d.7i(f).76;I d[f]}G(1f&&e&&f=="V")I D.1K(d.V,"9T",c);G(40)d.9Q(f,""+c);J h=1f&&e&&g?d.4G(f,2):d.4G(f);I h===U?12:h}G(1f&&f=="1y"){G(40){d.6B=1;d.1E=(d.1E||"").1o(/7f\\([^)]*\\)/,"")+(3r(c)+\'\'=="9L"?"":"7f(1y="+c*7a+")")}I d.1E&&d.1E.1h("1y=")>=0?(3d(d.1E.1I(/1y=([^)]*)/)[1])/7a)+\'\':""}f=f.1o(/-([a-z])/9H,H(a,b){I b.2r()});G(40)d[f]=c;I d[f]},3k:H(a){I(a||"").1o(/^\\s+|\\s+$/g,"")},2d:H(b){J a=[];G(b!=U){J i=b.K;G(i==U||b.1R||b.4I||b.1k)a[0]=b;N 1B(i)a[--i]=b[i]}I a},2L:H(b,a){R(J i=0,K=a.K;i*",7).21();1B(7.1x)7.37(7.1x)}},H(a,b){D.17[a]=H(){I 7.P(b,19)}});D.P(["6N","4b"],H(i,c){J b=c.3y();D.17[b]=H(a){I 7[0]==1b?D.14.2G&&S.1c["5t"+c]||D.14.2k&&1b["5s"+c]||S.70=="6Z"&&S.1C["5t"+c]||S.1c["5t"+c]:7[0]==S?29.2f(29.2f(S.1c["4y"+c],S.1C["4y"+c]),29.2f(S.1c["2i"+c],S.1C["2i"+c])):a==12?(7.K?D.1g(7[0],b):U):7.1g(b,a.1q==56?a:a+"2X")}});H 25(a,b){I a[0]&&3r(D.2a(a[0],b,M),10)||0}J C=D.14.2k&&3r(D.14.5B)<8H?"(?:[\\\\w*3m-]|\\\\\\\\.)":"(?:[\\\\w\\8F-\\8E*3m-]|\\\\\\\\.)",6L=2B 4v("^>\\\\s*("+C+"+)"),6J=2B 4v("^("+C+"+)(#)("+C+"+)"),6I=2B 4v("^([#.]?)("+C+"*)");D.1l({6H:{"":H(a,i,m){I m[2]=="*"||D.Y(a,m[2])},"#":H(a,i,m){I a.4G("2v")==m[2]},":":{8D:H(a,i,m){I im[3]-0},3a:H(a,i,m){I m[3]-0==i},79:H(a,i,m){I m[3]-0==i},3o:H(a,i){I i==0},3S:H(a,i,m,r){I i==r.K-1},6D:H(a,i){I i%2==0},6C:H(a,i){I i%2},"3o-4u":H(a){I a.1d.3H("*")[0]==a},"3S-4u":H(a){I D.3a(a.1d.5T,1,"4l")==a},"8z-4u":H(a){I!D.3a(a.1d.5T,2,"4l")},6W:H(a){I a.1x},4E:H(a){I!a.1x},8y:H(a,i,m){I(a.6O||a.8x||D(a).1r()||"").1h(m[3])>=0},4j:H(a){I"1G"!=a.O&&D.1g(a,"18")!="2F"&&D.1g(a,"5g")!="1G"},1G:H(a){I"1G"==a.O||D.1g(a,"18")=="2F"||D.1g(a,"5g")=="1G"},8w:H(a){I!a.3R},3R:H(a){I a.3R},4J:H(a){I a.4J},2W:H(a){I a.2W||D.1K(a,"2W")},1r:H(a){I"1r"==a.O},5O:H(a){I"5O"==a.O},5L:H(a){I"5L"==a.O},5p:H(a){I"5p"==a.O},3Q:H(a){I"3Q"==a.O},5o:H(a){I"5o"==a.O},6A:H(a){I"6A"==a.O},6z:H(a){I"6z"==a.O},2s:H(a){I"2s"==a.O||D.Y(a,"2s")},4T:H(a){I/4T|2A|6y|2s/i.11(a.Y)},3T:H(a,i,m){I D.2q(m[3],a).K},8t:H(a){I/h\\d/i.11(a.Y)},8s:H(a){I D.3C(D.3O,H(b){I a==b.T}).K}}},6x:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2B 4v("^([:.#]*)("+C+"+)")],3g:H(a,c,b){J d,1t=[];1B(a&&a!=d){d=a;J f=D.1E(a,c,b);a=f.t.1o(/^\\s*,\\s*/,"");1t=b?c=f.r:D.2R(1t,f.r)}I 1t},2q:H(t,o){G(1j t!="23")I[t];G(o&&o.16!=1&&o.16!=9)I[];o=o||S;J d=[o],2o=[],3S,Y;1B(t&&3S!=t){J r=[];3S=t;t=D.3k(t);J l=Q,3j=6L,m=3j.2D(t);G(m){Y=m[1].2r();R(J i=0;d[i];i++)R(J c=d[i].1x;c;c=c.2H)G(c.16==1&&(Y=="*"||c.Y.2r()==Y))r.1p(c);d=r;t=t.1o(3j,"");G(t.1h(" ")==0)6M;l=M}N{3j=/^([>+~])\\s*(\\w*)/i;G((m=3j.2D(t))!=U){r=[];J k={};Y=m[2].2r();m=m[1];R(J j=0,3i=d.K;j<3i;j++){J n=m=="~"||m=="+"?d[j].2H:d[j].1x;R(;n;n=n.2H)G(n.16==1){J g=D.L(n);G(m=="~"&&k[g])1X;G(!Y||n.Y.2r()==Y){G(m=="~")k[g]=M;r.1p(n)}G(m=="+")1X}}d=r;t=D.3k(t.1o(3j,""));l=M}}G(t&&!l){G(!t.1h(",")){G(o==d[0])d.4s();2o=D.2R(2o,d);r=d=[o];t=" "+t.6v(1,t.K)}N{J h=6J;J m=h.2D(t);G(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2D(t)}m[2]=m[2].1o(/\\\\/g,"");J f=d[d.K-1];G(m[1]=="#"&&f&&f.61&&!D.4n(f)){J p=f.61(m[2]);G((D.14.1f||D.14.2G)&&p&&1j p.2v=="23"&&p.2v!=m[2])p=D(\'[@2v="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.Y(p,m[3]))?[p]:[]}N{R(J i=0;d[i];i++){J a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];G(a=="*"&&d[i].Y.3y()=="49")a="3n";r=D.2R(r,d[i].3H(a))}G(m[1]==".")r=D.5m(r,m[2]);G(m[1]=="#"){J e=[];R(J i=0;r[i];i++)G(r[i].4G("2v")==m[2]){e=[r[i]];1X}r=e}d=r}t=t.1o(h,"")}}G(t){J b=D.1E(t,r);d=r=b.r;t=D.3k(b.t)}}G(t)d=[];G(d&&o==d[0])d.4s();2o=D.2R(2o,d);I 2o},5m:H(r,m,a){m=" "+m+" ";J c=[];R(J i=0;r[i];i++){J b=(" "+r[i].1F+" ").1h(m)>=0;G(!a&&b||a&&!b)c.1p(r[i])}I c},1E:H(t,r,h){J d;1B(t&&t!=d){d=t;J p=D.6x,m;R(J i=0;p[i];i++){m=p[i].2D(t);G(m){t=t.8r(m[0].K);m[2]=m[2].1o(/\\\\/g,"");1X}}G(!m)1X;G(m[1]==":"&&m[2]=="4Y")r=62.11(m[3])?D.1E(m[3],r,M).r:D(r).4Y(m[3]);N G(m[1]==".")r=D.5m(r,m[2],h);N G(m[1]=="["){J g=[],O=m[3];R(J i=0,3i=r.K;i<3i;i++){J a=r[i],z=a[D.3X[m[2]]||m[2]];G(z==U||/5Q|4d|2W/.11(m[2]))z=D.1K(a,m[2])||\'\';G((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1h(m[5])||O=="$="&&z.6v(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1h(m[5])>=0)^h)g.1p(a)}r=g}N G(m[1]==":"&&m[2]=="3a-4u"){J e={},g=[],11=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2D(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.11(m[3])&&"8q+"+m[3]||m[3]),3o=(11[1]+(11[2]||1))-0,d=11[3]-0;R(J i=0,3i=r.K;i<3i;i++){J j=r[i],1d=j.1d,2v=D.L(1d);G(!e[2v]){J c=1;R(J n=1d.1x;n;n=n.2H)G(n.16==1)n.4q=c++;e[2v]=M}J b=Q;G(3o==0){G(j.4q==d)b=M}N G((j.4q-d)%3o==0&&(j.4q-d)/3o>=0)b=M;G(b^h)g.1p(j)}r=g}N{J f=D.6H[m[1]];G(1j f=="49")f=f[m[2]];G(1j f=="23")f=6u("Q||H(a,i){I "+f+";}");r=D.3C(r,H(a,i){I f(a,i,m,r)},h)}}I{r:r,t:t}},4S:H(b,c){J a=[],1t=b[c];1B(1t&&1t!=S){G(1t.16==1)a.1p(1t);1t=1t[c]}I a},3a:H(a,e,c,b){e=e||1;J d=0;R(;a;a=a[c])G(a.16==1&&++d==e)1X;I a},5v:H(n,a){J r=[];R(;n;n=n.2H){G(n.16==1&&n!=a)r.1p(n)}I r}});D.W={1e:H(f,i,g,e){G(f.16==3||f.16==8)I;G(D.14.1f&&f.4I)f=1b;G(!g.24)g.24=7.24++;G(e!=12){J h=g;g=7.3M(h,H(){I h.1w(7,19)});g.L=e}J j=D.L(f,"3w")||D.L(f,"3w",{}),1H=D.L(f,"1H")||D.L(f,"1H",H(){G(1j D!="12"&&!D.W.5k)I D.W.1H.1w(19.3L.T,19)});1H.T=f;D.P(i.1R(/\\s+/),H(c,b){J a=b.1R(".");b=a[0];g.O=a[1];J d=j[b];G(!d){d=j[b]={};G(!D.W.2t[b]||D.W.2t[b].4p.1k(f)===Q){G(f.3K)f.3K(b,1H,Q);N G(f.6t)f.6t("4o"+b,1H)}}d[g.24]=g;D.W.26[b]=M});f=U},24:1,26:{},21:H(e,h,f){G(e.16==3||e.16==8)I;J i=D.L(e,"3w"),1L,5i;G(i){G(h==12||(1j h=="23"&&h.8p(0)=="."))R(J g 1n i)7.21(e,g+(h||""));N{G(h.O){f=h.2y;h=h.O}D.P(h.1R(/\\s+/),H(b,a){J c=a.1R(".");a=c[0];G(i[a]){G(f)2U i[a][f.24];N R(f 1n i[a])G(!c[1]||i[a][f].O==c[1])2U i[a][f];R(1L 1n i[a])1X;G(!1L){G(!D.W.2t[a]||D.W.2t[a].4A.1k(e)===Q){G(e.6p)e.6p(a,D.L(e,"1H"),Q);N G(e.6n)e.6n("4o"+a,D.L(e,"1H"))}1L=U;2U i[a]}}})}R(1L 1n i)1X;G(!1L){J d=D.L(e,"1H");G(d)d.T=U;D.3b(e,"3w");D.3b(e,"1H")}}},1P:H(h,c,f,g,i){c=D.2d(c);G(h.1h("!")>=0){h=h.3s(0,-1);J a=M}G(!f){G(7.26[h])D("*").1e([1b,S]).1P(h,c)}N{G(f.16==3||f.16==8)I 12;J b,1L,17=D.1D(f[h]||U),W=!c[0]||!c[0].32;G(W){c.6h({O:h,2J:f,32:H(){},3J:H(){},4C:1z()});c[0][E]=M}c[0].O=h;G(a)c[0].6m=M;J d=D.L(f,"1H");G(d)b=d.1w(f,c);G((!17||(D.Y(f,\'a\')&&h=="4V"))&&f["4o"+h]&&f["4o"+h].1w(f,c)===Q)b=Q;G(W)c.4s();G(i&&D.1D(i)){1L=i.1w(f,b==U?c:c.7d(b));G(1L!==12)b=1L}G(17&&g!==Q&&b!==Q&&!(D.Y(f,\'a\')&&h=="4V")){7.5k=M;1U{f[h]()}1V(e){}}7.5k=Q}I b},1H:H(b){J a,1L,38,5f,4m;b=19[0]=D.W.6l(b||1b.W);38=b.O.1R(".");b.O=38[0];38=38[1];5f=!38&&!b.6m;4m=(D.L(7,"3w")||{})[b.O];R(J j 1n 4m){J c=4m[j];G(5f||c.O==38){b.2y=c;b.L=c.L;1L=c.1w(7,19);G(a!==Q)a=1L;G(1L===Q){b.32();b.3J()}}}I a},6l:H(b){G(b[E]==M)I b;J d=b;b={8o:d};J c="8n 8m 8l 8k 2s 8j 47 5d 6j 5E 8i L 8h 8g 4K 2y 5a 59 8e 8b 58 6f 8a 88 4k 87 86 84 6d 2J 4C 6c O 82 81 35".1R(" ");R(J i=c.K;i;i--)b[c[i]]=d[c[i]];b[E]=M;b.32=H(){G(d.32)d.32();d.80=Q};b.3J=H(){G(d.3J)d.3J();d.7Z=M};b.4C=b.4C||1z();G(!b.2J)b.2J=b.6d||S;G(b.2J.16==3)b.2J=b.2J.1d;G(!b.4k&&b.4K)b.4k=b.4K==b.2J?b.6c:b.4K;G(b.58==U&&b.5d!=U){J a=S.1C,1c=S.1c;b.58=b.5d+(a&&a.2e||1c&&1c.2e||0)-(a.6b||0);b.6f=b.6j+(a&&a.2c||1c&&1c.2c||0)-(a.6a||0)}G(!b.35&&((b.47||b.47===0)?b.47:b.5a))b.35=b.47||b.5a;G(!b.59&&b.5E)b.59=b.5E;G(!b.35&&b.2s)b.35=(b.2s&1?1:(b.2s&2?3:(b.2s&4?2:0)));I b},3M:H(a,b){b.24=a.24=a.24||b.24||7.24++;I b},2t:{27:{4p:H(){55();I},4A:H(){I}},3D:{4p:H(){G(D.14.1f)I Q;D(7).2O("53",D.W.2t.3D.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("53",D.W.2t.3D.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3D";I D.W.1H.1w(7,19)}},3N:{4p:H(){G(D.14.1f)I Q;D(7).2O("51",D.W.2t.3N.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("51",D.W.2t.3N.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3N";I D.W.1H.1w(7,19)}}}};D.17.1l({2O:H(c,a,b){I c=="4X"?7.2V(c,a,b):7.P(H(){D.W.1e(7,c,b||a,b&&a)})},2V:H(d,b,c){J e=D.W.3M(c||b,H(a){D(7).4e(a,e);I(c||b).1w(7,19)});I 7.P(H(){D.W.1e(7,d,e,c&&b)})},4e:H(a,b){I 7.P(H(){D.W.21(7,a,b)})},1P:H(c,a,b){I 7.P(H(){D.W.1P(c,a,7,M,b)})},5C:H(c,a,b){I 7[0]&&D.W.1P(c,a,7[0],Q,b)},2m:H(b){J c=19,i=1;1B(i=0){J i=g.3s(e,g.K);g=g.3s(0,e)}c=c||H(){};J f="2P";G(d)G(D.1D(d)){c=d;d=U}N{d=D.3n(d);f="6g"}J h=7;D.3Y({1a:g,O:f,1O:"2K",L:d,1J:H(a,b){G(b=="1W"||b=="7J")h.2K(i?D("<1v/>").3v(a.4U.1o(/<1m(.|\\s)*?\\/1m>/g,"")).2q(i):a.4U);h.P(c,[a.4U,b,a])}});I 7},aL:H(){I D.3n(7.7I())},7I:H(){I 7.2l(H(){I D.Y(7,"3V")?D.2d(7.aH):7}).1E(H(){I 7.34&&!7.3R&&(7.4J||/2A|6y/i.11(7.Y)||/1r|1G|3Q/i.11(7.O))}).2l(H(i,c){J b=D(7).6e();I b==U?U:b.1q==2p?D.2l(b,H(a,i){I{34:c.34,2x:a}}):{34:c.34,2x:b}}).3p()}});D.P("7H,7G,7F,7D,7C,7B".1R(","),H(i,o){D.17[o]=H(f){I 7.2O(o,f)}});J B=1z();D.1l({3p:H(d,b,a,c){G(D.1D(b)){a=b;b=U}I D.3Y({O:"2P",1a:d,L:b,1W:a,1O:c})},aE:H(b,a){I D.3p(b,U,a,"1m")},aD:H(c,b,a){I D.3p(c,b,a,"3z")},aC:H(d,b,a,c){G(D.1D(b)){a=b;b={}}I D.3Y({O:"6g",1a:d,L:b,1W:a,1O:c})},aA:H(a){D.1l(D.60,a)},60:{1a:5Z.5Q,26:M,O:"2P",2T:0,7z:"4R/x-ax-3V-aw",7x:M,31:M,L:U,5Y:U,3Q:U,4Q:{2N:"4R/2N, 1r/2N",2K:"1r/2K",1m:"1r/4t, 4R/4t",3z:"4R/3z, 1r/4t",1r:"1r/as",4w:"*/*"}},4z:{},3Y:H(s){s=D.1l(M,s,D.1l(M,{},D.60,s));J g,2Z=/=\\?(&|$)/g,1u,L,O=s.O.2r();G(s.L&&s.7x&&1j s.L!="23")s.L=D.3n(s.L);G(s.1O=="4P"){G(O=="2P"){G(!s.1a.1I(2Z))s.1a+=(s.1a.1I(/\\?/)?"&":"?")+(s.4P||"7u")+"=?"}N G(!s.L||!s.L.1I(2Z))s.L=(s.L?s.L+"&":"")+(s.4P||"7u")+"=?";s.1O="3z"}G(s.1O=="3z"&&(s.L&&s.L.1I(2Z)||s.1a.1I(2Z))){g="4P"+B++;G(s.L)s.L=(s.L+"").1o(2Z,"="+g+"$1");s.1a=s.1a.1o(2Z,"="+g+"$1");s.1O="1m";1b[g]=H(a){L=a;1W();1J();1b[g]=12;1U{2U 1b[g]}1V(e){}G(i)i.37(h)}}G(s.1O=="1m"&&s.1Y==U)s.1Y=Q;G(s.1Y===Q&&O=="2P"){J j=1z();J k=s.1a.1o(/(\\?|&)3m=.*?(&|$)/,"$ap="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1I(/\\?/)?"&":"?")+"3m="+j:"")}G(s.L&&O=="2P"){s.1a+=(s.1a.1I(/\\?/)?"&":"?")+s.L;s.L=U}G(s.26&&!D.4O++)D.W.1P("7H");J n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;G(s.1O=="1m"&&O=="2P"&&n.11(s.1a)&&n.2D(s.1a)[1]!=5Z.al){J i=S.3H("6w")[0];J h=S.3h("1m");h.4d=s.1a;G(s.7t)h.aj=s.7t;G(!g){J l=Q;h.ah=h.ag=H(){G(!l&&(!7.3f||7.3f=="68"||7.3f=="1J")){l=M;1W();1J();i.37(h)}}}i.3U(h);I 12}J m=Q;J c=1b.7s?2B 7s("ae.ac"):2B 7r();G(s.5Y)c.6R(O,s.1a,s.31,s.5Y,s.3Q);N c.6R(O,s.1a,s.31);1U{G(s.L)c.4B("ab-aa",s.7z);G(s.5S)c.4B("a9-5R-a8",D.4z[s.1a]||"a7, a6 a5 a4 5N:5N:5N a2");c.4B("X-9Z-9Y","7r");c.4B("9W",s.1O&&s.4Q[s.1O]?s.4Q[s.1O]+", */*":s.4Q.4w)}1V(e){}G(s.7m&&s.7m(c,s)===Q){s.26&&D.4O--;c.7l();I Q}G(s.26)D.W.1P("7B",[c,s]);J d=H(a){G(!m&&c&&(c.3f==4||a=="2T")){m=M;G(f){7k(f);f=U}1u=a=="2T"&&"2T"||!D.7j(c)&&"3e"||s.5S&&D.7h(c,s.1a)&&"7J"||"1W";G(1u=="1W"){1U{L=D.6X(c,s.1O,s.9S)}1V(e){1u="5J"}}G(1u=="1W"){J b;1U{b=c.5I("7g-5R")}1V(e){}G(s.5S&&b)D.4z[s.1a]=b;G(!g)1W()}N D.5H(s,c,1u);1J();G(s.31)c=U}};G(s.31){J f=4I(d,13);G(s.2T>0)3B(H(){G(c){c.7l();G(!m)d("2T")}},s.2T)}1U{c.9P(s.L)}1V(e){D.5H(s,c,U,e)}G(!s.31)d();H 1W(){G(s.1W)s.1W(L,1u);G(s.26)D.W.1P("7C",[c,s])}H 1J(){G(s.1J)s.1J(c,1u);G(s.26)D.W.1P("7F",[c,s]);G(s.26&&!--D.4O)D.W.1P("7G")}I c},5H:H(s,a,b,e){G(s.3e)s.3e(a,b,e);G(s.26)D.W.1P("7D",[a,s,e])},4O:0,7j:H(a){1U{I!a.1u&&5Z.9O=="5p:"||(a.1u>=7e&&a.1u<9N)||a.1u==7c||a.1u==9K||D.14.2k&&a.1u==12}1V(e){}I Q},7h:H(a,c){1U{J b=a.5I("7g-5R");I a.1u==7c||b==D.4z[c]||D.14.2k&&a.1u==12}1V(e){}I Q},6X:H(a,c,b){J d=a.5I("9J-O"),2N=c=="2N"||!c&&d&&d.1h("2N")>=0,L=2N?a.9I:a.4U;G(2N&&L.1C.2j=="5J")7p"5J";G(b)L=b(L,c);G(c=="1m")D.5u(L);G(c=="3z")L=6u("("+L+")");I L},3n:H(a){J s=[];G(a.1q==2p||a.5w)D.P(a,H(){s.1p(3u(7.34)+"="+3u(7.2x))});N R(J j 1n a)G(a[j]&&a[j].1q==2p)D.P(a[j],H(){s.1p(3u(j)+"="+3u(7))});N s.1p(3u(j)+"="+3u(D.1D(a[j])?a[j]():a[j]));I s.6s("&").1o(/%20/g,"+")}});D.17.1l({1N:H(c,b){I c?7.2g({1Z:"1N",2h:"1N",1y:"1N"},c,b):7.1E(":1G").P(H(){7.V.18=7.5D||"";G(D.1g(7,"18")=="2F"){J a=D("<"+7.2j+" />").6P("1c");7.V.18=a.1g("18");G(7.V.18=="2F")7.V.18="3I";a.21()}}).3l()},1M:H(b,a){I b?7.2g({1Z:"1M",2h:"1M",1y:"1M"},b,a):7.1E(":4j").P(H(){7.5D=7.5D||D.1g(7,"18");7.V.18="2F"}).3l()},78:D.17.2m,2m:H(a,b){I D.1D(a)&&D.1D(b)?7.78.1w(7,19):a?7.2g({1Z:"2m",2h:"2m",1y:"2m"},a,b):7.P(H(){D(7)[D(7).3F(":1G")?"1N":"1M"]()})},9G:H(b,a){I 7.2g({1Z:"1N"},b,a)},9F:H(b,a){I 7.2g({1Z:"1M"},b,a)},9E:H(b,a){I 7.2g({1Z:"2m"},b,a)},9D:H(b,a){I 7.2g({1y:"1N"},b,a)},9M:H(b,a){I 7.2g({1y:"1M"},b,a)},9C:H(c,a,b){I 7.2g({1y:a},c,b)},2g:H(k,j,i,g){J h=D.77(j,i,g);I 7[h.36===Q?"P":"36"](H(){G(7.16!=1)I Q;J f=D.1l({},h),p,1G=D(7).3F(":1G"),46=7;R(p 1n k){G(k[p]=="1M"&&1G||k[p]=="1N"&&!1G)I f.1J.1k(7);G(p=="1Z"||p=="2h"){f.18=D.1g(7,"18");f.33=7.V.33}}G(f.33!=U)7.V.33="1G";f.45=D.1l({},k);D.P(k,H(c,a){J e=2B D.28(46,f,c);G(/2m|1N|1M/.11(a))e[a=="2m"?1G?"1N":"1M":a](k);N{J b=a.6r().1I(/^([+-]=)?([\\d+-.]+)(.*)$/),2b=e.1t(M)||0;G(b){J d=3d(b[2]),2M=b[3]||"2X";G(2M!="2X"){46.V[c]=(d||1)+2M;2b=((d||1)/e.1t(M))*2b;46.V[c]=2b+2M}G(b[1])d=((b[1]=="-="?-1:1)*d)+2b;e.3G(2b,d,2M)}N e.3G(2b,a,"")}});I M})},36:H(a,b){G(D.1D(a)||(a&&a.1q==2p)){b=a;a="28"}G(!a||(1j a=="23"&&!b))I A(7[0],a);I 7.P(H(){G(b.1q==2p)A(7,a,b);N{A(7,a).1p(b);G(A(7,a).K==1)b.1k(7)}})},9X:H(b,c){J a=D.3O;G(b)7.36([]);7.P(H(){R(J i=a.K-1;i>=0;i--)G(a[i].T==7){G(c)a[i](M);a.7n(i,1)}});G(!c)7.5A();I 7}});J A=H(b,c,a){G(b){c=c||"28";J q=D.L(b,c+"36");G(!q||a)q=D.L(b,c+"36",D.2d(a))}I q};D.17.5A=H(a){a=a||"28";I 7.P(H(){J q=A(7,a);q.4s();G(q.K)q[0].1k(7)})};D.1l({77:H(b,a,c){J d=b&&b.1q==a0?b:{1J:c||!c&&a||D.1D(b)&&b,2u:b,41:c&&a||a&&a.1q!=9t&&a};d.2u=(d.2u&&d.2u.1q==4L?d.2u:D.28.5K[d.2u])||D.28.5K.74;d.5M=d.1J;d.1J=H(){G(d.36!==Q)D(7).5A();G(D.1D(d.5M))d.5M.1k(7)};I d},41:{73:H(p,n,b,a){I b+a*p},5P:H(p,n,b,a){I((-29.9r(p*29.9q)/2)+0.5)*a+b}},3O:[],48:U,28:H(b,c,a){7.15=c;7.T=b;7.1i=a;G(!c.3Z)c.3Z={}}});D.28.44={4D:H(){G(7.15.2Y)7.15.2Y.1k(7.T,7.1z,7);(D.28.2Y[7.1i]||D.28.2Y.4w)(7);G(7.1i=="1Z"||7.1i=="2h")7.T.V.18="3I"},1t:H(a){G(7.T[7.1i]!=U&&7.T.V[7.1i]==U)I 7.T[7.1i];J r=3d(D.1g(7.T,7.1i,a));I r&&r>-9p?r:3d(D.2a(7.T,7.1i))||0},3G:H(c,b,d){7.5V=1z();7.2b=c;7.3l=b;7.2M=d||7.2M||"2X";7.1z=7.2b;7.2S=7.4N=0;7.4D();J e=7;H t(a){I e.2Y(a)}t.T=7.T;D.3O.1p(t);G(D.48==U){D.48=4I(H(){J a=D.3O;R(J i=0;i7.15.2u+7.5V){7.1z=7.3l;7.2S=7.4N=1;7.4D();7.15.45[7.1i]=M;J b=M;R(J i 1n 7.15.45)G(7.15.45[i]!==M)b=Q;G(b){G(7.15.18!=U){7.T.V.33=7.15.33;7.T.V.18=7.15.18;G(D.1g(7.T,"18")=="2F")7.T.V.18="3I"}G(7.15.1M)7.T.V.18="2F";G(7.15.1M||7.15.1N)R(J p 1n 7.15.45)D.1K(7.T.V,p,7.15.3Z[p])}G(b)7.15.1J.1k(7.T);I Q}N{J n=t-7.5V;7.4N=n/7.15.2u;7.2S=D.41[7.15.41||(D.41.5P?"5P":"73")](7.4N,n,0,1,7.15.2u);7.1z=7.2b+((7.3l-7.2b)*7.2S);7.4D()}I M}};D.1l(D.28,{5K:{9l:9j,9i:7e,74:9g},2Y:{2e:H(a){a.T.2e=a.1z},2c:H(a){a.T.2c=a.1z},1y:H(a){D.1K(a.T.V,"1y",a.1z)},4w:H(a){a.T.V[a.1i]=a.1z+a.2M}}});D.17.2i=H(){J b=0,1S=0,T=7[0],3q;G(T)ao(D.14){J d=T.1d,4a=T,1s=T.1s,1Q=T.2z,5U=2k&&3r(5B)<9c&&!/9a/i.11(v),1g=D.2a,3c=1g(T,"30")=="3c";G(T.7y){J c=T.7y();1e(c.1A+29.2f(1Q.1C.2e,1Q.1c.2e),c.1S+29.2f(1Q.1C.2c,1Q.1c.2c));1e(-1Q.1C.6b,-1Q.1C.6a)}N{1e(T.5X,T.5W);1B(1s){1e(1s.5X,1s.5W);G(42&&!/^t(98|d|h)$/i.11(1s.2j)||2k&&!5U)2C(1s);G(!3c&&1g(1s,"30")=="3c")3c=M;4a=/^1c$/i.11(1s.2j)?4a:1s;1s=1s.1s}1B(d&&d.2j&&!/^1c|2K$/i.11(d.2j)){G(!/^96|1T.*$/i.11(1g(d,"18")))1e(-d.2e,-d.2c);G(42&&1g(d,"33")!="4j")2C(d);d=d.1d}G((5U&&(3c||1g(4a,"30")=="5x"))||(42&&1g(4a,"30")!="5x"))1e(-1Q.1c.5X,-1Q.1c.5W);G(3c)1e(29.2f(1Q.1C.2e,1Q.1c.2e),29.2f(1Q.1C.2c,1Q.1c.2c))}3q={1S:1S,1A:b}}H 2C(a){1e(D.2a(a,"6V",M),D.2a(a,"6U",M))}H 1e(l,t){b+=3r(l,10)||0;1S+=3r(t,10)||0}I 3q};D.17.1l({30:H(){J a=0,1S=0,3q;G(7[0]){J b=7.1s(),2i=7.2i(),4c=/^1c|2K$/i.11(b[0].2j)?{1S:0,1A:0}:b.2i();2i.1S-=25(7,\'94\');2i.1A-=25(7,\'aF\');4c.1S+=25(b,\'6U\');4c.1A+=25(b,\'6V\');3q={1S:2i.1S-4c.1S,1A:2i.1A-4c.1A}}I 3q},1s:H(){J a=7[0].1s;1B(a&&(!/^1c|2K$/i.11(a.2j)&&D.1g(a,\'30\')==\'93\'))a=a.1s;I D(a)}});D.P([\'5e\',\'5G\'],H(i,b){J c=\'4y\'+b;D.17[c]=H(a){G(!7[0])I;I a!=12?7.P(H(){7==1b||7==S?1b.92(!i?a:D(1b).2e(),i?a:D(1b).2c()):7[c]=a}):7[0]==1b||7[0]==S?46[i?\'aI\':\'aJ\']||D.71&&S.1C[c]||S.1c[c]:7[0][c]}});D.P(["6N","4b"],H(i,b){J c=i?"5e":"5G",4f=i?"6k":"6i";D.17["5s"+b]=H(){I 7[b.3y()]()+25(7,"57"+c)+25(7,"57"+4f)};D.17["90"+b]=H(a){I 7["5s"+b]()+25(7,"2C"+c+"4b")+25(7,"2C"+4f+"4b")+(a?25(7,"6S"+c)+25(7,"6S"+4f):0)}})})();',62,669,'|||||||this|||||||||||||||||||||||||||||||||||if|function|return|var|length|data|true|else|type|each|false|for|document|elem|null|style|event||nodeName|||test|undefined||browser|options|nodeType|fn|display|arguments|url|window|body|parentNode|add|msie|css|indexOf|prop|typeof|call|extend|script|in|replace|push|constructor|text|offsetParent|cur|status|div|apply|firstChild|opacity|now|left|while|documentElement|isFunction|filter|className|hidden|handle|match|complete|attr|ret|hide|show|dataType|trigger|doc|split|top|table|try|catch|success|break|cache|height||remove|tbody|string|guid|num|global|ready|fx|Math|curCSS|start|scrollTop|makeArray|scrollLeft|max|animate|width|offset|tagName|safari|map|toggle||done|Array|find|toUpperCase|button|special|duration|id|copy|value|handler|ownerDocument|select|new|border|exec|stack|none|opera|nextSibling|pushStack|target|html|inArray|unit|xml|bind|GET|isReady|merge|pos|timeout|delete|one|selected|px|step|jsre|position|async|preventDefault|overflow|name|which|queue|removeChild|namespace|insertBefore|nth|removeData|fixed|parseFloat|error|readyState|multiFilter|createElement|rl|re|trim|end|_|param|first|get|results|parseInt|slice|childNodes|encodeURIComponent|append|events|elems|toLowerCase|json|readyList|setTimeout|grep|mouseenter|color|is|custom|getElementsByTagName|block|stopPropagation|addEventListener|callee|proxy|mouseleave|timers|defaultView|password|disabled|last|has|appendChild|form|domManip|props|ajax|orig|set|easing|mozilla|load|prototype|curAnim|self|charCode|timerId|object|offsetChild|Width|parentOffset|src|unbind|br|currentStyle|clean|float|visible|relatedTarget|previousSibling|handlers|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|child|RegExp|_default|deep|scroll|lastModified|teardown|setRequestHeader|timeStamp|update|empty|tr|getAttribute|innerHTML|setInterval|checked|fromElement|Number|jQuery|state|active|jsonp|accepts|application|dir|input|responseText|click|styleSheets|unload|not|lastToggle|outline|mouseout|getPropertyValue|mouseover|getComputedStyle|bindReady|String|padding|pageX|metaKey|keyCode|getWH|andSelf|clientX|Left|all|visibility|container|index|init|triggered|removeAttribute|classFilter|prevObject|submit|file|after|windowData|inner|client|globalEval|sibling|jquery|absolute|clone|wrapAll|dequeue|version|triggerHandler|oldblock|ctrlKey|createTextNode|Top|handleError|getResponseHeader|parsererror|speeds|checkbox|old|00|radio|swing|href|Modified|ifModified|lastChild|safari2|startTime|offsetTop|offsetLeft|username|location|ajaxSettings|getElementById|isSimple|values|selectedIndex|runtimeStyle|rsLeft|_load|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|val|pageY|POST|unshift|Bottom|clientY|Right|fix|exclusive|detachEvent|cloneNode|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|image|zoom|odd|even|before|prepend|exclude|expr|quickClass|quickID|uuid|quickChild|continue|Height|textContent|appendTo|contents|open|margin|evalScript|borderTopWidth|borderLeftWidth|parent|httpData|setArray|CSS1Compat|compatMode|boxModel|cssFloat|linear|def|webkit|nodeValue|speed|_toggle|eq|100|replaceWith|304|concat|200|alpha|Last|httpNotModified|getAttributeNode|httpSuccess|clearInterval|abort|beforeSend|splice|styleFloat|throw|colgroup|XMLHttpRequest|ActiveXObject|scriptCharset|callback|fieldset|multiple|processData|getBoundingClientRect|contentType|link|ajaxSend|ajaxSuccess|ajaxError|col|ajaxComplete|ajaxStop|ajaxStart|serializeArray|notmodified|keypress|keydown|change|mouseup|mousedown|dblclick|focus|blur|stylesheet|hasClass|rel|doScroll|black|hover|solid|cancelBubble|returnValue|wheelDelta|view|round|shiftKey|resize|screenY|screenX|relatedNode|mousemove|prevValue|originalTarget|offsetHeight|keyup|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|Date|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|outer|prev|scrollTo|static|marginTop|next|inline|parents|able|cellSpacing|adobeair|cellspacing|522|maxLength|maxlength|readOnly|400|readonly|fast|600|class|slow|1px|htmlFor|reverse|10000|PI|cos|compatible|Function|setData|ie|ra|it|rv|getData|userAgent|navigator|fadeTo|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|fadeOut|300|protocol|send|setAttribute|option|dataFilter|cssText|changed|be|Accept|stop|With|Requested|Object|can|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|XMLHTTP|th|Microsoft|td|onreadystatechange|onload|cap|charset|colg|host|tfoot|specified|with|1_|thead|leg|plain|attributes|opt|embed|urlencoded|www|area|hr|ajaxSetup|meta|post|getJSON|getScript|marginLeft|img|elements|pageYOffset|pageXOffset|abbr|serialize|pixelLeft'.split('|'),0,{})) \ No newline at end of file diff --git a/public/scripts/.svn/text-base/main.js.svn-base b/public/scripts/.svn/text-base/main.js.svn-base new file mode 100644 index 0000000..e69de29 diff --git a/public/scripts/admin.js b/public/scripts/admin.js new file mode 100644 index 0000000..ada7903 --- /dev/null +++ b/public/scripts/admin.js @@ -0,0 +1,113 @@ +$(document).ready(function(){ + + var base_url = $('input[name=base_url]').val(); + + $('a.change_password').click(function(){ + $('div#change_password_container').toggle(); + $('a.change_password').toggleClass('toggle'); + }); + + //show all tags + $('a.show_all_tags').click(function(){ + if ($('ul.tag_list.some').is(':visible')) { + $('ul.tag_list.some').slideUp('normal', function(){ + $('ul.tag_list.all').slideDown('normal'); + $('a.show_all_tags').html('Show Some Tags'); + }); + } else { + $('ul.tag_list.all').slideUp('normal', function(){ + $('ul.tag_list.some').slideDown('normal'); + $('a.show_all_tags').html('Show All Tags'); + }); + } + }); + + //reset cron key + $('a.reset_cron_key').click(function(){ + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/reset_cron_key", + success: function(msg){ + $('span#cron_key').html(msg); + } + }); + }); + + //cron url display + $('form#options_form').change(function(){ + if ($('input#radio_true').is(':checked')) { + $('span#cron_url').show(); + } else { + $('span#cron_url').hide(); + } + }); + + //save draft button + $('a.draft_button').click(function(){ + $('input[name=draft]').val('true'); + $('form').submit(); + }); + + //must confirm link + $('a.confirm_first').click(function(){ + if (confirm('Sure?')) { + return true; + } else { + return false; + } + }); + + //unpublish button + $('ul.activity_list li.unpublish_this a').click(function(){ + var id = $(this).parents('li.item').attr('id').replace('item_',''); + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/unpublish_item", + data: "id=" + id, + success: function(){ + $('li#item_' + id).removeClass('publish'); + $('li#item_' + id).addClass('draft'); + } + }); + }); + + //publish button + $('ul.activity_list li.publish_this a').click(function(){ + var id = $(this).parents('li.item').attr('id').replace('item_',''); + $.ajax({ + type: "POST", + url: base_url + "admin/ajax/publish_item", + data: "id=" + id, + success: function(){ + $('li#item_' + id).removeClass('draft'); + $('li#item_' + id).addClass('publish'); + } + }); + }); + + //external links, xhtml friendly + $('a[rel=external]').click(function(){ + //open new window + var myurl = $(this).attr('href'); + window.open(myurl, 'external'); + return false; + }); + + if ($('li.item div.hideshow:parent').length) { + $('li.item div.hideshow:parent').each(function(){ + $(this).parents('li.item').children('ul.item_tools').children('li.expand').css({display: 'inline'}); + }); + } + + $('li.expand a').click(function(){ + $(this).parents('li.item').children('div.item_container').children('div.hideshow').slideToggle(); + if ($(this).parents('li').hasClass('expanded')) { + $(this).parents('li').removeClass('expanded'); + $(this).html('Expand'); + } else { + $(this).parents('li').addClass('expanded'); + $(this).html('Collapse'); + } + }); + +}); \ No newline at end of file diff --git a/public/scripts/jquery.js b/public/scripts/jquery.js new file mode 100644 index 0000000..95dd013 --- /dev/null +++ b/public/scripts/jquery.js @@ -0,0 +1,11 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ + * $Rev: 5685 $ + */ +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(H(){J w=1b.4M,3m$=1b.$;J D=1b.4M=1b.$=H(a,b){I 2B D.17.5j(a,b)};J u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,62=/^.[^:#\\[\\.]*$/,12;D.17=D.44={5j:H(d,b){d=d||S;G(d.16){7[0]=d;7.K=1;I 7}G(1j d=="23"){J c=u.2D(d);G(c&&(c[1]||!b)){G(c[1])d=D.4h([c[1]],b);N{J a=S.61(c[3]);G(a){G(a.2v!=c[3])I D().2q(d);I D(a)}d=[]}}N I D(b).2q(d)}N G(D.1D(d))I D(S)[D.17.27?"27":"43"](d);I 7.6Y(D.2d(d))},5w:"1.2.6",8G:H(){I 7.K},K:0,3p:H(a){I a==12?D.2d(7):7[a]},2I:H(b){J a=D(b);a.5n=7;I a},6Y:H(a){7.K=0;2p.44.1p.1w(7,a);I 7},P:H(a,b){I D.P(7,a,b)},5i:H(b){J a=-1;I D.2L(b&&b.5w?b[0]:b,7)},1K:H(c,a,b){J d=c;G(c.1q==56)G(a===12)I 7[0]&&D[b||"1K"](7[0],c);N{d={};d[c]=a}I 7.P(H(i){R(c 1n d)D.1K(b?7.V:7,c,D.1i(7,d[c],b,i,c))})},1g:H(b,a){G((b==\'2h\'||b==\'1Z\')&&3d(a)<0)a=12;I 7.1K(b,a,"2a")},1r:H(b){G(1j b!="49"&&b!=U)I 7.4E().3v((7[0]&&7[0].2z||S).5F(b));J a="";D.P(b||7,H(){D.P(7.3t,H(){G(7.16!=8)a+=7.16!=1?7.76:D.17.1r([7])})});I a},5z:H(b){G(7[0])D(b,7[0].2z).5y().39(7[0]).2l(H(){J a=7;1B(a.1x)a=a.1x;I a}).3v(7);I 7},8Y:H(a){I 7.P(H(){D(7).6Q().5z(a)})},8R:H(a){I 7.P(H(){D(7).5z(a)})},3v:H(){I 7.3W(19,M,Q,H(a){G(7.16==1)7.3U(a)})},6F:H(){I 7.3W(19,M,M,H(a){G(7.16==1)7.39(a,7.1x)})},6E:H(){I 7.3W(19,Q,Q,H(a){7.1d.39(a,7)})},5q:H(){I 7.3W(19,Q,M,H(a){7.1d.39(a,7.2H)})},3l:H(){I 7.5n||D([])},2q:H(b){J c=D.2l(7,H(a){I D.2q(b,a)});I 7.2I(/[^+>] [^+>]/.11(b)||b.1h("..")>-1?D.4r(c):c)},5y:H(e){J f=7.2l(H(){G(D.14.1f&&!D.4n(7)){J a=7.6o(M),5h=S.3h("1v");5h.3U(a);I D.4h([5h.4H])[0]}N I 7.6o(M)});J d=f.2q("*").5c().P(H(){G(7[E]!=12)7[E]=U});G(e===M)7.2q("*").5c().P(H(i){G(7.16==3)I;J c=D.L(7,"3w");R(J a 1n c)R(J b 1n c[a])D.W.1e(d[i],a,c[a][b],c[a][b].L)});I f},1E:H(b){I 7.2I(D.1D(b)&&D.3C(7,H(a,i){I b.1k(a,i)})||D.3g(b,7))},4Y:H(b){G(b.1q==56)G(62.11(b))I 7.2I(D.3g(b,7,M));N b=D.3g(b,7);J a=b.K&&b[b.K-1]!==12&&!b.16;I 7.1E(H(){I a?D.2L(7,b)<0:7!=b})},1e:H(a){I 7.2I(D.4r(D.2R(7.3p(),1j a==\'23\'?D(a):D.2d(a))))},3F:H(a){I!!a&&D.3g(a,7).K>0},7T:H(a){I 7.3F("."+a)},6e:H(b){G(b==12){G(7.K){J c=7[0];G(D.Y(c,"2A")){J e=c.64,63=[],15=c.15,2V=c.O=="2A-2V";G(e<0)I U;R(J i=2V?e:0,2f=2V?e+1:15.K;i<2f;i++){J d=15[i];G(d.2W){b=D.14.1f&&!d.at.2x.an?d.1r:d.2x;G(2V)I b;63.1p(b)}}I 63}N I(7[0].2x||"").1o(/\\r/g,"")}I 12}G(b.1q==4L)b+=\'\';I 7.P(H(){G(7.16!=1)I;G(b.1q==2p&&/5O|5L/.11(7.O))7.4J=(D.2L(7.2x,b)>=0||D.2L(7.34,b)>=0);N G(D.Y(7,"2A")){J a=D.2d(b);D("9R",7).P(H(){7.2W=(D.2L(7.2x,a)>=0||D.2L(7.1r,a)>=0)});G(!a.K)7.64=-1}N 7.2x=b})},2K:H(a){I a==12?(7[0]?7[0].4H:U):7.4E().3v(a)},7b:H(a){I 7.5q(a).21()},79:H(i){I 7.3s(i,i+1)},3s:H(){I 7.2I(2p.44.3s.1w(7,19))},2l:H(b){I 7.2I(D.2l(7,H(a,i){I b.1k(a,i,a)}))},5c:H(){I 7.1e(7.5n)},L:H(d,b){J a=d.1R(".");a[1]=a[1]?"."+a[1]:"";G(b===12){J c=7.5C("9z"+a[1]+"!",[a[0]]);G(c===12&&7.K)c=D.L(7[0],d);I c===12&&a[1]?7.L(a[0]):c}N I 7.1P("9u"+a[1]+"!",[a[0],b]).P(H(){D.L(7,d,b)})},3b:H(a){I 7.P(H(){D.3b(7,a)})},3W:H(g,f,h,d){J e=7.K>1,3x;I 7.P(H(){G(!3x){3x=D.4h(g,7.2z);G(h)3x.9o()}J b=7;G(f&&D.Y(7,"1T")&&D.Y(3x[0],"4F"))b=7.3H("22")[0]||7.3U(7.2z.3h("22"));J c=D([]);D.P(3x,H(){J a=e?D(7).5y(M)[0]:7;G(D.Y(a,"1m"))c=c.1e(a);N{G(a.16==1)c=c.1e(D("1m",a).21());d.1k(b,a)}});c.P(6T)})}};D.17.5j.44=D.17;H 6T(i,a){G(a.4d)D.3Y({1a:a.4d,31:Q,1O:"1m"});N D.5u(a.1r||a.6O||a.4H||"");G(a.1d)a.1d.37(a)}H 1z(){I+2B 8J}D.1l=D.17.1l=H(){J b=19[0]||{},i=1,K=19.K,4x=Q,15;G(b.1q==8I){4x=b;b=19[1]||{};i=2}G(1j b!="49"&&1j b!="H")b={};G(K==i){b=7;--i}R(;i-1}},6q:H(b,c,a){J e={};R(J d 1n c){e[d]=b.V[d];b.V[d]=c[d]}a.1k(b);R(J d 1n c)b.V[d]=e[d]},1g:H(d,e,c){G(e=="2h"||e=="1Z"){J b,3X={30:"5x",5g:"1G",18:"3I"},35=e=="2h"?["5e","6k"]:["5G","6i"];H 5b(){b=e=="2h"?d.8f:d.8c;J a=0,2C=0;D.P(35,H(){a+=3d(D.2a(d,"57"+7,M))||0;2C+=3d(D.2a(d,"2C"+7+"4b",M))||0});b-=29.83(a+2C)}G(D(d).3F(":4j"))5b();N D.6q(d,3X,5b);I 29.2f(0,b)}I D.2a(d,e,c)},2a:H(f,l,k){J e,V=f.V;H 3E(b){G(!D.14.2k)I Q;J a=3P.54(b,U);I!a||a.52("3E")==""}G(l=="1y"&&D.14.1f){e=D.1K(V,"1y");I e==""?"1":e}G(D.14.2G&&l=="18"){J d=V.50;V.50="0 7Y 7W";V.50=d}G(l.1I(/4i/i))l=y;G(!k&&V&&V[l])e=V[l];N G(3P.54){G(l.1I(/4i/i))l="4i";l=l.1o(/([A-Z])/g,"-$1").3y();J c=3P.54(f,U);G(c&&!3E(f))e=c.52(l);N{J g=[],2E=[],a=f,i=0;R(;a&&3E(a);a=a.1d)2E.6h(a);R(;i<2E.K;i++)G(3E(2E[i])){g[i]=2E[i].V.18;2E[i].V.18="3I"}e=l=="18"&&g[2E.K-1]!=U?"2F":(c&&c.52(l))||"";R(i=0;i]*?)\\/>/g,H(b,a,c){I c.1I(/^(aK|4f|7E|aG|4T|7A|aB|3n|az|ay|av)$/i)?b:a+">"});J f=D.3k(d).3y(),1v=h.3h("1v");J e=!f.1h("",""]||!f.1h("",""]||f.1I(/^<(aq|22|am|ak|ai)/)&&[1,"<1T>",""]||!f.1h("<4F")&&[2,"<1T><22>",""]||(!f.1h("<22><4F>",""]||!f.1h("<7E")&&[2,"<1T><22><7q>",""]||D.14.1f&&[1,"1v<1v>",""]||[0,"",""];1v.4H=e[1]+d+e[2];1B(e[0]--)1v=1v.5T;G(D.14.1f){J g=!f.1h("<1T")&&f.1h("<22")<0?1v.1x&&1v.1x.3t:e[1]=="<1T>"&&f.1h("<22")<0?1v.3t:[];R(J j=g.K-1;j>=0;--j)G(D.Y(g[j],"22")&&!g[j].3t.K)g[j].1d.37(g[j]);G(/^\\s/.11(d))1v.39(h.5F(d.1I(/^\\s*/)[0]),1v.1x)}d=D.2d(1v.3t)}G(d.K===0&&(!D.Y(d,"3V")&&!D.Y(d,"2A")))I;G(d[0]==12||D.Y(d,"3V")||d.15)k.1p(d);N k=D.2R(k,d)});I k},1K:H(d,f,c){G(!d||d.16==3||d.16==8)I 12;J e=!D.4n(d),40=c!==12,1f=D.14.1f;f=e&&D.3X[f]||f;G(d.2j){J g=/5Q|4d|V/.11(f);G(f=="2W"&&D.14.2k)d.1d.64;G(f 1n d&&e&&!g){G(40){G(f=="O"&&D.Y(d,"4T")&&d.1d)7p"O a3 a1\'t 9V 9U";d[f]=c}G(D.Y(d,"3V")&&d.7i(f))I d.7i(f).76;I d[f]}G(1f&&e&&f=="V")I D.1K(d.V,"9T",c);G(40)d.9Q(f,""+c);J h=1f&&e&&g?d.4G(f,2):d.4G(f);I h===U?12:h}G(1f&&f=="1y"){G(40){d.6B=1;d.1E=(d.1E||"").1o(/7f\\([^)]*\\)/,"")+(3r(c)+\'\'=="9L"?"":"7f(1y="+c*7a+")")}I d.1E&&d.1E.1h("1y=")>=0?(3d(d.1E.1I(/1y=([^)]*)/)[1])/7a)+\'\':""}f=f.1o(/-([a-z])/9H,H(a,b){I b.2r()});G(40)d[f]=c;I d[f]},3k:H(a){I(a||"").1o(/^\\s+|\\s+$/g,"")},2d:H(b){J a=[];G(b!=U){J i=b.K;G(i==U||b.1R||b.4I||b.1k)a[0]=b;N 1B(i)a[--i]=b[i]}I a},2L:H(b,a){R(J i=0,K=a.K;i*",7).21();1B(7.1x)7.37(7.1x)}},H(a,b){D.17[a]=H(){I 7.P(b,19)}});D.P(["6N","4b"],H(i,c){J b=c.3y();D.17[b]=H(a){I 7[0]==1b?D.14.2G&&S.1c["5t"+c]||D.14.2k&&1b["5s"+c]||S.70=="6Z"&&S.1C["5t"+c]||S.1c["5t"+c]:7[0]==S?29.2f(29.2f(S.1c["4y"+c],S.1C["4y"+c]),29.2f(S.1c["2i"+c],S.1C["2i"+c])):a==12?(7.K?D.1g(7[0],b):U):7.1g(b,a.1q==56?a:a+"2X")}});H 25(a,b){I a[0]&&3r(D.2a(a[0],b,M),10)||0}J C=D.14.2k&&3r(D.14.5B)<8H?"(?:[\\\\w*3m-]|\\\\\\\\.)":"(?:[\\\\w\\8F-\\8E*3m-]|\\\\\\\\.)",6L=2B 4v("^>\\\\s*("+C+"+)"),6J=2B 4v("^("+C+"+)(#)("+C+"+)"),6I=2B 4v("^([#.]?)("+C+"*)");D.1l({6H:{"":H(a,i,m){I m[2]=="*"||D.Y(a,m[2])},"#":H(a,i,m){I a.4G("2v")==m[2]},":":{8D:H(a,i,m){I im[3]-0},3a:H(a,i,m){I m[3]-0==i},79:H(a,i,m){I m[3]-0==i},3o:H(a,i){I i==0},3S:H(a,i,m,r){I i==r.K-1},6D:H(a,i){I i%2==0},6C:H(a,i){I i%2},"3o-4u":H(a){I a.1d.3H("*")[0]==a},"3S-4u":H(a){I D.3a(a.1d.5T,1,"4l")==a},"8z-4u":H(a){I!D.3a(a.1d.5T,2,"4l")},6W:H(a){I a.1x},4E:H(a){I!a.1x},8y:H(a,i,m){I(a.6O||a.8x||D(a).1r()||"").1h(m[3])>=0},4j:H(a){I"1G"!=a.O&&D.1g(a,"18")!="2F"&&D.1g(a,"5g")!="1G"},1G:H(a){I"1G"==a.O||D.1g(a,"18")=="2F"||D.1g(a,"5g")=="1G"},8w:H(a){I!a.3R},3R:H(a){I a.3R},4J:H(a){I a.4J},2W:H(a){I a.2W||D.1K(a,"2W")},1r:H(a){I"1r"==a.O},5O:H(a){I"5O"==a.O},5L:H(a){I"5L"==a.O},5p:H(a){I"5p"==a.O},3Q:H(a){I"3Q"==a.O},5o:H(a){I"5o"==a.O},6A:H(a){I"6A"==a.O},6z:H(a){I"6z"==a.O},2s:H(a){I"2s"==a.O||D.Y(a,"2s")},4T:H(a){I/4T|2A|6y|2s/i.11(a.Y)},3T:H(a,i,m){I D.2q(m[3],a).K},8t:H(a){I/h\\d/i.11(a.Y)},8s:H(a){I D.3C(D.3O,H(b){I a==b.T}).K}}},6x:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2B 4v("^([:.#]*)("+C+"+)")],3g:H(a,c,b){J d,1t=[];1B(a&&a!=d){d=a;J f=D.1E(a,c,b);a=f.t.1o(/^\\s*,\\s*/,"");1t=b?c=f.r:D.2R(1t,f.r)}I 1t},2q:H(t,o){G(1j t!="23")I[t];G(o&&o.16!=1&&o.16!=9)I[];o=o||S;J d=[o],2o=[],3S,Y;1B(t&&3S!=t){J r=[];3S=t;t=D.3k(t);J l=Q,3j=6L,m=3j.2D(t);G(m){Y=m[1].2r();R(J i=0;d[i];i++)R(J c=d[i].1x;c;c=c.2H)G(c.16==1&&(Y=="*"||c.Y.2r()==Y))r.1p(c);d=r;t=t.1o(3j,"");G(t.1h(" ")==0)6M;l=M}N{3j=/^([>+~])\\s*(\\w*)/i;G((m=3j.2D(t))!=U){r=[];J k={};Y=m[2].2r();m=m[1];R(J j=0,3i=d.K;j<3i;j++){J n=m=="~"||m=="+"?d[j].2H:d[j].1x;R(;n;n=n.2H)G(n.16==1){J g=D.L(n);G(m=="~"&&k[g])1X;G(!Y||n.Y.2r()==Y){G(m=="~")k[g]=M;r.1p(n)}G(m=="+")1X}}d=r;t=D.3k(t.1o(3j,""));l=M}}G(t&&!l){G(!t.1h(",")){G(o==d[0])d.4s();2o=D.2R(2o,d);r=d=[o];t=" "+t.6v(1,t.K)}N{J h=6J;J m=h.2D(t);G(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2D(t)}m[2]=m[2].1o(/\\\\/g,"");J f=d[d.K-1];G(m[1]=="#"&&f&&f.61&&!D.4n(f)){J p=f.61(m[2]);G((D.14.1f||D.14.2G)&&p&&1j p.2v=="23"&&p.2v!=m[2])p=D(\'[@2v="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.Y(p,m[3]))?[p]:[]}N{R(J i=0;d[i];i++){J a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];G(a=="*"&&d[i].Y.3y()=="49")a="3n";r=D.2R(r,d[i].3H(a))}G(m[1]==".")r=D.5m(r,m[2]);G(m[1]=="#"){J e=[];R(J i=0;r[i];i++)G(r[i].4G("2v")==m[2]){e=[r[i]];1X}r=e}d=r}t=t.1o(h,"")}}G(t){J b=D.1E(t,r);d=r=b.r;t=D.3k(b.t)}}G(t)d=[];G(d&&o==d[0])d.4s();2o=D.2R(2o,d);I 2o},5m:H(r,m,a){m=" "+m+" ";J c=[];R(J i=0;r[i];i++){J b=(" "+r[i].1F+" ").1h(m)>=0;G(!a&&b||a&&!b)c.1p(r[i])}I c},1E:H(t,r,h){J d;1B(t&&t!=d){d=t;J p=D.6x,m;R(J i=0;p[i];i++){m=p[i].2D(t);G(m){t=t.8r(m[0].K);m[2]=m[2].1o(/\\\\/g,"");1X}}G(!m)1X;G(m[1]==":"&&m[2]=="4Y")r=62.11(m[3])?D.1E(m[3],r,M).r:D(r).4Y(m[3]);N G(m[1]==".")r=D.5m(r,m[2],h);N G(m[1]=="["){J g=[],O=m[3];R(J i=0,3i=r.K;i<3i;i++){J a=r[i],z=a[D.3X[m[2]]||m[2]];G(z==U||/5Q|4d|2W/.11(m[2]))z=D.1K(a,m[2])||\'\';G((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1h(m[5])||O=="$="&&z.6v(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1h(m[5])>=0)^h)g.1p(a)}r=g}N G(m[1]==":"&&m[2]=="3a-4u"){J e={},g=[],11=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2D(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.11(m[3])&&"8q+"+m[3]||m[3]),3o=(11[1]+(11[2]||1))-0,d=11[3]-0;R(J i=0,3i=r.K;i<3i;i++){J j=r[i],1d=j.1d,2v=D.L(1d);G(!e[2v]){J c=1;R(J n=1d.1x;n;n=n.2H)G(n.16==1)n.4q=c++;e[2v]=M}J b=Q;G(3o==0){G(j.4q==d)b=M}N G((j.4q-d)%3o==0&&(j.4q-d)/3o>=0)b=M;G(b^h)g.1p(j)}r=g}N{J f=D.6H[m[1]];G(1j f=="49")f=f[m[2]];G(1j f=="23")f=6u("Q||H(a,i){I "+f+";}");r=D.3C(r,H(a,i){I f(a,i,m,r)},h)}}I{r:r,t:t}},4S:H(b,c){J a=[],1t=b[c];1B(1t&&1t!=S){G(1t.16==1)a.1p(1t);1t=1t[c]}I a},3a:H(a,e,c,b){e=e||1;J d=0;R(;a;a=a[c])G(a.16==1&&++d==e)1X;I a},5v:H(n,a){J r=[];R(;n;n=n.2H){G(n.16==1&&n!=a)r.1p(n)}I r}});D.W={1e:H(f,i,g,e){G(f.16==3||f.16==8)I;G(D.14.1f&&f.4I)f=1b;G(!g.24)g.24=7.24++;G(e!=12){J h=g;g=7.3M(h,H(){I h.1w(7,19)});g.L=e}J j=D.L(f,"3w")||D.L(f,"3w",{}),1H=D.L(f,"1H")||D.L(f,"1H",H(){G(1j D!="12"&&!D.W.5k)I D.W.1H.1w(19.3L.T,19)});1H.T=f;D.P(i.1R(/\\s+/),H(c,b){J a=b.1R(".");b=a[0];g.O=a[1];J d=j[b];G(!d){d=j[b]={};G(!D.W.2t[b]||D.W.2t[b].4p.1k(f)===Q){G(f.3K)f.3K(b,1H,Q);N G(f.6t)f.6t("4o"+b,1H)}}d[g.24]=g;D.W.26[b]=M});f=U},24:1,26:{},21:H(e,h,f){G(e.16==3||e.16==8)I;J i=D.L(e,"3w"),1L,5i;G(i){G(h==12||(1j h=="23"&&h.8p(0)=="."))R(J g 1n i)7.21(e,g+(h||""));N{G(h.O){f=h.2y;h=h.O}D.P(h.1R(/\\s+/),H(b,a){J c=a.1R(".");a=c[0];G(i[a]){G(f)2U i[a][f.24];N R(f 1n i[a])G(!c[1]||i[a][f].O==c[1])2U i[a][f];R(1L 1n i[a])1X;G(!1L){G(!D.W.2t[a]||D.W.2t[a].4A.1k(e)===Q){G(e.6p)e.6p(a,D.L(e,"1H"),Q);N G(e.6n)e.6n("4o"+a,D.L(e,"1H"))}1L=U;2U i[a]}}})}R(1L 1n i)1X;G(!1L){J d=D.L(e,"1H");G(d)d.T=U;D.3b(e,"3w");D.3b(e,"1H")}}},1P:H(h,c,f,g,i){c=D.2d(c);G(h.1h("!")>=0){h=h.3s(0,-1);J a=M}G(!f){G(7.26[h])D("*").1e([1b,S]).1P(h,c)}N{G(f.16==3||f.16==8)I 12;J b,1L,17=D.1D(f[h]||U),W=!c[0]||!c[0].32;G(W){c.6h({O:h,2J:f,32:H(){},3J:H(){},4C:1z()});c[0][E]=M}c[0].O=h;G(a)c[0].6m=M;J d=D.L(f,"1H");G(d)b=d.1w(f,c);G((!17||(D.Y(f,\'a\')&&h=="4V"))&&f["4o"+h]&&f["4o"+h].1w(f,c)===Q)b=Q;G(W)c.4s();G(i&&D.1D(i)){1L=i.1w(f,b==U?c:c.7d(b));G(1L!==12)b=1L}G(17&&g!==Q&&b!==Q&&!(D.Y(f,\'a\')&&h=="4V")){7.5k=M;1U{f[h]()}1V(e){}}7.5k=Q}I b},1H:H(b){J a,1L,38,5f,4m;b=19[0]=D.W.6l(b||1b.W);38=b.O.1R(".");b.O=38[0];38=38[1];5f=!38&&!b.6m;4m=(D.L(7,"3w")||{})[b.O];R(J j 1n 4m){J c=4m[j];G(5f||c.O==38){b.2y=c;b.L=c.L;1L=c.1w(7,19);G(a!==Q)a=1L;G(1L===Q){b.32();b.3J()}}}I a},6l:H(b){G(b[E]==M)I b;J d=b;b={8o:d};J c="8n 8m 8l 8k 2s 8j 47 5d 6j 5E 8i L 8h 8g 4K 2y 5a 59 8e 8b 58 6f 8a 88 4k 87 86 84 6d 2J 4C 6c O 82 81 35".1R(" ");R(J i=c.K;i;i--)b[c[i]]=d[c[i]];b[E]=M;b.32=H(){G(d.32)d.32();d.80=Q};b.3J=H(){G(d.3J)d.3J();d.7Z=M};b.4C=b.4C||1z();G(!b.2J)b.2J=b.6d||S;G(b.2J.16==3)b.2J=b.2J.1d;G(!b.4k&&b.4K)b.4k=b.4K==b.2J?b.6c:b.4K;G(b.58==U&&b.5d!=U){J a=S.1C,1c=S.1c;b.58=b.5d+(a&&a.2e||1c&&1c.2e||0)-(a.6b||0);b.6f=b.6j+(a&&a.2c||1c&&1c.2c||0)-(a.6a||0)}G(!b.35&&((b.47||b.47===0)?b.47:b.5a))b.35=b.47||b.5a;G(!b.59&&b.5E)b.59=b.5E;G(!b.35&&b.2s)b.35=(b.2s&1?1:(b.2s&2?3:(b.2s&4?2:0)));I b},3M:H(a,b){b.24=a.24=a.24||b.24||7.24++;I b},2t:{27:{4p:H(){55();I},4A:H(){I}},3D:{4p:H(){G(D.14.1f)I Q;D(7).2O("53",D.W.2t.3D.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("53",D.W.2t.3D.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3D";I D.W.1H.1w(7,19)}},3N:{4p:H(){G(D.14.1f)I Q;D(7).2O("51",D.W.2t.3N.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("51",D.W.2t.3N.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3N";I D.W.1H.1w(7,19)}}}};D.17.1l({2O:H(c,a,b){I c=="4X"?7.2V(c,a,b):7.P(H(){D.W.1e(7,c,b||a,b&&a)})},2V:H(d,b,c){J e=D.W.3M(c||b,H(a){D(7).4e(a,e);I(c||b).1w(7,19)});I 7.P(H(){D.W.1e(7,d,e,c&&b)})},4e:H(a,b){I 7.P(H(){D.W.21(7,a,b)})},1P:H(c,a,b){I 7.P(H(){D.W.1P(c,a,7,M,b)})},5C:H(c,a,b){I 7[0]&&D.W.1P(c,a,7[0],Q,b)},2m:H(b){J c=19,i=1;1B(i=0){J i=g.3s(e,g.K);g=g.3s(0,e)}c=c||H(){};J f="2P";G(d)G(D.1D(d)){c=d;d=U}N{d=D.3n(d);f="6g"}J h=7;D.3Y({1a:g,O:f,1O:"2K",L:d,1J:H(a,b){G(b=="1W"||b=="7J")h.2K(i?D("<1v/>").3v(a.4U.1o(/<1m(.|\\s)*?\\/1m>/g,"")).2q(i):a.4U);h.P(c,[a.4U,b,a])}});I 7},aL:H(){I D.3n(7.7I())},7I:H(){I 7.2l(H(){I D.Y(7,"3V")?D.2d(7.aH):7}).1E(H(){I 7.34&&!7.3R&&(7.4J||/2A|6y/i.11(7.Y)||/1r|1G|3Q/i.11(7.O))}).2l(H(i,c){J b=D(7).6e();I b==U?U:b.1q==2p?D.2l(b,H(a,i){I{34:c.34,2x:a}}):{34:c.34,2x:b}}).3p()}});D.P("7H,7G,7F,7D,7C,7B".1R(","),H(i,o){D.17[o]=H(f){I 7.2O(o,f)}});J B=1z();D.1l({3p:H(d,b,a,c){G(D.1D(b)){a=b;b=U}I D.3Y({O:"2P",1a:d,L:b,1W:a,1O:c})},aE:H(b,a){I D.3p(b,U,a,"1m")},aD:H(c,b,a){I D.3p(c,b,a,"3z")},aC:H(d,b,a,c){G(D.1D(b)){a=b;b={}}I D.3Y({O:"6g",1a:d,L:b,1W:a,1O:c})},aA:H(a){D.1l(D.60,a)},60:{1a:5Z.5Q,26:M,O:"2P",2T:0,7z:"4R/x-ax-3V-aw",7x:M,31:M,L:U,5Y:U,3Q:U,4Q:{2N:"4R/2N, 1r/2N",2K:"1r/2K",1m:"1r/4t, 4R/4t",3z:"4R/3z, 1r/4t",1r:"1r/as",4w:"*/*"}},4z:{},3Y:H(s){s=D.1l(M,s,D.1l(M,{},D.60,s));J g,2Z=/=\\?(&|$)/g,1u,L,O=s.O.2r();G(s.L&&s.7x&&1j s.L!="23")s.L=D.3n(s.L);G(s.1O=="4P"){G(O=="2P"){G(!s.1a.1I(2Z))s.1a+=(s.1a.1I(/\\?/)?"&":"?")+(s.4P||"7u")+"=?"}N G(!s.L||!s.L.1I(2Z))s.L=(s.L?s.L+"&":"")+(s.4P||"7u")+"=?";s.1O="3z"}G(s.1O=="3z"&&(s.L&&s.L.1I(2Z)||s.1a.1I(2Z))){g="4P"+B++;G(s.L)s.L=(s.L+"").1o(2Z,"="+g+"$1");s.1a=s.1a.1o(2Z,"="+g+"$1");s.1O="1m";1b[g]=H(a){L=a;1W();1J();1b[g]=12;1U{2U 1b[g]}1V(e){}G(i)i.37(h)}}G(s.1O=="1m"&&s.1Y==U)s.1Y=Q;G(s.1Y===Q&&O=="2P"){J j=1z();J k=s.1a.1o(/(\\?|&)3m=.*?(&|$)/,"$ap="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1I(/\\?/)?"&":"?")+"3m="+j:"")}G(s.L&&O=="2P"){s.1a+=(s.1a.1I(/\\?/)?"&":"?")+s.L;s.L=U}G(s.26&&!D.4O++)D.W.1P("7H");J n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;G(s.1O=="1m"&&O=="2P"&&n.11(s.1a)&&n.2D(s.1a)[1]!=5Z.al){J i=S.3H("6w")[0];J h=S.3h("1m");h.4d=s.1a;G(s.7t)h.aj=s.7t;G(!g){J l=Q;h.ah=h.ag=H(){G(!l&&(!7.3f||7.3f=="68"||7.3f=="1J")){l=M;1W();1J();i.37(h)}}}i.3U(h);I 12}J m=Q;J c=1b.7s?2B 7s("ae.ac"):2B 7r();G(s.5Y)c.6R(O,s.1a,s.31,s.5Y,s.3Q);N c.6R(O,s.1a,s.31);1U{G(s.L)c.4B("ab-aa",s.7z);G(s.5S)c.4B("a9-5R-a8",D.4z[s.1a]||"a7, a6 a5 a4 5N:5N:5N a2");c.4B("X-9Z-9Y","7r");c.4B("9W",s.1O&&s.4Q[s.1O]?s.4Q[s.1O]+", */*":s.4Q.4w)}1V(e){}G(s.7m&&s.7m(c,s)===Q){s.26&&D.4O--;c.7l();I Q}G(s.26)D.W.1P("7B",[c,s]);J d=H(a){G(!m&&c&&(c.3f==4||a=="2T")){m=M;G(f){7k(f);f=U}1u=a=="2T"&&"2T"||!D.7j(c)&&"3e"||s.5S&&D.7h(c,s.1a)&&"7J"||"1W";G(1u=="1W"){1U{L=D.6X(c,s.1O,s.9S)}1V(e){1u="5J"}}G(1u=="1W"){J b;1U{b=c.5I("7g-5R")}1V(e){}G(s.5S&&b)D.4z[s.1a]=b;G(!g)1W()}N D.5H(s,c,1u);1J();G(s.31)c=U}};G(s.31){J f=4I(d,13);G(s.2T>0)3B(H(){G(c){c.7l();G(!m)d("2T")}},s.2T)}1U{c.9P(s.L)}1V(e){D.5H(s,c,U,e)}G(!s.31)d();H 1W(){G(s.1W)s.1W(L,1u);G(s.26)D.W.1P("7C",[c,s])}H 1J(){G(s.1J)s.1J(c,1u);G(s.26)D.W.1P("7F",[c,s]);G(s.26&&!--D.4O)D.W.1P("7G")}I c},5H:H(s,a,b,e){G(s.3e)s.3e(a,b,e);G(s.26)D.W.1P("7D",[a,s,e])},4O:0,7j:H(a){1U{I!a.1u&&5Z.9O=="5p:"||(a.1u>=7e&&a.1u<9N)||a.1u==7c||a.1u==9K||D.14.2k&&a.1u==12}1V(e){}I Q},7h:H(a,c){1U{J b=a.5I("7g-5R");I a.1u==7c||b==D.4z[c]||D.14.2k&&a.1u==12}1V(e){}I Q},6X:H(a,c,b){J d=a.5I("9J-O"),2N=c=="2N"||!c&&d&&d.1h("2N")>=0,L=2N?a.9I:a.4U;G(2N&&L.1C.2j=="5J")7p"5J";G(b)L=b(L,c);G(c=="1m")D.5u(L);G(c=="3z")L=6u("("+L+")");I L},3n:H(a){J s=[];G(a.1q==2p||a.5w)D.P(a,H(){s.1p(3u(7.34)+"="+3u(7.2x))});N R(J j 1n a)G(a[j]&&a[j].1q==2p)D.P(a[j],H(){s.1p(3u(j)+"="+3u(7))});N s.1p(3u(j)+"="+3u(D.1D(a[j])?a[j]():a[j]));I s.6s("&").1o(/%20/g,"+")}});D.17.1l({1N:H(c,b){I c?7.2g({1Z:"1N",2h:"1N",1y:"1N"},c,b):7.1E(":1G").P(H(){7.V.18=7.5D||"";G(D.1g(7,"18")=="2F"){J a=D("<"+7.2j+" />").6P("1c");7.V.18=a.1g("18");G(7.V.18=="2F")7.V.18="3I";a.21()}}).3l()},1M:H(b,a){I b?7.2g({1Z:"1M",2h:"1M",1y:"1M"},b,a):7.1E(":4j").P(H(){7.5D=7.5D||D.1g(7,"18");7.V.18="2F"}).3l()},78:D.17.2m,2m:H(a,b){I D.1D(a)&&D.1D(b)?7.78.1w(7,19):a?7.2g({1Z:"2m",2h:"2m",1y:"2m"},a,b):7.P(H(){D(7)[D(7).3F(":1G")?"1N":"1M"]()})},9G:H(b,a){I 7.2g({1Z:"1N"},b,a)},9F:H(b,a){I 7.2g({1Z:"1M"},b,a)},9E:H(b,a){I 7.2g({1Z:"2m"},b,a)},9D:H(b,a){I 7.2g({1y:"1N"},b,a)},9M:H(b,a){I 7.2g({1y:"1M"},b,a)},9C:H(c,a,b){I 7.2g({1y:a},c,b)},2g:H(k,j,i,g){J h=D.77(j,i,g);I 7[h.36===Q?"P":"36"](H(){G(7.16!=1)I Q;J f=D.1l({},h),p,1G=D(7).3F(":1G"),46=7;R(p 1n k){G(k[p]=="1M"&&1G||k[p]=="1N"&&!1G)I f.1J.1k(7);G(p=="1Z"||p=="2h"){f.18=D.1g(7,"18");f.33=7.V.33}}G(f.33!=U)7.V.33="1G";f.45=D.1l({},k);D.P(k,H(c,a){J e=2B D.28(46,f,c);G(/2m|1N|1M/.11(a))e[a=="2m"?1G?"1N":"1M":a](k);N{J b=a.6r().1I(/^([+-]=)?([\\d+-.]+)(.*)$/),2b=e.1t(M)||0;G(b){J d=3d(b[2]),2M=b[3]||"2X";G(2M!="2X"){46.V[c]=(d||1)+2M;2b=((d||1)/e.1t(M))*2b;46.V[c]=2b+2M}G(b[1])d=((b[1]=="-="?-1:1)*d)+2b;e.3G(2b,d,2M)}N e.3G(2b,a,"")}});I M})},36:H(a,b){G(D.1D(a)||(a&&a.1q==2p)){b=a;a="28"}G(!a||(1j a=="23"&&!b))I A(7[0],a);I 7.P(H(){G(b.1q==2p)A(7,a,b);N{A(7,a).1p(b);G(A(7,a).K==1)b.1k(7)}})},9X:H(b,c){J a=D.3O;G(b)7.36([]);7.P(H(){R(J i=a.K-1;i>=0;i--)G(a[i].T==7){G(c)a[i](M);a.7n(i,1)}});G(!c)7.5A();I 7}});J A=H(b,c,a){G(b){c=c||"28";J q=D.L(b,c+"36");G(!q||a)q=D.L(b,c+"36",D.2d(a))}I q};D.17.5A=H(a){a=a||"28";I 7.P(H(){J q=A(7,a);q.4s();G(q.K)q[0].1k(7)})};D.1l({77:H(b,a,c){J d=b&&b.1q==a0?b:{1J:c||!c&&a||D.1D(b)&&b,2u:b,41:c&&a||a&&a.1q!=9t&&a};d.2u=(d.2u&&d.2u.1q==4L?d.2u:D.28.5K[d.2u])||D.28.5K.74;d.5M=d.1J;d.1J=H(){G(d.36!==Q)D(7).5A();G(D.1D(d.5M))d.5M.1k(7)};I d},41:{73:H(p,n,b,a){I b+a*p},5P:H(p,n,b,a){I((-29.9r(p*29.9q)/2)+0.5)*a+b}},3O:[],48:U,28:H(b,c,a){7.15=c;7.T=b;7.1i=a;G(!c.3Z)c.3Z={}}});D.28.44={4D:H(){G(7.15.2Y)7.15.2Y.1k(7.T,7.1z,7);(D.28.2Y[7.1i]||D.28.2Y.4w)(7);G(7.1i=="1Z"||7.1i=="2h")7.T.V.18="3I"},1t:H(a){G(7.T[7.1i]!=U&&7.T.V[7.1i]==U)I 7.T[7.1i];J r=3d(D.1g(7.T,7.1i,a));I r&&r>-9p?r:3d(D.2a(7.T,7.1i))||0},3G:H(c,b,d){7.5V=1z();7.2b=c;7.3l=b;7.2M=d||7.2M||"2X";7.1z=7.2b;7.2S=7.4N=0;7.4D();J e=7;H t(a){I e.2Y(a)}t.T=7.T;D.3O.1p(t);G(D.48==U){D.48=4I(H(){J a=D.3O;R(J i=0;i7.15.2u+7.5V){7.1z=7.3l;7.2S=7.4N=1;7.4D();7.15.45[7.1i]=M;J b=M;R(J i 1n 7.15.45)G(7.15.45[i]!==M)b=Q;G(b){G(7.15.18!=U){7.T.V.33=7.15.33;7.T.V.18=7.15.18;G(D.1g(7.T,"18")=="2F")7.T.V.18="3I"}G(7.15.1M)7.T.V.18="2F";G(7.15.1M||7.15.1N)R(J p 1n 7.15.45)D.1K(7.T.V,p,7.15.3Z[p])}G(b)7.15.1J.1k(7.T);I Q}N{J n=t-7.5V;7.4N=n/7.15.2u;7.2S=D.41[7.15.41||(D.41.5P?"5P":"73")](7.4N,n,0,1,7.15.2u);7.1z=7.2b+((7.3l-7.2b)*7.2S);7.4D()}I M}};D.1l(D.28,{5K:{9l:9j,9i:7e,74:9g},2Y:{2e:H(a){a.T.2e=a.1z},2c:H(a){a.T.2c=a.1z},1y:H(a){D.1K(a.T.V,"1y",a.1z)},4w:H(a){a.T.V[a.1i]=a.1z+a.2M}}});D.17.2i=H(){J b=0,1S=0,T=7[0],3q;G(T)ao(D.14){J d=T.1d,4a=T,1s=T.1s,1Q=T.2z,5U=2k&&3r(5B)<9c&&!/9a/i.11(v),1g=D.2a,3c=1g(T,"30")=="3c";G(T.7y){J c=T.7y();1e(c.1A+29.2f(1Q.1C.2e,1Q.1c.2e),c.1S+29.2f(1Q.1C.2c,1Q.1c.2c));1e(-1Q.1C.6b,-1Q.1C.6a)}N{1e(T.5X,T.5W);1B(1s){1e(1s.5X,1s.5W);G(42&&!/^t(98|d|h)$/i.11(1s.2j)||2k&&!5U)2C(1s);G(!3c&&1g(1s,"30")=="3c")3c=M;4a=/^1c$/i.11(1s.2j)?4a:1s;1s=1s.1s}1B(d&&d.2j&&!/^1c|2K$/i.11(d.2j)){G(!/^96|1T.*$/i.11(1g(d,"18")))1e(-d.2e,-d.2c);G(42&&1g(d,"33")!="4j")2C(d);d=d.1d}G((5U&&(3c||1g(4a,"30")=="5x"))||(42&&1g(4a,"30")!="5x"))1e(-1Q.1c.5X,-1Q.1c.5W);G(3c)1e(29.2f(1Q.1C.2e,1Q.1c.2e),29.2f(1Q.1C.2c,1Q.1c.2c))}3q={1S:1S,1A:b}}H 2C(a){1e(D.2a(a,"6V",M),D.2a(a,"6U",M))}H 1e(l,t){b+=3r(l,10)||0;1S+=3r(t,10)||0}I 3q};D.17.1l({30:H(){J a=0,1S=0,3q;G(7[0]){J b=7.1s(),2i=7.2i(),4c=/^1c|2K$/i.11(b[0].2j)?{1S:0,1A:0}:b.2i();2i.1S-=25(7,\'94\');2i.1A-=25(7,\'aF\');4c.1S+=25(b,\'6U\');4c.1A+=25(b,\'6V\');3q={1S:2i.1S-4c.1S,1A:2i.1A-4c.1A}}I 3q},1s:H(){J a=7[0].1s;1B(a&&(!/^1c|2K$/i.11(a.2j)&&D.1g(a,\'30\')==\'93\'))a=a.1s;I D(a)}});D.P([\'5e\',\'5G\'],H(i,b){J c=\'4y\'+b;D.17[c]=H(a){G(!7[0])I;I a!=12?7.P(H(){7==1b||7==S?1b.92(!i?a:D(1b).2e(),i?a:D(1b).2c()):7[c]=a}):7[0]==1b||7[0]==S?46[i?\'aI\':\'aJ\']||D.71&&S.1C[c]||S.1c[c]:7[0][c]}});D.P(["6N","4b"],H(i,b){J c=i?"5e":"5G",4f=i?"6k":"6i";D.17["5s"+b]=H(){I 7[b.3y()]()+25(7,"57"+c)+25(7,"57"+4f)};D.17["90"+b]=H(a){I 7["5s"+b]()+25(7,"2C"+c+"4b")+25(7,"2C"+4f+"4b")+(a?25(7,"6S"+c)+25(7,"6S"+4f):0)}})})();',62,669,'|||||||this|||||||||||||||||||||||||||||||||||if|function|return|var|length|data|true|else|type|each|false|for|document|elem|null|style|event||nodeName|||test|undefined||browser|options|nodeType|fn|display|arguments|url|window|body|parentNode|add|msie|css|indexOf|prop|typeof|call|extend|script|in|replace|push|constructor|text|offsetParent|cur|status|div|apply|firstChild|opacity|now|left|while|documentElement|isFunction|filter|className|hidden|handle|match|complete|attr|ret|hide|show|dataType|trigger|doc|split|top|table|try|catch|success|break|cache|height||remove|tbody|string|guid|num|global|ready|fx|Math|curCSS|start|scrollTop|makeArray|scrollLeft|max|animate|width|offset|tagName|safari|map|toggle||done|Array|find|toUpperCase|button|special|duration|id|copy|value|handler|ownerDocument|select|new|border|exec|stack|none|opera|nextSibling|pushStack|target|html|inArray|unit|xml|bind|GET|isReady|merge|pos|timeout|delete|one|selected|px|step|jsre|position|async|preventDefault|overflow|name|which|queue|removeChild|namespace|insertBefore|nth|removeData|fixed|parseFloat|error|readyState|multiFilter|createElement|rl|re|trim|end|_|param|first|get|results|parseInt|slice|childNodes|encodeURIComponent|append|events|elems|toLowerCase|json|readyList|setTimeout|grep|mouseenter|color|is|custom|getElementsByTagName|block|stopPropagation|addEventListener|callee|proxy|mouseleave|timers|defaultView|password|disabled|last|has|appendChild|form|domManip|props|ajax|orig|set|easing|mozilla|load|prototype|curAnim|self|charCode|timerId|object|offsetChild|Width|parentOffset|src|unbind|br|currentStyle|clean|float|visible|relatedTarget|previousSibling|handlers|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|child|RegExp|_default|deep|scroll|lastModified|teardown|setRequestHeader|timeStamp|update|empty|tr|getAttribute|innerHTML|setInterval|checked|fromElement|Number|jQuery|state|active|jsonp|accepts|application|dir|input|responseText|click|styleSheets|unload|not|lastToggle|outline|mouseout|getPropertyValue|mouseover|getComputedStyle|bindReady|String|padding|pageX|metaKey|keyCode|getWH|andSelf|clientX|Left|all|visibility|container|index|init|triggered|removeAttribute|classFilter|prevObject|submit|file|after|windowData|inner|client|globalEval|sibling|jquery|absolute|clone|wrapAll|dequeue|version|triggerHandler|oldblock|ctrlKey|createTextNode|Top|handleError|getResponseHeader|parsererror|speeds|checkbox|old|00|radio|swing|href|Modified|ifModified|lastChild|safari2|startTime|offsetTop|offsetLeft|username|location|ajaxSettings|getElementById|isSimple|values|selectedIndex|runtimeStyle|rsLeft|_load|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|val|pageY|POST|unshift|Bottom|clientY|Right|fix|exclusive|detachEvent|cloneNode|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|image|zoom|odd|even|before|prepend|exclude|expr|quickClass|quickID|uuid|quickChild|continue|Height|textContent|appendTo|contents|open|margin|evalScript|borderTopWidth|borderLeftWidth|parent|httpData|setArray|CSS1Compat|compatMode|boxModel|cssFloat|linear|def|webkit|nodeValue|speed|_toggle|eq|100|replaceWith|304|concat|200|alpha|Last|httpNotModified|getAttributeNode|httpSuccess|clearInterval|abort|beforeSend|splice|styleFloat|throw|colgroup|XMLHttpRequest|ActiveXObject|scriptCharset|callback|fieldset|multiple|processData|getBoundingClientRect|contentType|link|ajaxSend|ajaxSuccess|ajaxError|col|ajaxComplete|ajaxStop|ajaxStart|serializeArray|notmodified|keypress|keydown|change|mouseup|mousedown|dblclick|focus|blur|stylesheet|hasClass|rel|doScroll|black|hover|solid|cancelBubble|returnValue|wheelDelta|view|round|shiftKey|resize|screenY|screenX|relatedNode|mousemove|prevValue|originalTarget|offsetHeight|keyup|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|Date|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|outer|prev|scrollTo|static|marginTop|next|inline|parents|able|cellSpacing|adobeair|cellspacing|522|maxLength|maxlength|readOnly|400|readonly|fast|600|class|slow|1px|htmlFor|reverse|10000|PI|cos|compatible|Function|setData|ie|ra|it|rv|getData|userAgent|navigator|fadeTo|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|fadeOut|300|protocol|send|setAttribute|option|dataFilter|cssText|changed|be|Accept|stop|With|Requested|Object|can|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|XMLHTTP|th|Microsoft|td|onreadystatechange|onload|cap|charset|colg|host|tfoot|specified|with|1_|thead|leg|plain|attributes|opt|embed|urlencoded|www|area|hr|ajaxSetup|meta|post|getJSON|getScript|marginLeft|img|elements|pageYOffset|pageXOffset|abbr|serialize|pixelLeft'.split('|'),0,{})) \ No newline at end of file diff --git a/public/scripts/main.js b/public/scripts/main.js new file mode 100644 index 0000000..e69de29 diff --git a/system/.svn/all-wcprops b/system/.svn/all-wcprops new file mode 100644 index 0000000..636afb8 --- /dev/null +++ b/system/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 30 +/svn/!svn/ver/124/trunk/system +END diff --git a/system/.svn/entries b/system/.svn/entries new file mode 100644 index 0000000..facbde2 --- /dev/null +++ b/system/.svn/entries @@ -0,0 +1,64 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +scaffolding +dir + +plugins +dir + +helpers +dir + +application +dir + +cache +dir + +language +dir + +database +dir + +logs +dir + +fonts +dir + +utilities +dir + +codeigniter +dir + +libraries +dir + diff --git a/system/application/.svn/all-wcprops b/system/application/.svn/all-wcprops new file mode 100644 index 0000000..713867d --- /dev/null +++ b/system/application/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/!svn/ver/124/trunk/system/application +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/application/index.html +END diff --git a/system/application/.svn/entries b/system/application/.svn/entries new file mode 100644 index 0000000..3009f04 --- /dev/null +++ b/system/application/.svn/entries @@ -0,0 +1,92 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +plugins +dir + +helpers +dir + +hooks +dir + +language +dir + +models +dir + +config +dir + +controllers +dir + +index.html +file + + + + +2009-09-15T00:18:04.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +errors +dir + +libraries +dir + +views +dir + diff --git a/system/application/.svn/prop-base/index.html.svn-base b/system/application/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/.svn/text-base/index.html.svn-base b/system/application/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/config/.svn/all-wcprops b/system/application/config/.svn/all-wcprops new file mode 100644 index 0000000..9b6f258 --- /dev/null +++ b/system/application/config/.svn/all-wcprops @@ -0,0 +1,59 @@ +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/117/trunk/system/application/config +END +mimes.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/application/config/mimes.php +END +user_agents.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/application/config/user_agents.php +END +routes.php +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/application/config/routes.php +END +hooks.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/application/config/hooks.php +END +database-sample.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/18/trunk/system/application/config/database-sample.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/application/config/index.html +END +config-sample.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/117/trunk/system/application/config/config-sample.php +END +smileys.php +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/18/trunk/system/application/config/smileys.php +END +autoload.php +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/!svn/ver/18/trunk/system/application/config/autoload.php +END diff --git a/system/application/config/.svn/entries b/system/application/config/.svn/entries new file mode 100644 index 0000000..df950d5 --- /dev/null +++ b/system/application/config/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/config +http://sweetcron.googlecode.com/svn + + + +2008-10-05T07:25:02.976982Z +117 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +mimes.php +file + + + + +2009-09-15T00:17:49.000000Z +f448652e2041378459f98e1351fa2075 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3915 + +user_agents.php +file + + + + +2009-09-15T00:17:49.000000Z +af54d668da8675307fd1e58dccaeced8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3333 + +routes.php +file + + + + +2009-09-15T00:17:49.000000Z +ac739e7cd13dc9d819de049f867f2364 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1871 + +hooks.php +file + + + + +2009-09-15T00:17:49.000000Z +18ccf2a3e220d7a493e3bc8801a1cd87 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +423 + +database-sample.php +file + + + + +2009-09-15T00:17:49.000000Z +f6427b46fae29e65fdd56438cae76a83 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2277 + +index.html +file + + + + +2009-09-15T00:17:49.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +config-sample.php +file + + + + +2009-09-15T00:17:49.000000Z +a25db98cac3f754b9ccaea9d132d7c27 +2008-10-05T07:25:02.976982Z +117 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +10721 + +smileys.php +file + + + + +2009-09-15T00:17:49.000000Z +9c96d1097118853e6ef60b36e74ae897 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3217 + +autoload.php +file + + + + +2009-09-15T00:17:49.000000Z +4d2649f038c629ccaaf4d1c4e84bc08e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3280 + diff --git a/system/application/config/.svn/prop-base/autoload.php.svn-base b/system/application/config/.svn/prop-base/autoload.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/autoload.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/config-sample.php.svn-base b/system/application/config/.svn/prop-base/config-sample.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/config-sample.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/database-sample.php.svn-base b/system/application/config/.svn/prop-base/database-sample.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/database-sample.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/hooks.php.svn-base b/system/application/config/.svn/prop-base/hooks.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/hooks.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/index.html.svn-base b/system/application/config/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/mimes.php.svn-base b/system/application/config/.svn/prop-base/mimes.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/mimes.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/routes.php.svn-base b/system/application/config/.svn/prop-base/routes.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/routes.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/smileys.php.svn-base b/system/application/config/.svn/prop-base/smileys.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/smileys.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/prop-base/user_agents.php.svn-base b/system/application/config/.svn/prop-base/user_agents.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/config/.svn/prop-base/user_agents.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/config/.svn/text-base/autoload.php.svn-base b/system/application/config/.svn/text-base/autoload.php.svn-base new file mode 100644 index 0000000..539c72d --- /dev/null +++ b/system/application/config/.svn/text-base/autoload.php.svn-base @@ -0,0 +1,125 @@ + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/config-sample.php.svn-base b/system/application/config/.svn/text-base/config-sample.php.svn-base new file mode 100644 index 0000000..3e5aaf1 --- /dev/null +++ b/system/application/config/.svn/text-base/config-sample.php.svn-base @@ -0,0 +1,314 @@ + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/database-sample.php.svn-base b/system/application/config/.svn/text-base/database-sample.php.svn-base new file mode 100644 index 0000000..0d0e08e --- /dev/null +++ b/system/application/config/.svn/text-base/database-sample.php.svn-base @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/hooks.php.svn-base b/system/application/config/.svn/text-base/hooks.php.svn-base new file mode 100644 index 0000000..f0a0d6e --- /dev/null +++ b/system/application/config/.svn/text-base/hooks.php.svn-base @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/index.html.svn-base b/system/application/config/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/config/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/mimes.php.svn-base b/system/application/config/.svn/text-base/mimes.php.svn-base new file mode 100644 index 0000000..225b0a5 --- /dev/null +++ b/system/application/config/.svn/text-base/mimes.php.svn-base @@ -0,0 +1,102 @@ + 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'), + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/x-download'), + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/excel', 'application/vnd.ms-excel'), + 'ppt' => 'application/powerpoint', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822' + ); + + +?> \ No newline at end of file diff --git a/system/application/config/.svn/text-base/routes.php.svn-base b/system/application/config/.svn/text-base/routes.php.svn-base new file mode 100644 index 0000000..d7e13ac --- /dev/null +++ b/system/application/config/.svn/text-base/routes.php.svn-base @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/system/application/config/.svn/text-base/smileys.php.svn-base b/system/application/config/.svn/text-base/smileys.php.svn-base new file mode 100644 index 0000000..a227d8b --- /dev/null +++ b/system/application/config/.svn/text-base/smileys.php.svn-base @@ -0,0 +1,64 @@ + array('grin.gif', '19', '19', 'grin'), + ':lol:' => array('lol.gif', '19', '19', 'LOL'), + ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), + ':)' => array('smile.gif', '19', '19', 'smile'), + ';-)' => array('wink.gif', '19', '19', 'wink'), + ';)' => array('wink.gif', '19', '19', 'wink'), + ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), + ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), + ':-S' => array('confused.gif', '19', '19', 'confused'), + ':wow:' => array('surprise.gif', '19', '19', 'surprised'), + ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), + ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), + '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), + ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), + ':P' => array('rasberry.gif', '19', '19', 'rasberry'), + ':blank:' => array('blank.gif', '19', '19', 'blank stare'), + ':long:' => array('longface.gif', '19', '19', 'long face'), + ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), + ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), + ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), + '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), + ':down:' => array('downer.gif', '19', '19', 'downer'), + ':red:' => array('embarrassed.gif', '19', '19', 'red face'), + ':sick:' => array('sick.gif', '19', '19', 'sick'), + ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), + ':-/' => array('hmm.gif', '19', '19', 'hmmm'), + '>:(' => array('mad.gif', '19', '19', 'mad'), + ':mad:' => array('mad.gif', '19', '19', 'mad'), + '>:-(' => array('angry.gif', '19', '19', 'angry'), + ':angry:' => array('angry.gif', '19', '19', 'angry'), + ':zip:' => array('zip.gif', '19', '19', 'zipper'), + ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), + ':ahhh:' => array('shock.gif', '19', '19', 'shock'), + ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), + ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), + ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), + ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), + ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), + ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), + ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), + ':snake:' => array('snake.gif', '19', '19', 'snake'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), + ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item + + ); +?> \ No newline at end of file diff --git a/system/application/config/.svn/text-base/user_agents.php.svn-base b/system/application/config/.svn/text-base/user_agents.php.svn-base new file mode 100644 index 0000000..08a665f --- /dev/null +++ b/system/application/config/.svn/text-base/user_agents.php.svn-base @@ -0,0 +1,103 @@ + 'Windows Longhorn', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows' => 'Unknown Windows OS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS' + ); + + +// The order of this array should NOT be changed. Many browsers return +// multiple browser types so we want to identify the sub-type first. +$browsers = array( + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Mozilla' => 'Mozilla', + 'Safari' => 'Safari', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse' + ); + +$mobiles = array( + 'mobileexplorer' => 'Mobile Explorer', + 'openwave' => 'Open Wave', + 'opera mini' => 'Opera Mini', + 'operamini' => 'Opera Mini', + 'elaine' => 'Palm', + 'palmsource' => 'Palm', + 'digital paths' => 'Palm', + 'avantgo' => 'Avantgo', + 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', + 'nokia' => 'Nokia', + 'ericsson' => 'Ericsson', + 'blackberry' => 'BlackBerry', + 'motorola' => 'Motorola' + ); + +// There are hundreds of bots but these are the most common. +$robots = array( + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'askjeeves' => 'AskJeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos' + ); + + +?> \ No newline at end of file diff --git a/system/application/config/autoload.php b/system/application/config/autoload.php new file mode 100755 index 0000000..539c72d --- /dev/null +++ b/system/application/config/autoload.php @@ -0,0 +1,125 @@ + \ No newline at end of file diff --git a/system/application/config/config-sample.php b/system/application/config/config-sample.php new file mode 100755 index 0000000..3e5aaf1 --- /dev/null +++ b/system/application/config/config-sample.php @@ -0,0 +1,314 @@ + \ No newline at end of file diff --git a/system/application/config/database-sample.php b/system/application/config/database-sample.php new file mode 100755 index 0000000..0d0e08e --- /dev/null +++ b/system/application/config/database-sample.php @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/system/application/config/hooks.php b/system/application/config/hooks.php new file mode 100755 index 0000000..f0a0d6e --- /dev/null +++ b/system/application/config/hooks.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/system/application/config/index.html b/system/application/config/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/config/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/config/mimes.php b/system/application/config/mimes.php new file mode 100755 index 0000000..225b0a5 --- /dev/null +++ b/system/application/config/mimes.php @@ -0,0 +1,102 @@ + 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'), + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/x-download'), + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/excel', 'application/vnd.ms-excel'), + 'ppt' => 'application/powerpoint', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822' + ); + + +?> \ No newline at end of file diff --git a/system/application/config/routes.php b/system/application/config/routes.php new file mode 100755 index 0000000..d7e13ac --- /dev/null +++ b/system/application/config/routes.php @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/system/application/config/smileys.php b/system/application/config/smileys.php new file mode 100755 index 0000000..a227d8b --- /dev/null +++ b/system/application/config/smileys.php @@ -0,0 +1,64 @@ + array('grin.gif', '19', '19', 'grin'), + ':lol:' => array('lol.gif', '19', '19', 'LOL'), + ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), + ':)' => array('smile.gif', '19', '19', 'smile'), + ';-)' => array('wink.gif', '19', '19', 'wink'), + ';)' => array('wink.gif', '19', '19', 'wink'), + ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), + ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), + ':-S' => array('confused.gif', '19', '19', 'confused'), + ':wow:' => array('surprise.gif', '19', '19', 'surprised'), + ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), + ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), + '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), + ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), + ':P' => array('rasberry.gif', '19', '19', 'rasberry'), + ':blank:' => array('blank.gif', '19', '19', 'blank stare'), + ':long:' => array('longface.gif', '19', '19', 'long face'), + ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), + ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), + ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), + '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), + ':down:' => array('downer.gif', '19', '19', 'downer'), + ':red:' => array('embarrassed.gif', '19', '19', 'red face'), + ':sick:' => array('sick.gif', '19', '19', 'sick'), + ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), + ':-/' => array('hmm.gif', '19', '19', 'hmmm'), + '>:(' => array('mad.gif', '19', '19', 'mad'), + ':mad:' => array('mad.gif', '19', '19', 'mad'), + '>:-(' => array('angry.gif', '19', '19', 'angry'), + ':angry:' => array('angry.gif', '19', '19', 'angry'), + ':zip:' => array('zip.gif', '19', '19', 'zipper'), + ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), + ':ahhh:' => array('shock.gif', '19', '19', 'shock'), + ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), + ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), + ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), + ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), + ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), + ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), + ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), + ':snake:' => array('snake.gif', '19', '19', 'snake'), + ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), + ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item + + ); +?> \ No newline at end of file diff --git a/system/application/config/user_agents.php b/system/application/config/user_agents.php new file mode 100755 index 0000000..08a665f --- /dev/null +++ b/system/application/config/user_agents.php @@ -0,0 +1,103 @@ + 'Windows Longhorn', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows' => 'Unknown Windows OS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS' + ); + + +// The order of this array should NOT be changed. Many browsers return +// multiple browser types so we want to identify the sub-type first. +$browsers = array( + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Mozilla' => 'Mozilla', + 'Safari' => 'Safari', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse' + ); + +$mobiles = array( + 'mobileexplorer' => 'Mobile Explorer', + 'openwave' => 'Open Wave', + 'opera mini' => 'Opera Mini', + 'operamini' => 'Opera Mini', + 'elaine' => 'Palm', + 'palmsource' => 'Palm', + 'digital paths' => 'Palm', + 'avantgo' => 'Avantgo', + 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', + 'nokia' => 'Nokia', + 'ericsson' => 'Ericsson', + 'blackberry' => 'BlackBerry', + 'motorola' => 'Motorola' + ); + +// There are hundreds of bots but these are the most common. +$robots = array( + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'askjeeves' => 'AskJeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos' + ); + + +?> \ No newline at end of file diff --git a/system/application/controllers/.svn/all-wcprops b/system/application/controllers/.svn/all-wcprops new file mode 100644 index 0000000..6648945 --- /dev/null +++ b/system/application/controllers/.svn/all-wcprops @@ -0,0 +1,41 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/124/trunk/system/application/controllers +END +p.php +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/124/trunk/system/application/controllers/p.php +END +cron.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/124/trunk/system/application/controllers/cron.php +END +items.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/124/trunk/system/application/controllers/items.php +END +feed.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/124/trunk/system/application/controllers/feed.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/application/controllers/index.html +END +home.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/124/trunk/system/application/controllers/home.php +END diff --git a/system/application/controllers/.svn/entries b/system/application/controllers/.svn/entries new file mode 100644 index 0000000..1b66f91 --- /dev/null +++ b/system/application/controllers/.svn/entries @@ -0,0 +1,235 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/controllers +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +p.php +file + + + + +2009-09-15T00:17:51.000000Z +4c4f9e19be11bec2af84184ffddf4672 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +1916 + +cron.php +file + + + + +2009-09-15T00:17:51.000000Z +9cd1c44a456ca42ed9da963ef61cf1f8 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2071 + +items.php +file + + + + +2009-09-15T00:17:51.000000Z +fd2aff5f140f6685783c2217a1edec7b +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2833 + +admin +dir + +feed.php +file + + + + +2009-09-15T00:17:51.000000Z +87ec197a083e6d260157e93ccaf15641 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2545 + +index.html +file + + + + +2009-09-15T00:17:51.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +home.php +file + + + + +2009-09-15T00:17:51.000000Z +ab83c9b3543dab448a546cfcaa07933a +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +1945 + diff --git a/system/application/controllers/.svn/prop-base/index.html.svn-base b/system/application/controllers/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/controllers/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/controllers/.svn/text-base/cron.php.svn-base b/system/application/controllers/.svn/text-base/cron.php.svn-base new file mode 100644 index 0000000..eae1bb2 --- /dev/null +++ b/system/application/controllers/.svn/text-base/cron.php.svn-base @@ -0,0 +1,53 @@ +config->item('cron_key')) { + $this->sweetcron->fetch_items(); + } else { + die("Uh uh uh, you didn't say the magic word"); + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/.svn/text-base/feed.php.svn-base b/system/application/controllers/.svn/text-base/feed.php.svn-base new file mode 100644 index 0000000..f167e31 --- /dev/null +++ b/system/application/controllers/.svn/text-base/feed.php.svn-base @@ -0,0 +1,76 @@ +sweetcron->get_items_page('rss_feed', 1, TRUE); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $query, 'search'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $tag, 'tag'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $feed_domain, 'site'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/.svn/text-base/home.php.svn-base b/system/application/controllers/.svn/text-base/home.php.svn-base new file mode 100644 index 0000000..3f0f82a --- /dev/null +++ b/system/application/controllers/.svn/text-base/home.php.svn-base @@ -0,0 +1,49 @@ +sweetcron->get_items_page('index', $this->uri->segment(2,1), TRUE); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/.svn/text-base/index.html.svn-base b/system/application/controllers/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/controllers/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/controllers/.svn/text-base/items.php.svn-base b/system/application/controllers/.svn/text-base/items.php.svn-base new file mode 100644 index 0000000..b8aa6b2 --- /dev/null +++ b/system/application/controllers/.svn/text-base/items.php.svn-base @@ -0,0 +1,91 @@ +sweetcron->do_search(); + } + + function index() + { + header('Location: '.$this->config->item('base_url')); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('search', $this->uri->segment(5,1), TRUE, $query); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('tag', $this->uri->segment(5,1), TRUE, $tag); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('site', $this->uri->segment(5,1), TRUE, $feed_domain); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function view($item_id = NULL) + { + if ($item_id) { + $this->sweetcron->get_single_item_page($item_id); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/.svn/text-base/p.php.svn-base b/system/application/controllers/.svn/text-base/p.php.svn-base new file mode 100644 index 0000000..461d06f --- /dev/null +++ b/system/application/controllers/.svn/text-base/p.php.svn-base @@ -0,0 +1,49 @@ +sweetcron->get_items_page('static_page'); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/all-wcprops b/system/application/controllers/admin/.svn/all-wcprops new file mode 100644 index 0000000..edd06d1 --- /dev/null +++ b/system/application/controllers/admin/.svn/all-wcprops @@ -0,0 +1,59 @@ +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/124/trunk/system/application/controllers/admin +END +write.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/write.php +END +options.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/options.php +END +process.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/process.php +END +items.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/items.php +END +ajax.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/ajax.php +END +install.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/install.php +END +feeds.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/feeds.php +END +dashboard.php +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/124/trunk/system/application/controllers/admin/dashboard.php +END +login.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/application/controllers/admin/login.php +END diff --git a/system/application/controllers/admin/.svn/entries b/system/application/controllers/admin/.svn/entries new file mode 100644 index 0000000..95623ca --- /dev/null +++ b/system/application/controllers/admin/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/controllers/admin +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +write.php +file + + + + +2009-09-15T00:17:51.000000Z +131d227ee499c28d9f7c55f2f4d61fc0 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +5098 + +options.php +file + + + + +2009-09-15T00:17:51.000000Z +56f8e6c8e1edb6f97bf84b78545dfcfd +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +4239 + +process.php +file + + + + +2009-09-15T00:17:51.000000Z +1f8d271db4a2b99b04fcd78112bd4935 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2212 + +items.php +file + + + + +2009-09-15T00:17:51.000000Z +c9c62f4b97b734ede915af1b0e5adf28 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2885 + +ajax.php +file + + + + +2009-09-15T00:17:51.000000Z +cc4207af311f603b78be4d214f94b26a +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2402 + +install.php +file + + + + +2009-09-15T00:17:51.000000Z +f1b94107782361ed9dfe13d4aa2ecad6 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +4698 + +feeds.php +file + + + + +2009-09-15T00:17:51.000000Z +b8f63a402ccd50179ee5b3470b4bed5a +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +4828 + +dashboard.php +file + + + + +2009-09-15T00:17:51.000000Z +04d3bb1aec011ab54bf39e17a359d0f4 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2271 + +login.php +file + + + + +2009-09-15T00:17:51.000000Z +ae5db605d38084541235b248c333a351 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +4668 + diff --git a/system/application/controllers/admin/.svn/text-base/ajax.php.svn-base b/system/application/controllers/admin/.svn/text-base/ajax.php.svn-base new file mode 100644 index 0000000..6c0c31a --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/ajax.php.svn-base @@ -0,0 +1,65 @@ +option_name = 'cron_key'; + $option->option_value = substr(md5(time().$this->config->item('lifestream_title')), 0, 8); + $this->option_model->add_option($option); + echo $option->option_value; + } + + function unpublish_item() + { + $item_id = $this->input->post('id'); + $this->db->update('items', array('item_status' => 'draft'), array('ID' => $item_id)); + } + + function publish_item() + { + $item_id = $this->input->post('id'); + $this->db->update('items', array('item_status' => 'publish'), array('ID' => $item_id)); + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/dashboard.php.svn-base b/system/application/controllers/admin/.svn/text-base/dashboard.php.svn-base new file mode 100644 index 0000000..d9aecca --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/dashboard.php.svn-base @@ -0,0 +1,57 @@ +page_name = 'Dashboard'; + $data->item_count = $this->item_model->count_all_items(TRUE); + $data->feed_count = $this->feed_model->count_active_feeds(); + $data->items = $this->item_model->get_all_items(0, 5, TRUE); + $this->load->view('admin/_header', $data); + $this->load->view('admin/dashboard', $data); + $this->load->view('admin/_footer'); + + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/feeds.php.svn-base b/system/application/controllers/admin/.svn/text-base/feeds.php.svn-base new file mode 100644 index 0000000..f243eb3 --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/feeds.php.svn-base @@ -0,0 +1,129 @@ +page_name = 'Feeds'; + $data->feeds = $this->feed_model->get_active_feeds(); + $this->load->view('admin/_header', $data); + $this->load->view('admin/feeds', $data); + $this->load->view('admin/_footer'); + } + + function add() + { + $data->page_name = 'Add Feed'; + if ($_POST) { + if ($this->input->post('url') == 'http://') { + $_POST['url'] = ''; + } + $this->load->library('validation'); + $rules['url'] = "trim|required|callback__test_feed"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/feed_add', $data); + } else { + $new->feed_title = $this->simplepie->get_title(); + $new->feed_icon = $this->simplepie->get_favicon(); + $new->feed_url = $this->validation->url; + + $new->feed_status = 'active'; + + //use permalink because sometimes feed is on subdomain which screws up plugin compatibility + $url = parse_url($this->simplepie->get_permalink()); + if (!$url['host']) { + $url = parse_url($this->validation->url); + } + if (substr($url['host'], 0, 4) == 'www.') { + $new->feed_domain = substr($url['host'], 4); + } else { + $new->feed_domain = $url['host']; + } + if (!$new->feed_icon) { + $new->feed_icon = 'http://'.$new->feed_domain.'/favicon.ico'; + } + $this->feed_model->add_feed($new); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/feed_add', $data); + } + $this->load->view('admin/_footer'); + } + + function delete($feed_id) + { + $this->feed_model->delete_feed($feed_id); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + } + + function _test_feed($url) + { + $this->simplepie->set_feed_url(prep_url($url)); + $this->simplepie->enable_cache(FALSE); + $this->simplepie->init(); + //check if already in the db + if ($this->db->get_where('feeds', array('feed_url' => $url))->row()) { + //if it was a deleted feed just reactivate it and forward to feed page + $feed = $this->db->get_where('feeds', array('feed_url' => $url))->row(); + if ($feed->feed_status == 'deleted') { + $this->db->update('feeds', array('feed_status' => 'active'), array('feed_id' => $feed->feed_id)); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + exit(); + } else { + $this->validation->set_message('_test_feed', 'You already added that feed...'); + return false; + } + } else if ($this->simplepie->error()) { + $this->validation->set_message('_test_feed', $this->simplepie->error()); + return false; + } else { + //looks like the feed is ok + return true; + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/install.php.svn-base b/system/application/controllers/admin/.svn/text-base/install.php.svn-base new file mode 100644 index 0000000..82f7d20 --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/install.php.svn-base @@ -0,0 +1,120 @@ +load->library('sweetcron'); + $this->sweetcron->compatibility_check(); + $this->sweetcron->install_check(); + $data->page_name = 'Install'; + + if ($_POST) { + $this->load->library('validation'); + $rules['lifestream_title'] = "trim|required"; + $rules['username'] = "trim|required|min_length[5]|max_length[20]"; + $rules['email'] = "trim|required|valid_email"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + } else { + $this->load->helper('file'); + $sql = read_file(BASEPATH.'utilities/install.sql'); + $sql = str_replace('%DB_PREFIX%', $this->db->dbprefix, $sql); + $sql = explode('CREATE', $sql); + unset($sql[0]); + //install sql and pray to baby jebus + foreach ($sql as $snippet) { + $this->db->query('CREATE'.$snippet); + } + //populate options + $options->lifestream_title = array('option_name' => 'lifestream_title', 'option_value' => $this->validation->lifestream_title); + $options->admin_email = array('option_name' => 'admin_email', 'option_value' => $this->validation->email); + $options->per_page = array('option_name' => 'per_page', 'option_value' => 9); + $options->cron_type = array('option_name' => 'cron_type', 'option_value' => 'pseudo'); + $cron_key = substr(md5(time().rand(1,100).$this->validation->lifestream_title.time()), 0, 8); + $options->cron_key = array('option_name' => 'cron_key', 'option_value' => $cron_key); + $options->theme = array('option_name' => 'theme', 'option_value' => 'sandbox'); + $this->load->model('option_model'); + foreach ($options as $option) { + $this->option_model->add_option($option); + } + + //add user + $password = substr(md5(time().rand(1,100).$this->validation->lifestream_title), 0, 8); + $user->user_login = $this->validation->username; + $user->user_pass = md5($password); + $user->user_email = $this->validation->email; + $user->user_activation_key = md5(time()); + $this->db->insert('users', $user); + + //send email + $url = $this->config->item('base_url'); + $this->load->library('email'); + + $this->email->from($this->validation->email, 'Sweetcron'); + $this->email->to($this->validation->email); + + $this->email->subject('[Sweetcron] Welcome to Sweetcron'); + $this->email->message('You have successfully installed Sweetcron! + +Your login details are as follows: + +Username: '.$this->validation->username.' +Password: '.$password.' + +Your Sweetcron site: '.$url.' + +Thanks and have fun!'); + + $this->email->send(); + $data->success = TRUE; + $data->password = $password; + } + } + + $this->load->view('admin/_header', $data); + $this->load->view('admin/install', $data); + $this->load->view('admin/_footer'); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/items.php.svn-base b/system/application/controllers/admin/.svn/text-base/items.php.svn-base new file mode 100644 index 0000000..91ff0dd --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/items.php.svn-base @@ -0,0 +1,88 @@ +sweetcron->get_items_page('index', $this->uri->segment(4,1), FALSE); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('search', $this->uri->segment(6,1), FALSE, $query); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('tag', $this->uri->segment(6,1), FALSE, $tag); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('site', $this->uri->segment(6,1), FALSE, $feed_domain); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function fetch() + { + $this->sweetcron->fetch_items(); + header('Location: '.$_SERVER['HTTP_REFERER']); + } + + function delete($item_id) + { + $this->item_model->delete_item($item_id); + header('Location: '.$_SERVER['HTTP_REFERER']); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/login.php.svn-base b/system/application/controllers/admin/.svn/text-base/login.php.svn-base new file mode 100644 index 0000000..155c492 --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/login.php.svn-base @@ -0,0 +1,130 @@ +data->user === FALSE) { + header('Location: '.$this->config->item('base_url').'admin'); + } + } + + function index() { + $data->page_name = 'Login'; + $this->load->view('admin/_header', $data); + if ($_POST) { + $this->load->library('validation'); + $rules['username'] = "required|trim"; + $rules['password'] = "required|trim"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/login', $data); + } else { + //passed validation but need to check if can log in + if (!$this->auth->try_login(array('user_login' => $this->validation->username, 'user_pass' => md5($this->validation->password)))) { + //authentication error + $data->errors = 'Usernames / Password incorrect'; + $this->load->view('admin/login', $data); + } else { + header('Location: '.$this->config->item('base_url').'admin'); + } + } + } else { + $this->load->view('admin/login'); + } + + $this->load->view('admin/_footer'); + } + + function forgot() { + $data->page_name = 'Password Reset'; + $this->load->view('admin/_header', $data); + if ($_POST) { + $this->load->library('validation'); + $rules['email'] = "required|trim|valid_email|callback__is_admin_email"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/forgot', $data); + } else { + //change activation key and send a mail + $key = substr(md5(time().rand(1,100)),0,10); + $user->user_activation_key = $key; + $this->db->update('users', $user, array('user_email' => $this->validation->email)); + $link = $this->config->item('base_url').'admin/login/reset_password/'.$key; + //send email + $this->load->library('email'); + + $this->email->from($this->validation->email, 'Sweetcron'); + $this->email->to($this->validation->email); + + $this->email->subject('[Sweetcron] Reset Password'); + $this->email->message('You have initiated a password reset request. + +Click this link to reset your password: + +'.$link.' + +If you feel you have received this message in error, ignore this message and do not click the link.'); + + $this->email->send(); + $data->success = TRUE; + $this->load->view('admin/forgot',$data); + } + } else { + $this->load->view('admin/forgot'); + } + + $this->load->view('admin/_footer'); + } + + function reset_password($key) + { + if ($user = $this->db->get_where('users', array('user_activation_key' => $key))->row()) { + //reset the activation key + $key = substr(md5(time().rand(1,100)),0,10); + $edited->user_activation_key = $key; + //reset users password + $password = substr(md5(time().rand(1,100).$this->config->item('lifestream_title')), 0, 8); + $edited->user_pass = md5($password); + $this->db->update('users', $edited, array('user_email' => $user->user_email)); + + $this->load->library('email'); + + $this->email->from($user->user_email, 'Sweetcron'); + $this->email->to($user->user_email); + + $this->email->subject('[Sweetcron] New Password'); + $this->email->message('You initiated and confirmed a password reset request. + +Your login details are as follows: + +Username: '.$user->user_login.' +Password: '.$password.' + +Thanks and have fun!'); + + $this->email->send(); + + die('Your password was reset - please check your email'); + } else { + die("Uh uh uh, you didn't say the magic word!"); + } + } + + function _is_admin_email($email) + { + if ($this->db->get_where('users', array('user_email' => $email))->row()) { + return true; + } else { + $this->validation->set_message('_is_admin_email', 'That email is not registered with Sweetcron'); + return false; + } + } + + function bye() + { + $this->auth->logout(); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/options.php.svn-base b/system/application/controllers/admin/.svn/text-base/options.php.svn-base new file mode 100644 index 0000000..88d5bf3 --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/options.php.svn-base @@ -0,0 +1,108 @@ +load->helper('file'); + $this->load->helper('inflector'); + $data->page_name = 'Options'; + $theme_folder = get_dir_file_info(BASEPATH.'application/views/themes', FALSE, TRUE); + foreach ($theme_folder as $key => $value) { + if (is_dir(BASEPATH.'application/views/themes/'.$key)) { + $themes[$key]->folder = $key; + $themes[$key]->name = humanize($key); + } + } + $data->themes = $themes; + + if ($_POST) { + $this->load->library('validation'); + $fields['lifestream_title'] = 'Lifestream Title'; + $fields['admin_email'] = 'Admin Email'; + $fields['new_password'] = 'New Password'; + $fields['new_password_confirm'] = 'New Password Confirm'; + $fields['per_page'] = 'Items Per Page'; + + $this->validation->set_fields($fields); + + $rules['lifestream_title'] = "trim|required"; + $rules['admin_email'] = "trim|required|valid_email"; + $rules['new_password'] = "trim|matches[new_password_confirm]"; + $rules['new_password_confirm'] = "trim"; + $rules['per_page'] = "numeric"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/options', $data); + $this->load->view('admin/_footer'); + } else { + //set new password if required + if ($this->validation->new_password && $this->validation->new_password != '') { + $password = md5($this->validation->new_password); + $this->db->update('users', array('user_pass' => $password), array('ID' => $this->data->user->ID)); + } + //set admin email + $this->db->update('users', array('user_email' => $this->validation->admin_email), array('ID' => $this->data->user->ID)); + + unset($_POST['new_password']); + unset($_POST['new_password_confirm']); + //save options + foreach ($_POST as $key => $value) { + $option_array[$key]->option_name = $key; + $option_array[$key]->option_value = $value; + } + foreach ($option_array as $option) { + $this->option_model->add_option($option); + } + header('Location: '.$this->config->item('base_url').'admin/options'); + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/options', $data); + $this->load->view('admin/_footer'); + } + + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/process.php.svn-base b/system/application/controllers/admin/.svn/text-base/process.php.svn-base new file mode 100644 index 0000000..e6cf8db --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/process.php.svn-base @@ -0,0 +1,56 @@ +input->post('keywords')) { + //strip out stuff and send to page + $keywords = urlencode($this->input->post('keywords')); + header('Location: '.$this->config->item('base_url').'admin/items/search/'.$keywords); + } else { + show_error('You must type some keywords to search'); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/.svn/text-base/write.php.svn-base b/system/application/controllers/admin/.svn/text-base/write.php.svn-base new file mode 100644 index 0000000..69c8e25 --- /dev/null +++ b/system/application/controllers/admin/.svn/text-base/write.php.svn-base @@ -0,0 +1,126 @@ +uri->segment(3) == 'edit') { + if ($this->input->post('referer')) { + $data->referer = $this->input->post('referer'); + } else { + $data->referer = $_SERVER['HTTP_REFERER']; + } + $data->editing = TRUE; + //get item + $data->item = $this->item_model->get_edit_item_by_id($this->uri->segment(4)); + if (isset($data->item->item_tags[0])) { + foreach ($data->item->item_tags as $tag) { + $tags[] = $tag->name; + } + $data->tag_string = implode(', ', $tags); + } + $new_post->item_data = $data->item->item_data; + } + $data->page_name = 'Write'; + if ($_POST) { + $this->load->library('validation'); + $rules['title'] = "trim|required|xss_clean"; + $rules['date'] = "trim|xss_clean"; + $rules['content'] = "trim|xss_clean"; + $rules['tags'] = "trim|xss_clean"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/write', $data); + } else { + //prepare data + if (!isset($data->editing)) { + $new_post->item_data = array(); + } + if ($this->validation->tags) { + $tags = explode(',', $this->validation->tags); + foreach ($tags as $key => $value) { + $tags[$key] = trim($value); + } + if (isset($tags[0])) { + $new_post->item_data['tags'] = $tags; + } + } + + $new_post->item_title = $this->validation->title; + if (!$this->validation->content) { + $new_post->item_content = ''; + } else { + $new_post->item_content = $this->validation->content; + } + + if ($this->input->post('save_edit') == 'true') { + //save edits + if ($this->input->post('timestamp') == 'make_current') { + $new_post->item_date = time(); + } elseif ($this->input->post('timestamp') == 'make_current_publish') { + $new_post->item_status = 'publish'; + $new_post->item_date = time(); + } + $this->item_model->update_item($new_post, $data->item); + header('Location: '.$this->input->post('referer')); + } else { + //add new item + $new_post->item_name = url_title($this->validation->title); + $new_post->item_date = time(); + if ($this->input->post('draft') == 'true') { + $new_post->item_status = 'draft'; + } + $this->item_model->add_blog_post($new_post); + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/write', $data); + } + $this->load->view('admin/_footer'); + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/ajax.php b/system/application/controllers/admin/ajax.php new file mode 100644 index 0000000..6c0c31a --- /dev/null +++ b/system/application/controllers/admin/ajax.php @@ -0,0 +1,65 @@ +option_name = 'cron_key'; + $option->option_value = substr(md5(time().$this->config->item('lifestream_title')), 0, 8); + $this->option_model->add_option($option); + echo $option->option_value; + } + + function unpublish_item() + { + $item_id = $this->input->post('id'); + $this->db->update('items', array('item_status' => 'draft'), array('ID' => $item_id)); + } + + function publish_item() + { + $item_id = $this->input->post('id'); + $this->db->update('items', array('item_status' => 'publish'), array('ID' => $item_id)); + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/dashboard.php b/system/application/controllers/admin/dashboard.php new file mode 100644 index 0000000..d9aecca --- /dev/null +++ b/system/application/controllers/admin/dashboard.php @@ -0,0 +1,57 @@ +page_name = 'Dashboard'; + $data->item_count = $this->item_model->count_all_items(TRUE); + $data->feed_count = $this->feed_model->count_active_feeds(); + $data->items = $this->item_model->get_all_items(0, 5, TRUE); + $this->load->view('admin/_header', $data); + $this->load->view('admin/dashboard', $data); + $this->load->view('admin/_footer'); + + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/feeds.php b/system/application/controllers/admin/feeds.php new file mode 100644 index 0000000..f243eb3 --- /dev/null +++ b/system/application/controllers/admin/feeds.php @@ -0,0 +1,129 @@ +page_name = 'Feeds'; + $data->feeds = $this->feed_model->get_active_feeds(); + $this->load->view('admin/_header', $data); + $this->load->view('admin/feeds', $data); + $this->load->view('admin/_footer'); + } + + function add() + { + $data->page_name = 'Add Feed'; + if ($_POST) { + if ($this->input->post('url') == 'http://') { + $_POST['url'] = ''; + } + $this->load->library('validation'); + $rules['url'] = "trim|required|callback__test_feed"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/feed_add', $data); + } else { + $new->feed_title = $this->simplepie->get_title(); + $new->feed_icon = $this->simplepie->get_favicon(); + $new->feed_url = $this->validation->url; + + $new->feed_status = 'active'; + + //use permalink because sometimes feed is on subdomain which screws up plugin compatibility + $url = parse_url($this->simplepie->get_permalink()); + if (!$url['host']) { + $url = parse_url($this->validation->url); + } + if (substr($url['host'], 0, 4) == 'www.') { + $new->feed_domain = substr($url['host'], 4); + } else { + $new->feed_domain = $url['host']; + } + if (!$new->feed_icon) { + $new->feed_icon = 'http://'.$new->feed_domain.'/favicon.ico'; + } + $this->feed_model->add_feed($new); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/feed_add', $data); + } + $this->load->view('admin/_footer'); + } + + function delete($feed_id) + { + $this->feed_model->delete_feed($feed_id); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + } + + function _test_feed($url) + { + $this->simplepie->set_feed_url(prep_url($url)); + $this->simplepie->enable_cache(FALSE); + $this->simplepie->init(); + //check if already in the db + if ($this->db->get_where('feeds', array('feed_url' => $url))->row()) { + //if it was a deleted feed just reactivate it and forward to feed page + $feed = $this->db->get_where('feeds', array('feed_url' => $url))->row(); + if ($feed->feed_status == 'deleted') { + $this->db->update('feeds', array('feed_status' => 'active'), array('feed_id' => $feed->feed_id)); + header('Location: '.$this->config->item('base_url').'admin/feeds'); + exit(); + } else { + $this->validation->set_message('_test_feed', 'You already added that feed...'); + return false; + } + } else if ($this->simplepie->error()) { + $this->validation->set_message('_test_feed', $this->simplepie->error()); + return false; + } else { + //looks like the feed is ok + return true; + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/install.php b/system/application/controllers/admin/install.php new file mode 100644 index 0000000..82f7d20 --- /dev/null +++ b/system/application/controllers/admin/install.php @@ -0,0 +1,120 @@ +load->library('sweetcron'); + $this->sweetcron->compatibility_check(); + $this->sweetcron->install_check(); + $data->page_name = 'Install'; + + if ($_POST) { + $this->load->library('validation'); + $rules['lifestream_title'] = "trim|required"; + $rules['username'] = "trim|required|min_length[5]|max_length[20]"; + $rules['email'] = "trim|required|valid_email"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + } else { + $this->load->helper('file'); + $sql = read_file(BASEPATH.'utilities/install.sql'); + $sql = str_replace('%DB_PREFIX%', $this->db->dbprefix, $sql); + $sql = explode('CREATE', $sql); + unset($sql[0]); + //install sql and pray to baby jebus + foreach ($sql as $snippet) { + $this->db->query('CREATE'.$snippet); + } + //populate options + $options->lifestream_title = array('option_name' => 'lifestream_title', 'option_value' => $this->validation->lifestream_title); + $options->admin_email = array('option_name' => 'admin_email', 'option_value' => $this->validation->email); + $options->per_page = array('option_name' => 'per_page', 'option_value' => 9); + $options->cron_type = array('option_name' => 'cron_type', 'option_value' => 'pseudo'); + $cron_key = substr(md5(time().rand(1,100).$this->validation->lifestream_title.time()), 0, 8); + $options->cron_key = array('option_name' => 'cron_key', 'option_value' => $cron_key); + $options->theme = array('option_name' => 'theme', 'option_value' => 'sandbox'); + $this->load->model('option_model'); + foreach ($options as $option) { + $this->option_model->add_option($option); + } + + //add user + $password = substr(md5(time().rand(1,100).$this->validation->lifestream_title), 0, 8); + $user->user_login = $this->validation->username; + $user->user_pass = md5($password); + $user->user_email = $this->validation->email; + $user->user_activation_key = md5(time()); + $this->db->insert('users', $user); + + //send email + $url = $this->config->item('base_url'); + $this->load->library('email'); + + $this->email->from($this->validation->email, 'Sweetcron'); + $this->email->to($this->validation->email); + + $this->email->subject('[Sweetcron] Welcome to Sweetcron'); + $this->email->message('You have successfully installed Sweetcron! + +Your login details are as follows: + +Username: '.$this->validation->username.' +Password: '.$password.' + +Your Sweetcron site: '.$url.' + +Thanks and have fun!'); + + $this->email->send(); + $data->success = TRUE; + $data->password = $password; + } + } + + $this->load->view('admin/_header', $data); + $this->load->view('admin/install', $data); + $this->load->view('admin/_footer'); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/items.php b/system/application/controllers/admin/items.php new file mode 100644 index 0000000..91ff0dd --- /dev/null +++ b/system/application/controllers/admin/items.php @@ -0,0 +1,88 @@ +sweetcron->get_items_page('index', $this->uri->segment(4,1), FALSE); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('search', $this->uri->segment(6,1), FALSE, $query); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('tag', $this->uri->segment(6,1), FALSE, $tag); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('site', $this->uri->segment(6,1), FALSE, $feed_domain); + } else { + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + + function fetch() + { + $this->sweetcron->fetch_items(); + header('Location: '.$_SERVER['HTTP_REFERER']); + } + + function delete($item_id) + { + $this->item_model->delete_item($item_id); + header('Location: '.$_SERVER['HTTP_REFERER']); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/login.php b/system/application/controllers/admin/login.php new file mode 100644 index 0000000..155c492 --- /dev/null +++ b/system/application/controllers/admin/login.php @@ -0,0 +1,130 @@ +data->user === FALSE) { + header('Location: '.$this->config->item('base_url').'admin'); + } + } + + function index() { + $data->page_name = 'Login'; + $this->load->view('admin/_header', $data); + if ($_POST) { + $this->load->library('validation'); + $rules['username'] = "required|trim"; + $rules['password'] = "required|trim"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/login', $data); + } else { + //passed validation but need to check if can log in + if (!$this->auth->try_login(array('user_login' => $this->validation->username, 'user_pass' => md5($this->validation->password)))) { + //authentication error + $data->errors = 'Usernames / Password incorrect'; + $this->load->view('admin/login', $data); + } else { + header('Location: '.$this->config->item('base_url').'admin'); + } + } + } else { + $this->load->view('admin/login'); + } + + $this->load->view('admin/_footer'); + } + + function forgot() { + $data->page_name = 'Password Reset'; + $this->load->view('admin/_header', $data); + if ($_POST) { + $this->load->library('validation'); + $rules['email'] = "required|trim|valid_email|callback__is_admin_email"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/forgot', $data); + } else { + //change activation key and send a mail + $key = substr(md5(time().rand(1,100)),0,10); + $user->user_activation_key = $key; + $this->db->update('users', $user, array('user_email' => $this->validation->email)); + $link = $this->config->item('base_url').'admin/login/reset_password/'.$key; + //send email + $this->load->library('email'); + + $this->email->from($this->validation->email, 'Sweetcron'); + $this->email->to($this->validation->email); + + $this->email->subject('[Sweetcron] Reset Password'); + $this->email->message('You have initiated a password reset request. + +Click this link to reset your password: + +'.$link.' + +If you feel you have received this message in error, ignore this message and do not click the link.'); + + $this->email->send(); + $data->success = TRUE; + $this->load->view('admin/forgot',$data); + } + } else { + $this->load->view('admin/forgot'); + } + + $this->load->view('admin/_footer'); + } + + function reset_password($key) + { + if ($user = $this->db->get_where('users', array('user_activation_key' => $key))->row()) { + //reset the activation key + $key = substr(md5(time().rand(1,100)),0,10); + $edited->user_activation_key = $key; + //reset users password + $password = substr(md5(time().rand(1,100).$this->config->item('lifestream_title')), 0, 8); + $edited->user_pass = md5($password); + $this->db->update('users', $edited, array('user_email' => $user->user_email)); + + $this->load->library('email'); + + $this->email->from($user->user_email, 'Sweetcron'); + $this->email->to($user->user_email); + + $this->email->subject('[Sweetcron] New Password'); + $this->email->message('You initiated and confirmed a password reset request. + +Your login details are as follows: + +Username: '.$user->user_login.' +Password: '.$password.' + +Thanks and have fun!'); + + $this->email->send(); + + die('Your password was reset - please check your email'); + } else { + die("Uh uh uh, you didn't say the magic word!"); + } + } + + function _is_admin_email($email) + { + if ($this->db->get_where('users', array('user_email' => $email))->row()) { + return true; + } else { + $this->validation->set_message('_is_admin_email', 'That email is not registered with Sweetcron'); + return false; + } + } + + function bye() + { + $this->auth->logout(); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/options.php b/system/application/controllers/admin/options.php new file mode 100644 index 0000000..88d5bf3 --- /dev/null +++ b/system/application/controllers/admin/options.php @@ -0,0 +1,108 @@ +load->helper('file'); + $this->load->helper('inflector'); + $data->page_name = 'Options'; + $theme_folder = get_dir_file_info(BASEPATH.'application/views/themes', FALSE, TRUE); + foreach ($theme_folder as $key => $value) { + if (is_dir(BASEPATH.'application/views/themes/'.$key)) { + $themes[$key]->folder = $key; + $themes[$key]->name = humanize($key); + } + } + $data->themes = $themes; + + if ($_POST) { + $this->load->library('validation'); + $fields['lifestream_title'] = 'Lifestream Title'; + $fields['admin_email'] = 'Admin Email'; + $fields['new_password'] = 'New Password'; + $fields['new_password_confirm'] = 'New Password Confirm'; + $fields['per_page'] = 'Items Per Page'; + + $this->validation->set_fields($fields); + + $rules['lifestream_title'] = "trim|required"; + $rules['admin_email'] = "trim|required|valid_email"; + $rules['new_password'] = "trim|matches[new_password_confirm]"; + $rules['new_password_confirm'] = "trim"; + $rules['per_page'] = "numeric"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/options', $data); + $this->load->view('admin/_footer'); + } else { + //set new password if required + if ($this->validation->new_password && $this->validation->new_password != '') { + $password = md5($this->validation->new_password); + $this->db->update('users', array('user_pass' => $password), array('ID' => $this->data->user->ID)); + } + //set admin email + $this->db->update('users', array('user_email' => $this->validation->admin_email), array('ID' => $this->data->user->ID)); + + unset($_POST['new_password']); + unset($_POST['new_password_confirm']); + //save options + foreach ($_POST as $key => $value) { + $option_array[$key]->option_name = $key; + $option_array[$key]->option_value = $value; + } + foreach ($option_array as $option) { + $this->option_model->add_option($option); + } + header('Location: '.$this->config->item('base_url').'admin/options'); + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/options', $data); + $this->load->view('admin/_footer'); + } + + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/process.php b/system/application/controllers/admin/process.php new file mode 100644 index 0000000..e6cf8db --- /dev/null +++ b/system/application/controllers/admin/process.php @@ -0,0 +1,56 @@ +input->post('keywords')) { + //strip out stuff and send to page + $keywords = urlencode($this->input->post('keywords')); + header('Location: '.$this->config->item('base_url').'admin/items/search/'.$keywords); + } else { + show_error('You must type some keywords to search'); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/admin/write.php b/system/application/controllers/admin/write.php new file mode 100644 index 0000000..69c8e25 --- /dev/null +++ b/system/application/controllers/admin/write.php @@ -0,0 +1,126 @@ +uri->segment(3) == 'edit') { + if ($this->input->post('referer')) { + $data->referer = $this->input->post('referer'); + } else { + $data->referer = $_SERVER['HTTP_REFERER']; + } + $data->editing = TRUE; + //get item + $data->item = $this->item_model->get_edit_item_by_id($this->uri->segment(4)); + if (isset($data->item->item_tags[0])) { + foreach ($data->item->item_tags as $tag) { + $tags[] = $tag->name; + } + $data->tag_string = implode(', ', $tags); + } + $new_post->item_data = $data->item->item_data; + } + $data->page_name = 'Write'; + if ($_POST) { + $this->load->library('validation'); + $rules['title'] = "trim|required|xss_clean"; + $rules['date'] = "trim|xss_clean"; + $rules['content'] = "trim|xss_clean"; + $rules['tags'] = "trim|xss_clean"; + $this->validation->set_rules($rules); + if ($this->validation->run() == FALSE) { + $data->errors = $this->validation->error_string; + $this->load->view('admin/_header', $data); + $this->load->view('admin/write', $data); + } else { + //prepare data + if (!isset($data->editing)) { + $new_post->item_data = array(); + } + if ($this->validation->tags) { + $tags = explode(',', $this->validation->tags); + foreach ($tags as $key => $value) { + $tags[$key] = trim($value); + } + if (isset($tags[0])) { + $new_post->item_data['tags'] = $tags; + } + } + + $new_post->item_title = $this->validation->title; + if (!$this->validation->content) { + $new_post->item_content = ''; + } else { + $new_post->item_content = $this->validation->content; + } + + if ($this->input->post('save_edit') == 'true') { + //save edits + if ($this->input->post('timestamp') == 'make_current') { + $new_post->item_date = time(); + } elseif ($this->input->post('timestamp') == 'make_current_publish') { + $new_post->item_status = 'publish'; + $new_post->item_date = time(); + } + $this->item_model->update_item($new_post, $data->item); + header('Location: '.$this->input->post('referer')); + } else { + //add new item + $new_post->item_name = url_title($this->validation->title); + $new_post->item_date = time(); + if ($this->input->post('draft') == 'true') { + $new_post->item_status = 'draft'; + } + $this->item_model->add_blog_post($new_post); + header('Location: '.$this->config->item('base_url').'admin/items'); + } + } + } else { + $this->load->view('admin/_header', $data); + $this->load->view('admin/write', $data); + } + $this->load->view('admin/_footer'); + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/cron.php b/system/application/controllers/cron.php new file mode 100644 index 0000000..eae1bb2 --- /dev/null +++ b/system/application/controllers/cron.php @@ -0,0 +1,53 @@ +config->item('cron_key')) { + $this->sweetcron->fetch_items(); + } else { + die("Uh uh uh, you didn't say the magic word"); + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/feed.php b/system/application/controllers/feed.php new file mode 100644 index 0000000..f167e31 --- /dev/null +++ b/system/application/controllers/feed.php @@ -0,0 +1,76 @@ +sweetcron->get_items_page('rss_feed', 1, TRUE); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $query, 'search'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $tag, 'tag'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('rss_feed', 1, TRUE, $feed_domain, 'site'); + } else { + header('Location: '.$this->config->item('base_url')); + } + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/home.php b/system/application/controllers/home.php new file mode 100644 index 0000000..3f0f82a --- /dev/null +++ b/system/application/controllers/home.php @@ -0,0 +1,49 @@ +sweetcron->get_items_page('index', $this->uri->segment(2,1), TRUE); + } +} +?> \ No newline at end of file diff --git a/system/application/controllers/index.html b/system/application/controllers/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/controllers/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/controllers/items.php b/system/application/controllers/items.php new file mode 100644 index 0000000..b8aa6b2 --- /dev/null +++ b/system/application/controllers/items.php @@ -0,0 +1,91 @@ +sweetcron->do_search(); + } + + function index() + { + header('Location: '.$this->config->item('base_url')); + } + + function search($query = NULL) + { + if ($query) { + $this->sweetcron->get_items_page('search', $this->uri->segment(5,1), TRUE, $query); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function tag($tag = NULL) + { + if ($tag) { + $this->sweetcron->get_items_page('tag', $this->uri->segment(5,1), TRUE, $tag); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function site($feed_domain = NULL) + { + if ($feed_domain) { + $this->sweetcron->get_items_page('site', $this->uri->segment(5,1), TRUE, $feed_domain); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + + function view($item_id = NULL) + { + if ($item_id) { + $this->sweetcron->get_single_item_page($item_id); + } else { + header('Location: '.$this->config->item('base_url')); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/controllers/p.php b/system/application/controllers/p.php new file mode 100644 index 0000000..461d06f --- /dev/null +++ b/system/application/controllers/p.php @@ -0,0 +1,49 @@ +sweetcron->get_items_page('static_page'); + } +} +?> \ No newline at end of file diff --git a/system/application/errors/.svn/all-wcprops b/system/application/errors/.svn/all-wcprops new file mode 100644 index 0000000..dc652cc --- /dev/null +++ b/system/application/errors/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/18/trunk/system/application/errors +END +error_db.php +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/!svn/ver/18/trunk/system/application/errors/error_db.php +END +error_404.php +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/application/errors/error_404.php +END +error_php.php +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/application/errors/error_php.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/application/errors/index.html +END +error_general.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/18/trunk/system/application/errors/error_general.php +END diff --git a/system/application/errors/.svn/entries b/system/application/errors/.svn/entries new file mode 100644 index 0000000..bcc84ff --- /dev/null +++ b/system/application/errors/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/errors +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +error_db.php +file + + + + +2009-09-15T00:17:51.000000Z +5670a42820ea40968b47b75e8a710c63 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +520 + +error_404.php +file + + + + +2009-09-15T00:17:51.000000Z +4dc5ce77087d486ebbf9ec398166c1e6 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +567 + +error_php.php +file + + + + +2009-09-15T00:17:51.000000Z +f4ab89a1c904098a1253e34b0a72e42d +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +288 + +index.html +file + + + + +2009-09-15T00:17:51.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +error_general.php +file + + + + +2009-09-15T00:17:51.000000Z +489e05135731c7911cdb63ea39785dfa +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +511 + diff --git a/system/application/errors/.svn/prop-base/error_404.php.svn-base b/system/application/errors/.svn/prop-base/error_404.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/errors/.svn/prop-base/error_404.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/errors/.svn/prop-base/error_db.php.svn-base b/system/application/errors/.svn/prop-base/error_db.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/errors/.svn/prop-base/error_db.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/errors/.svn/prop-base/error_general.php.svn-base b/system/application/errors/.svn/prop-base/error_general.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/errors/.svn/prop-base/error_general.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/errors/.svn/prop-base/error_php.php.svn-base b/system/application/errors/.svn/prop-base/error_php.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/errors/.svn/prop-base/error_php.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/errors/.svn/prop-base/index.html.svn-base b/system/application/errors/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/errors/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/errors/.svn/text-base/error_404.php.svn-base b/system/application/errors/.svn/text-base/error_404.php.svn-base new file mode 100644 index 0000000..bfe9444 --- /dev/null +++ b/system/application/errors/.svn/text-base/error_404.php.svn-base @@ -0,0 +1,35 @@ + + + +404 Page Not Found + + + +

+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/.svn/text-base/error_db.php.svn-base b/system/application/errors/.svn/text-base/error_db.php.svn-base new file mode 100644 index 0000000..1ce52df --- /dev/null +++ b/system/application/errors/.svn/text-base/error_db.php.svn-base @@ -0,0 +1,34 @@ + + +Database Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/.svn/text-base/error_general.php.svn-base b/system/application/errors/.svn/text-base/error_general.php.svn-base new file mode 100644 index 0000000..d861070 --- /dev/null +++ b/system/application/errors/.svn/text-base/error_general.php.svn-base @@ -0,0 +1,34 @@ + + +Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/.svn/text-base/error_php.php.svn-base b/system/application/errors/.svn/text-base/error_php.php.svn-base new file mode 100644 index 0000000..f085c20 --- /dev/null +++ b/system/application/errors/.svn/text-base/error_php.php.svn-base @@ -0,0 +1,10 @@ +
+ +

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ +
\ No newline at end of file diff --git a/system/application/errors/.svn/text-base/index.html.svn-base b/system/application/errors/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/errors/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/errors/error_404.php b/system/application/errors/error_404.php new file mode 100755 index 0000000..bfe9444 --- /dev/null +++ b/system/application/errors/error_404.php @@ -0,0 +1,35 @@ + + + +404 Page Not Found + + + +

+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/error_db.php b/system/application/errors/error_db.php new file mode 100755 index 0000000..1ce52df --- /dev/null +++ b/system/application/errors/error_db.php @@ -0,0 +1,34 @@ + + +Database Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/error_general.php b/system/application/errors/error_general.php new file mode 100755 index 0000000..d861070 --- /dev/null +++ b/system/application/errors/error_general.php @@ -0,0 +1,34 @@ + + +Error + + + +
+

+ +
+ + \ No newline at end of file diff --git a/system/application/errors/error_php.php b/system/application/errors/error_php.php new file mode 100755 index 0000000..f085c20 --- /dev/null +++ b/system/application/errors/error_php.php @@ -0,0 +1,10 @@ +
+ +

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ +
\ No newline at end of file diff --git a/system/application/errors/index.html b/system/application/errors/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/errors/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/helpers/.svn/all-wcprops b/system/application/helpers/.svn/all-wcprops new file mode 100644 index 0000000..62c8990 --- /dev/null +++ b/system/application/helpers/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/application/helpers +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/18/trunk/system/application/helpers/index.html +END diff --git a/system/application/helpers/.svn/entries b/system/application/helpers/.svn/entries new file mode 100644 index 0000000..15b6bb7 --- /dev/null +++ b/system/application/helpers/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/helpers +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:17:46.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/application/helpers/.svn/prop-base/index.html.svn-base b/system/application/helpers/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/helpers/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/helpers/.svn/text-base/index.html.svn-base b/system/application/helpers/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/helpers/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/helpers/index.html b/system/application/helpers/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/helpers/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/hooks/.svn/all-wcprops b/system/application/hooks/.svn/all-wcprops new file mode 100644 index 0000000..41e2803 --- /dev/null +++ b/system/application/hooks/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/application/hooks +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/application/hooks/index.html +END diff --git a/system/application/hooks/.svn/entries b/system/application/hooks/.svn/entries new file mode 100644 index 0000000..b132f32 --- /dev/null +++ b/system/application/hooks/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/hooks +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:17:46.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/application/hooks/.svn/prop-base/index.html.svn-base b/system/application/hooks/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/hooks/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/hooks/.svn/text-base/index.html.svn-base b/system/application/hooks/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/hooks/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/hooks/index.html b/system/application/hooks/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/hooks/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/index.html b/system/application/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/language/.svn/all-wcprops b/system/application/language/.svn/all-wcprops new file mode 100644 index 0000000..1cb01c7 --- /dev/null +++ b/system/application/language/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/application/language +END diff --git a/system/application/language/.svn/entries b/system/application/language/.svn/entries new file mode 100644 index 0000000..ac302fd --- /dev/null +++ b/system/application/language/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/language +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +english +dir + diff --git a/system/application/language/english/.svn/all-wcprops b/system/application/language/english/.svn/all-wcprops new file mode 100644 index 0000000..9d0173f --- /dev/null +++ b/system/application/language/english/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/application/language/english +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/application/language/english/index.html +END diff --git a/system/application/language/english/.svn/entries b/system/application/language/english/.svn/entries new file mode 100644 index 0000000..4ddc635 --- /dev/null +++ b/system/application/language/english/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/language/english +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:17:46.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/application/language/english/.svn/prop-base/index.html.svn-base b/system/application/language/english/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/language/english/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/language/english/.svn/text-base/index.html.svn-base b/system/application/language/english/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/language/english/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/language/english/index.html b/system/application/language/english/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/language/english/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/libraries/.svn/all-wcprops b/system/application/libraries/.svn/all-wcprops new file mode 100644 index 0000000..1b686d4 --- /dev/null +++ b/system/application/libraries/.svn/all-wcprops @@ -0,0 +1,53 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/124/trunk/system/application/libraries +END +sweetcron.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/124/trunk/system/application/libraries/sweetcron.php +END +page.php +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/18/trunk/system/application/libraries/page.php +END +auth.php +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/18/trunk/system/application/libraries/auth.php +END +markdown.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/application/libraries/markdown.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/application/libraries/index.html +END +sweetcron_item.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/124/trunk/system/application/libraries/sweetcron_item.php +END +simplepie.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/18/trunk/system/application/libraries/simplepie.php +END +MY_Controller.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/124/trunk/system/application/libraries/MY_Controller.php +END diff --git a/system/application/libraries/.svn/entries b/system/application/libraries/.svn/entries new file mode 100644 index 0000000..f42c751 --- /dev/null +++ b/system/application/libraries/.svn/entries @@ -0,0 +1,300 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/libraries +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +sweetcron.php +file + + + + +2009-09-15T00:17:59.000000Z +48dbd1806030f43605ba15ae008e7033 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +15659 + +page.php +file + + + + +2009-09-15T00:17:59.000000Z +50c32b2203293353f2812f29f2b3babd +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +7137 + +auth.php +file + + + + +2009-09-15T00:17:59.000000Z +976a91467ae5ff46255a75820587f476 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +3224 + +markdown.php +file + + + + +2009-09-15T00:17:59.000000Z +b97e901d3c07d7b998cd44ded00a5680 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +82461 + +index.html +file + + + + +2009-09-15T00:17:59.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +sweetcron_item.php +file + + + + +2009-09-15T00:17:59.000000Z +7cc5706c8485d3eb5702af717e6819a4 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +4605 + +simplepie.php +file + + + + +2009-09-15T00:17:59.000000Z +7028d3369d785dda97d5eed958e13378 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +348018 + +MY_Controller.php +file + + + + +2009-09-15T00:17:59.000000Z +f01707f6a0c2c66d00e24acf97fa2423 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +3356 + diff --git a/system/application/libraries/.svn/prop-base/index.html.svn-base b/system/application/libraries/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/libraries/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/libraries/.svn/text-base/MY_Controller.php.svn-base b/system/application/libraries/.svn/text-base/MY_Controller.php.svn-base new file mode 100644 index 0000000..de6f23b --- /dev/null +++ b/system/application/libraries/.svn/text-base/MY_Controller.php.svn-base @@ -0,0 +1,87 @@ +load->library('sweetcron'); + $this->load->file(BASEPATH.'/application/libraries/sweetcron_item.php'); + $this->sweetcron->compatibility_check(); + $this->sweetcron->integrity_check(); + + //load other stuff + $this->load->file(BASEPATH.'/application/libraries/markdown.php'); + $this->load->helper('text'); + $this->load->helper('url'); + $this->load->library('simplepie'); + $this->load->library('page'); + $this->load->model('feed_model'); + $this->load->model('item_model'); + $this->load->model('tag_model'); + $this->load->model('option_model'); + $this->load->helper('date'); + $this->load->library('auth'); + + //update last access + $option->option_name = 'last_access'; + $option->option_value = time(); + $this->option_model->add_option($option); + + //Set config items + $this->option_model->load_config_options(); + + //initiate pseudo-cron + $this->sweetcron->pseudo_cron(); + $this->data->user = $this->auth->get_user($this->session->userdata('user_id')); + } +} + +// Controllers accessible only by logged in users +class Auth_Controller extends Public_Controller { + function Auth_Controller() { + parent::Public_Controller(); + //OMG WHO R U + if ($this->data->user === FALSE) { + header('Location: '.$this->config->item('base_url').'admin/login'); + exit(); + } else { + return; + } + } +} \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/auth.php.svn-base b/system/application/libraries/.svn/text-base/auth.php.svn-base new file mode 100644 index 0000000..1883e6d --- /dev/null +++ b/system/application/libraries/.svn/text-base/auth.php.svn-base @@ -0,0 +1,103 @@ +CI =& get_instance(); + log_message('debug', 'Authorization class initialized.'); + + $this->CI->load->database(); + } + + /*** + Determines whether the passed condition is valid to login a user, if so - sets a session variable containing the user's ID + * @param $condition array The condition to query the database for + * @return boolean + ***/ + function try_login($condition = array()) { + $query = $this->CI->db->getwhere($this->db_table, $condition, 1, 0); + + if ($query->num_rows != 1) { return FALSE; } + + $row = $query->row(); + $this->CI->session->set_userdata(array('user_id' => $row->ID, 'call_user' => $row->user_login)); + + return $row; + } + + + /*** + Returns an object containing user information via the user's ID + * @param $id integer The user's ID + * @return object Upon valid user + * @return FALSE Upon invalid user + ***/ + function get_user($id = FALSE) { + if ($id == FALSE) $id = $this->CI->session->userdata('user_id'); + if ($id == FALSE) return FALSE; + + $condition = array(($this->db_table . '.' . $this->db_userid) => $id); + + $query = $this->CI->db->getwhere($this->db_table, $condition, 1, 0); + + $row = ($query->num_rows() == 1) ? $query->row() : FALSE; + + return $row; + } + + /*** + Logs out a user by deleting their session variables + * @return null + ***/ + function logout() { + $this->CI->session->set_userdata(array('user_id' => FALSE)); + header('Location: '.$this->CI->config->item('base_url')); + } + + function is_logged() + { + if ($this->CI->data->user === FALSE) { + return false; + } else { + return true; + } + } + + + // use $this->auth->permit('super_admin') at the start of non-visual functions to prevent hackery + // parameter can be a string role or an array of roles + // if user is not of correct role they see an error page - they would only see this if they were + // trying something malicious, i.e. trying to access functions that their role doesn't allow + function permit($permitted_role = null) + { + if ($permitted_role) { + if (is_array($permitted_role)) { + if (!in_array($this->CI->data->user->user_role, $permitted_role)) { + return false; + } else { + return true; + } + } else { + if ($this->CI->data->user->user_role != $permitted_role) { + return false; + } else { + return true; + } + } + } + } + +} \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/index.html.svn-base b/system/application/libraries/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/libraries/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/markdown.php.svn-base b/system/application/libraries/.svn/text-base/markdown.php.svn-base new file mode 100644 index 0000000..ed79197 --- /dev/null +++ b/system/application/libraries/.svn/text-base/markdown.php.svn-base @@ -0,0 +1,2894 @@ + +# +# Original Markdown +# Copyright (c) 2004-2006 John Gruber +# +# + + +define( 'MARKDOWN_VERSION', "1.0.1m" ); # Sat 21 Jun 2008 +define( 'MARKDOWNEXTRA_VERSION', "1.2.2" ); # Sat 21 Jun 2008 + + +# +# Global default settings: +# + +# Change to ">" for HTML output +@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />"); + +# Define the width of a tab for code blocks. +@define( 'MARKDOWN_TAB_WIDTH', 4 ); + +# Optional title attribute for footnote links and backlinks. +@define( 'MARKDOWN_FN_LINK_TITLE', "" ); +@define( 'MARKDOWN_FN_BACKLINK_TITLE', "" ); + +# Optional class attribute for footnote links and backlinks. +@define( 'MARKDOWN_FN_LINK_CLASS', "" ); +@define( 'MARKDOWN_FN_BACKLINK_CLASS', "" ); + + +# +# WordPress settings: +# + +# Change to false to remove Markdown from posts and/or comments. +@define( 'MARKDOWN_WP_POSTS', true ); +@define( 'MARKDOWN_WP_COMMENTS', true ); + + + +### Standard Function Interface ### + +@define( 'MARKDOWN_PARSER_CLASS', 'MarkdownExtra_Parser' ); + +function Markdown($text) { +# +# Initialize the parser and return the result of its transform method. +# + # Setup static parser variable. + static $parser; + if (!isset($parser)) { + $parser_class = MARKDOWN_PARSER_CLASS; + $parser = new $parser_class; + } + + # Transform text using parser. + return $parser->transform($text); +} + + +### WordPress Plugin Interface ### + +/* +Plugin Name: Markdown Extra +Plugin URI: http://www.michelf.com/projects/php-markdown/ +Description: Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More... +Version: 1.2.2 +Author: Michel Fortin +Author URI: http://www.michelf.com/ +*/ + +if (isset($wp_version)) { + # More details about how it works here: + # + + # Post content and excerpts + # - Remove WordPress paragraph generator. + # - Run Markdown on excerpt, then remove all tags. + # - Add paragraph tag around the excerpt, but remove it for the excerpt rss. + if (MARKDOWN_WP_POSTS) { + remove_filter('the_content', 'wpautop'); + remove_filter('the_content_rss', 'wpautop'); + remove_filter('the_excerpt', 'wpautop'); + add_filter('the_content', 'Markdown', 6); + add_filter('the_content_rss', 'Markdown', 6); + add_filter('get_the_excerpt', 'Markdown', 6); + add_filter('get_the_excerpt', 'trim', 7); + add_filter('the_excerpt', 'mdwp_add_p'); + add_filter('the_excerpt_rss', 'mdwp_strip_p'); + + remove_filter('content_save_pre', 'balanceTags', 50); + remove_filter('excerpt_save_pre', 'balanceTags', 50); + add_filter('the_content', 'balanceTags', 50); + add_filter('get_the_excerpt', 'balanceTags', 9); + } + + # Comments + # - Remove WordPress paragraph generator. + # - Remove WordPress auto-link generator. + # - Scramble important tags before passing them to the kses filter. + # - Run Markdown on excerpt then remove paragraph tags. + if (MARKDOWN_WP_COMMENTS) { + remove_filter('comment_text', 'wpautop', 30); + remove_filter('comment_text', 'make_clickable'); + add_filter('pre_comment_content', 'Markdown', 6); + add_filter('pre_comment_content', 'mdwp_hide_tags', 8); + add_filter('pre_comment_content', 'mdwp_show_tags', 12); + add_filter('get_comment_text', 'Markdown', 6); + add_filter('get_comment_excerpt', 'Markdown', 6); + add_filter('get_comment_excerpt', 'mdwp_strip_p', 7); + + global $mdwp_hidden_tags, $mdwp_placeholders; + $mdwp_hidden_tags = explode(' ', + '

 
  • '); + $mdwp_placeholders = explode(' ', str_rot13( + 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '. + 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli')); + } + + function mdwp_add_p($text) { + if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) { + $text = '

    '.$text.'

    '; + $text = preg_replace('{\n{2,}}', "

    \n\n

    ", $text); + } + return $text; + } + + function mdwp_strip_p($t) { return preg_replace('{}i', '', $t); } + + function mdwp_hide_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text); + } + function mdwp_show_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text); + } +} + + +### bBlog Plugin Info ### + +function identify_modifier_markdown() { + return array( + 'name' => 'markdown', + 'type' => 'modifier', + 'nicename' => 'PHP Markdown Extra', + 'description' => 'A text-to-HTML conversion tool for web writers', + 'authors' => 'Michel Fortin and John Gruber', + 'licence' => 'GPL', + 'version' => MARKDOWNEXTRA_VERSION, + 'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...', + ); +} + + +### Smarty Modifier Interface ### + +function smarty_modifier_markdown($text) { + return Markdown($text); +} + + +### Textile Compatibility Mode ### + +# Rename this file to "classTextile.php" and it can replace Textile everywhere. + +if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) { + # Try to include PHP SmartyPants. Should be in the same directory. + @include_once 'smartypants.php'; + # Fake Textile class. It calls Markdown instead. + class Textile { + function TextileThis($text, $lite='', $encode='') { + if ($lite == '' && $encode == '') $text = Markdown($text); + if (function_exists('SmartyPants')) $text = SmartyPants($text); + return $text; + } + # Fake restricted version: restrictions are not supported for now. + function TextileRestricted($text, $lite='', $noimage='') { + return $this->TextileThis($text, $lite); + } + # Workaround to ensure compatibility with TextPattern 4.0.3. + function blockLite($text) { return $text; } + } +} + + + +# +# Markdown Parser Class +# + +class Markdown_Parser { + + # Regex to match balanced [brackets]. + # Needed to insert a maximum bracked depth while converting to PHP. + var $nested_brackets_depth = 6; + var $nested_brackets_re; + + var $nested_url_parenthesis_depth = 4; + var $nested_url_parenthesis_re; + + # Table of hash values for escaped characters: + var $escape_chars = '\`*_{}[]()>#+-.!'; + var $escape_chars_re; + + # Change to ">" for HTML output. + var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX; + var $tab_width = MARKDOWN_TAB_WIDTH; + + # Change to `true` to disallow markup or entities. + var $no_markup = false; + var $no_entities = false; + + # Predefined urls and titles for reference links and images. + var $predef_urls = array(); + var $predef_titles = array(); + + + function Markdown_Parser() { + # + # Constructor function. Initialize appropriate member variables. + # + $this->_initDetab(); + $this->prepareItalicsAndBold(); + + $this->nested_brackets_re = + str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). + str_repeat('\])*', $this->nested_brackets_depth); + + $this->nested_url_parenthesis_re = + str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). + str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); + + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; + + # Sort document, block, and span gamut in ascendent priority order. + asort($this->document_gamut); + asort($this->block_gamut); + asort($this->span_gamut); + } + + + # Internal hashes used during transformation. + var $urls = array(); + var $titles = array(); + var $html_hashes = array(); + + # Status flag to avoid invalid nesting. + var $in_anchor = false; + + + function setup() { + # + # Called before the transformation process starts to setup parser + # states. + # + # Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; + $this->html_hashes = array(); + + $in_anchor = false; + } + + function teardown() { + # + # Called after the transformation process to clear any variable + # which may be taking up memory unnecessarly. + # + $this->urls = array(); + $this->titles = array(); + $this->html_hashes = array(); + } + + + function transform($text) { + # + # Main function. Performs some preprocessing on the input text + # and pass it through the document gamut. + # + $this->setup(); + + # Remove UTF-8 BOM and marker character in input, if present. + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # Standardize line endings: + # DOS to Unix and Mac to Unix + $text = preg_replace('{\r\n?}', "\n", $text); + + # Make sure $text ends with a couple of newlines: + $text .= "\n\n"; + + # Convert all tabs to spaces. + $text = $this->detab($text); + + # Turn block-level HTML blocks into hash entries + $text = $this->hashHTMLBlocks($text); + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ ]*\n+/ . + $text = preg_replace('/^[ ]+$/m', '', $text); + + # Run document gamut methods. + foreach ($this->document_gamut as $method => $priority) { + $text = $this->$method($text); + } + + $this->teardown(); + + return $text . "\n"; + } + + var $document_gamut = array( + # Strip link definitions, store in hashes. + "stripLinkDefinitions" => 20, + + "runBasicBlockGamut" => 30, + ); + + + function stripLinkDefinitions($text) { + # + # Strips link definitions from text, stores the URLs and titles in + # hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + ? # url = $2 + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $3 + [")] + [ ]* + )? # title is optional + (?:\n+|\Z) + }xm', + array(&$this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $this->urls[$link_id] = $matches[2]; + $this->titles[$link_id] =& $matches[3]; + return ''; # String that will replace the block + } + + + function hashHTMLBlocks($text) { + if ($this->no_markup) return $text; + + $less_than_tab = $this->tab_width - 1; + + # Hashify HTML blocks: + # We only want to do this for block-level HTML tags, such as headers, + # lists, and tables. That's because we still want to wrap

    s around + # "paragraphs" that are wrapped in non-block-level tags, such as anchors, + # phrase emphasis, and spans. The list of tags we're looking for is + # hard-coded: + # + # * List "a" is made of tags which can be both inline or block-level. + # These will be treated block-level when the start tag is alone on + # its line, otherwise they're not matched here and will be taken as + # inline later. + # * List "b" is made of tags which are always block-level; + # + $block_tags_a_re = 'ins|del'; + $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. + 'script|noscript|form|fieldset|iframe|math'; + + # Regular expression for the content of a block tag. + $nested_tags_level = 4; + $attr = ' + (?> # optional tag attributes + \s # starts with whitespace + (?> + [^>"/]+ # text outside quotes + | + /+(?!>) # slash not followed by ">" + | + "[^"]*" # text inside double quotes (tolerate ">") + | + \'[^\']*\' # text inside single quotes (tolerate ">") + )* + )? + '; + $content = + str_repeat(' + (?> + [^<]+ # content without tag + | + <\2 # nested opening tag + '.$attr.' # attributes + (?> + /> + | + >', $nested_tags_level). # end of opening tag + '.*?'. # last level nested tag content + str_repeat(' + # closing nested tag + ) + | + <(?!/\2\s*> # other tags with a different name + ) + )*', + $nested_tags_level); + $content2 = str_replace('\2', '\3', $content); + + # First, look for nested blocks, e.g.: + #

    + #
    + # tags for inner block must be indented. + #
    + #
    + # + # The outermost tags must start at the left margin for this to match, and + # the inner nested divs must be indented. + # We need to do this before the next, more liberal match, because the next + # match will start at the first `
    ` and stop at the first `
    `. + $text = preg_replace_callback('{(?> + (?> + (?<=\n\n) # Starting after a blank line + | # or + \A\n? # the beginning of the doc + ) + ( # save in $1 + + # Match from `\n` to `\n`, handling nested tags + # in between. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_b_re.')# start tag = $2 + '.$attr.'> # attributes followed by > and \n + '.$content.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special version for tags of group a. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_a_re.')# start tag = $3 + '.$attr.'>[ ]*\n # attributes followed by > + '.$content2.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special case just for
    . It was easier to make a special + # case than to make the other regex more complicated. + + [ ]{0,'.$less_than_tab.'} + <(hr) # start tag = $2 + '.$attr.' # attributes + /?> # the matching end tag + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # Special case for standalone HTML comments: + + [ ]{0,'.$less_than_tab.'} + (?s: + + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # PHP and ASP-style processor instructions ( + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + ) + )}Sxmi', + array(&$this, '_hashHTMLBlocks_callback'), + $text); + + return $text; + } + function _hashHTMLBlocks_callback($matches) { + $text = $matches[1]; + $key = $this->hashBlock($text); + return "\n\n$key\n\n"; + } + + + function hashPart($text, $boundary = 'X') { + # + # Called whenever a tag must be hashed when a function insert an atomic + # element in the text stream. Passing $text to through this function gives + # a unique text-token which will be reverted back when calling unhash. + # + # The $boundary argument specify what character should be used to surround + # the token. By convension, "B" is used for block elements that needs not + # to be wrapped into paragraph tags at the end, ":" is used for elements + # that are word separators and "X" is used in the general case. + # + # Swap back any tag hash found in $text so we do not have to `unhash` + # multiple times at the end. + $text = $this->unhash($text); + + # Then hash the block. + static $i = 0; + $key = "$boundary\x1A" . ++$i . $boundary; + $this->html_hashes[$key] = $text; + return $key; # String that will replace the tag. + } + + + function hashBlock($text) { + # + # Shortcut function for hashPart with block-level boundaries. + # + return $this->hashPart($text, 'B'); + } + + + var $block_gamut = array( + # + # These are all the transformations that form block-level + # tags like paragraphs, headers, and list items. + # + "doHeaders" => 10, + "doHorizontalRules" => 20, + + "doLists" => 40, + "doCodeBlocks" => 50, + "doBlockQuotes" => 60, + ); + + function runBlockGamut($text) { + # + # Run block gamut tranformations. + # + # We need to escape raw HTML in Markdown source before doing anything + # else. This need to be done for each block, and not only at the + # begining in the Markdown function since hashed blocks can be part of + # list items and could have been indented. Indented blocks would have + # been seen as a code block in a previous pass of hashHTMLBlocks. + $text = $this->hashHTMLBlocks($text); + + return $this->runBasicBlockGamut($text); + } + + function runBasicBlockGamut($text) { + # + # Run block gamut tranformations, without hashing HTML blocks. This is + # useful when HTML blocks are known to be already hashed, like in the first + # whole-document pass. + # + foreach ($this->block_gamut as $method => $priority) { + $text = $this->$method($text); + } + + # Finally form paragraph and restore hashed blocks. + $text = $this->formParagraphs($text); + + return $text; + } + + + function doHorizontalRules($text) { + # Do Horizontal Rules: + return preg_replace( + '{ + ^[ ]{0,3} # Leading space + ([-*_]) # $1: First marker + (?> # Repeated marker group + [ ]{0,2} # Zero, one, or two spaces. + \1 # Marker character + ){2,} # Group repeated at least twice + [ ]* # Tailing spaces + $ # End of line. + }mx', + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text); + } + + + var $span_gamut = array( + # + # These are all the transformations that occur *within* block-level + # tags like paragraphs, headers, and list items. + # + # Process character escapes, code spans, and inline HTML + # in one shot. + "parseSpan" => -30, + + # Process anchor and image tags. Images must come first, + # because ![foo][f] looks like an anchor. + "doImages" => 10, + "doAnchors" => 20, + + # Make links out of things like `` + # Must come after doAnchors, because you can use < and > + # delimiters in inline links like [this](). + "doAutoLinks" => 30, + "encodeAmpsAndAngles" => 40, + + "doItalicsAndBold" => 50, + "doHardBreaks" => 60, + ); + + function runSpanGamut($text) { + # + # Run span gamut tranformations. + # + foreach ($this->span_gamut as $method => $priority) { + $text = $this->$method($text); + } + + return $text; + } + + + function doHardBreaks($text) { + # Do hard breaks: + return preg_replace_callback('/ {2,}\n/', + array(&$this, '_doHardBreaks_callback'), $text); + } + function _doHardBreaks_callback($matches) { + return $this->hashPart("empty_element_suffix\n"); + } + + + function doAnchors($text) { + # + # Turn Markdown link shortcuts into XHTML tags. + # + if ($this->in_anchor) return $text; + $this->in_anchor = true; + + # + # First, handle reference-style links: [link text] [id] + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array(&$this, '_doAnchors_reference_callback'), $text); + + # + # Next, inline-style links: [link text](url "optional title") + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + \( # literal paren + [ ]* + (?: + <(\S*)> # href = $3 + | + ('.$this->nested_url_parenthesis_re.') # href = $4 + ) + [ ]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ ]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + ) + }xs', + array(&$this, '_DoAnchors_inline_callback'), $text); + + # + # Last, handle reference-style shortcuts: [link text] + # These must come last in case you've also got [link test][1] + # or [link test](/foo) + # +// $text = preg_replace_callback('{ +// ( # wrap whole match in $1 +// \[ +// ([^\[\]]+) # link text = $2; can\'t contain [ or ] +// \] +// ) +// }xs', +// array(&$this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + # for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + # lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } + else { + $result = $whole_match; + } + return $result; + } + function _doAnchors_inline_callback($matches) { + $whole_match = $matches[1]; + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $url = $this->encodeAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + + function doImages($text) { + # + # Turn Markdown image shortcuts into tags. + # + # + # First, handle reference-style labeled images: ![alt text][id] + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array(&$this, '_doImages_reference_callback'), $text); + + # + # Next, handle inline images: ![alt text](url "optional title") + # Don't forget: encode * and _ + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ ]* + (?: + <(\S*)> # src url = $3 + | + ('.$this->nested_url_parenthesis_re.') # src url = $4 + ) + [ ]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ ]* + )? # title is optional + \) + ) + }xs', + array(&$this, '_doImages_inline_callback'), $text); + + return $text; + } + function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); # for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } + else { + # If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; # $title already quoted + } + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + + function doHeaders($text) { + # Setext-style headers: + # Header 1 + # ======== + # + # Header 2 + # -------- + # + $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', + array(&$this, '_doHeaders_callback_setext'), $text); + + # atx-style headers: + # # Header 1 + # ## Header 2 + # ## Header 2 with closing hashes ## + # ... + # ###### Header 6 + # + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + \n+ + }xm', + array(&$this, '_doHeaders_callback_atx'), $text); + + return $text; + } + function _doHeaders_callback_setext($matches) { + # Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) + return $matches[0]; + + $level = $matches[2]{0} == '=' ? 1 : 2; + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + + function doLists($text) { + # + # Form HTML ordered (numbered) and unordered (bulleted) lists. + # + $less_than_tab = $this->tab_width - 1; + + # Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + + $markers_relist = array($marker_ul_re, $marker_ol_re); + + foreach ($markers_relist as $marker_re) { + # Re-usable pattern to match any entirel ul or ol list: + $whole_list_re = ' + ( # $1 = whole list + ( # $2 + [ ]{0,'.$less_than_tab.'} + ('.$marker_re.') # $3 = first list item marker + [ ]+ + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another list item marker + [ ]* + '.$marker_re.'[ ]+ + ) + ) + ) + '; // mx + + # We use a different prefix before nested lists than top-level lists. + # See extended comment in _ProcessListItems(). + + if ($this->list_level) { + $text = preg_replace_callback('{ + ^ + '.$whole_list_re.' + }mx', + array(&$this, '_doLists_callback'), $text); + } + else { + $text = preg_replace_callback('{ + (?:(?<=\n)\n|\A\n?) # Must eat the newline + '.$whole_list_re.' + }mx', + array(&$this, '_doLists_callback'), $text); + } + } + + return $text; + } + function _doLists_callback($matches) { + # Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + + $list = $matches[1]; + $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol"; + + $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); + + $list .= "\n"; + $result = $this->processListItems($list, $marker_any_re); + + $result = $this->hashBlock("<$list_type>\n" . $result . ""); + return "\n". $result ."\n\n"; + } + + var $list_level = 0; + + function processListItems($list_str, $marker_any_re) { + # + # Process the contents of a single ordered or unordered list, splitting it + # into individual list items. + # + # The $this->list_level global keeps track of when we're inside a list. + # Each time we enter a list, we increment it; when we leave a list, + # we decrement. If it's zero, we're not in a list anymore. + # + # We do this because when we're not inside a list, we want to treat + # something like this: + # + # I recommend upgrading to version + # 8. Oops, now this line is treated + # as a sub-list. + # + # As a single paragraph, despite the fact that the second line starts + # with a digit-period-space sequence. + # + # Whereas when we're inside a list (or sub-list), that line will be + # treated as the start of a sub-list. What a kludge, huh? This is + # an aspect of Markdown's syntax that's hard to parse perfectly + # without resorting to mind-reading. Perhaps the solution is to + # change the syntax rules such that sub-lists must start with a + # starting cardinal number; e.g. "1." or "a.". + + $this->list_level++; + + # trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + $list_str = preg_replace_callback('{ + (\n)? # leading line = $1 + (^[ ]*) # leading whitespace = $2 + ('.$marker_any_re.' # list marker and space = $3 + (?:[ ]+|(?=\n)) # space only required if item is not empty + ) + ((?s:.*?)) # list item text = $4 + (?:(\n+(?=\n))|\n) # tailing blank line = $5 + (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) + }xm', + array(&$this, '_processListItems_callback'), $list_str); + + $this->list_level--; + return $list_str; + } + function _processListItems_callback($matches) { + $item = $matches[4]; + $leading_line =& $matches[1]; + $leading_space =& $matches[2]; + $marker_space = $matches[3]; + $tailing_blank_line =& $matches[5]; + + if ($leading_line || $tailing_blank_line || + preg_match('/\n{2,}/', $item)) + { + # Replace marker with the appropriate whitespace indentation + $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; + $item = $this->runBlockGamut($this->outdent($item)."\n"); + } + else { + # Recursion for sub-lists: + $item = $this->doLists($this->outdent($item)); + $item = preg_replace('/\n+$/', '', $item); + $item = $this->runSpanGamut($item); + } + + return "
  • " . $item . "
  • \n"; + } + + + function doCodeBlocks($text) { + # + # Process Markdown `
    ` blocks.
    +	#
    +		$text = preg_replace_callback('{
    +				(?:\n\n|\A\n?)
    +				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    +				  (?>
    +					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    +					.*\n+
    +				  )+
    +				)
    +				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    +			}xm',
    +			array(&$this, '_doCodeBlocks_callback'), $text);
    +
    +		return $text;
    +	}
    +	function _doCodeBlocks_callback($matches) {
    +		$codeblock = $matches[1];
    +
    +		$codeblock = $this->outdent($codeblock);
    +		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    +
    +		# trim leading newlines and trailing newlines
    +		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    +
    +		$codeblock = "
    $codeblock\n
    "; + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + + + function makeCodeSpan($code) { + # + # Create a code span markup for $code. Called from handleSpanToken. + # + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + return $this->hashPart("$code"); + } + + + var $em_relist = array( + '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(?em_relist as $em => $em_re) { + foreach ($this->strong_relist as $strong => $strong_re) { + # Construct list of allowed token expressions. + $token_relist = array(); + if (isset($this->em_strong_relist["$em$strong"])) { + $token_relist[] = $this->em_strong_relist["$em$strong"]; + } + $token_relist[] = $em_re; + $token_relist[] = $strong_re; + + # Construct master expression from list. + $token_re = '{('. implode('|', $token_relist) .')}'; + $this->em_strong_prepared_relist["$em$strong"] = $token_re; + } + } + } + + function doItalicsAndBold($text) { + $token_stack = array(''); + $text_stack = array(''); + $em = ''; + $strong = ''; + $tree_char_em = false; + + while (1) { + # + # Get prepared regular expression for seraching emphasis tokens + # in current context. + # + $token_re = $this->em_strong_prepared_relist["$em$strong"]; + + # + # Each loop iteration seach for the next emphasis token. + # Each token is then passed to handleSpanToken. + # + $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + $text_stack[0] .= $parts[0]; + $token =& $parts[1]; + $text =& $parts[2]; + + if (empty($token)) { + # Reached end of text span: empty stack without emitting. + # any more emphasis. + while ($token_stack[0]) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + break; + } + + $token_len = strlen($token); + if ($tree_char_em) { + # Reached closing marker while inside a three-char emphasis. + if ($token_len == 3) { + # Three-char closing marker, close em and strong. + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + $strong = ''; + } else { + # Other closing marker: close one em or strong and + # change current token state to match the other + $token_stack[0] = str_repeat($token{0}, 3-$token_len); + $tag = $token_len == 2 ? "strong" : "em"; + $span = $text_stack[0]; + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] = $this->hashPart($span); + $$tag = ''; # $$tag stands for $em or $strong + } + $tree_char_em = false; + } else if ($token_len == 3) { + if ($em) { + # Reached closing marker for both em and strong. + # Closing strong marker: + for ($i = 0; $i < 2; ++$i) { + $shifted_token = array_shift($token_stack); + $tag = strlen($shifted_token) == 2 ? "strong" : "em"; + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] .= $this->hashPart($span); + $$tag = ''; # $$tag stands for $em or $strong + } + } else { + # Reached opening three-char emphasis marker. Push on token + # stack; will be handled by the special condition above. + $em = $token{0}; + $strong = "$em$em"; + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $tree_char_em = true; + } + } else if ($token_len == 2) { + if ($strong) { + # Unwind any dangling emphasis marker: + if (strlen($token_stack[0]) == 1) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + # Closing strong marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $strong = ''; + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $strong = $token; + } + } else { + # Here $token_len == 1 + if ($em) { + if (strlen($token_stack[0]) == 1) { + # Closing emphasis marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + } else { + $text_stack[0] .= $token; + } + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $em = $token; + } + } + } + return $text_stack[0]; + } + + + function doBlockQuotes($text) { + $text = preg_replace_callback('/ + ( # Wrap whole match in $1 + (?> + ^[ ]*>[ ]? # ">" at the start of a line + .+\n # rest of the first line + (.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + /xm', + array(&$this, '_doBlockQuotes_callback'), $text); + + return $text; + } + function _doBlockQuotes_callback($matches) { + $bq = $matches[1]; + # trim one level of quoting - trim whitespace-only lines + $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); + $bq = $this->runBlockGamut($bq); # recurse + + $bq = preg_replace('/^/m', " ", $bq); + # These leading spaces cause problem with
     content, 
    +		# so we need to fix that:
    +		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', + array(&$this, '_DoBlockQuotes_callback2'), $bq); + + return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; + } + function _doBlockQuotes_callback2($matches) { + $pre = $matches[1]; + $pre = preg_replace('/^ /m', '', $pre); + return $pre; + } + + + function formParagraphs($text) { + # + # Params: + # $text - string to process with html

    tags + # + # Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + # + # Wrap

    tags and unhashify HTML blocks + # + foreach ($grafs as $key => $value) { + if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { + # Is a paragraph. + $value = $this->runSpanGamut($value); + $value = preg_replace('/^([ ]*)/', "

    ", $value); + $value .= "

    "; + $grafs[$key] = $this->unhash($value); + } + else { + # Is a block. + # Modify elements of @grafs in-place... + $graf = $value; + $block = $this->html_hashes[$graf]; + $graf = $block; +// if (preg_match('{ +// \A +// ( # $1 =
    tag +//
    ]* +// \b +// markdown\s*=\s* ([\'"]) # $2 = attr quote char +// 1 +// \2 +// [^>]* +// > +// ) +// ( # $3 = contents +// .* +// ) +// (
    ) # $4 = closing tag +// \z +// }xs', $block, $matches)) +// { +// list(, $div_open, , $div_content, $div_close) = $matches; +// +// # We can't call Markdown(), because that resets the hash; +// # that initialization code should be pulled into its own sub, though. +// $div_content = $this->hashHTMLBlocks($div_content); +// +// # Run document gamut methods on the content. +// foreach ($this->document_gamut as $method => $priority) { +// $div_content = $this->$method($div_content); +// } +// +// $div_open = preg_replace( +// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); +// +// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; +// } + $grafs[$key] = $graf; + } + } + + return implode("\n\n", $grafs); + } + + + function encodeAttribute($text) { + # + # Encode text for a double-quoted HTML attribute. This function + # is *not* suitable for attributes enclosed in single quotes. + # + $text = $this->encodeAmpsAndAngles($text); + $text = str_replace('"', '"', $text); + return $text; + } + + + function encodeAmpsAndAngles($text) { + # + # Smart processing for ampersands and angle brackets that need to + # be encoded. Valid character entities are left alone unless the + # no-entities mode is set. + # + if ($this->no_entities) { + $text = str_replace('&', '&', $text); + } else { + # Ampersand-encoding based entirely on Nat Irons's Amputator + # MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + '&', $text);; + } + # Encode remaining <'s + $text = str_replace('<', '<', $text); + + return $text; + } + + + function doAutoLinks($text) { + $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', + array(&$this, '_doAutoLinks_url_callback'), $text); + + # Email addresses: + $text = preg_replace_callback('{ + < + (?:mailto:)? + ( + [-.\w\x80-\xFF]+ + \@ + [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ + ) + > + }xi', + array(&$this, '_doAutoLinks_email_callback'), $text); + + return $text; + } + function _doAutoLinks_url_callback($matches) { + $url = $this->encodeAttribute($matches[1]); + $link = "$url"; + return $this->hashPart($link); + } + function _doAutoLinks_email_callback($matches) { + $address = $matches[1]; + $link = $this->encodeEmailAddress($address); + return $this->hashPart($link); + } + + + function encodeEmailAddress($addr) { + # + # Input: an email address, e.g. "foo@example.com" + # + # Output: the email address as a mailto link, with each character + # of the address encoded as either a decimal or hex entity, in + # the hopes of foiling most address harvesting spam bots. E.g.: + # + #

    foo@exampl + # e.com

    + # + # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + # With some optimizations by Milian Wolff. + # + $addr = "mailto:" . $addr; + $chars = preg_split('/(? $char) { + $ord = ord($char); + # Ignore non-ascii chars. + if ($ord < 128) { + $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. + # roughly 10% raw, 45% hex, 45% dec + # '@' *must* be encoded. I insist. + if ($r > 90 && $char != '@') /* do nothing */; + else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; + else $chars[$key] = '&#'.$ord.';'; + } + } + + $addr = implode('', $chars); + $text = implode('', array_slice($chars, 7)); # text without `mailto:` + $addr = "$text"; + + return $addr; + } + + + function parseSpan($str) { + # + # Take the string $str and parse it into tokens, hashing embeded HTML, + # escaped characters and handling code spans. + # + $output = ''; + + $span_re = '{ + ( + \\\\'.$this->escape_chars_re.' + | + (?no_markup ? '' : ' + | + # comment + | + <\?.*?\?> | <%.*?%> # processing instruction + | + <[/!$]?[-a-zA-Z0-9:]+ # regular tags + (?> + \s + (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* + )? + > + ').' + ) + }xs'; + + while (1) { + # + # Each loop iteration seach for either the next tag, the next + # openning code span marker, or the next escaped character. + # Each token is then passed to handleSpanToken. + # + $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); + + # Create token from text preceding tag. + if ($parts[0] != "") { + $output .= $parts[0]; + } + + # Check if we reach the end. + if (isset($parts[1])) { + $output .= $this->handleSpanToken($parts[1], $parts[2]); + $str = $parts[2]; + } + else { + break; + } + } + + return $output; + } + + + function handleSpanToken($token, &$str) { + # + # Handle $token provided by parseSpan by determining its nature and + # returning the corresponding value that should replace it. + # + switch ($token{0}) { + case "\\": + return $this->hashPart("&#". ord($token{1}). ";"); + case "`": + # Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + $str, $matches)) + { + $str = $matches[2]; + $codespan = $this->makeCodeSpan($matches[1]); + return $this->hashPart($codespan); + } + return $token; // return as text since no ending marker found. + default: + return $this->hashPart($token); + } + } + + + function outdent($text) { + # + # Remove one level of line-leading tabs or spaces + # + return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); + } + + + # String length function for detab. `_initDetab` will create a function to + # hanlde UTF-8 if the default function does not exist. + var $utf8_strlen = 'mb_strlen'; + + function detab($text) { + # + # Replace tabs with the appropriate amount of space. + # + # For each line we separate the line in blocks delemited by + # tab characters. Then we reconstruct every line by adding the + # appropriate number of space between each blocks. + + $text = preg_replace_callback('/^.*\t.*$/m', + array(&$this, '_detab_callback'), $text); + + return $text; + } + function _detab_callback($matches) { + $line = $matches[0]; + $strlen = $this->utf8_strlen; # strlen function for UTF-8. + + # Split in blocks. + $blocks = explode("\t", $line); + # Add each blocks to the line. + $line = $blocks[0]; + unset($blocks[0]); # Do not add first block twice. + foreach ($blocks as $block) { + # Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - + $strlen($line, 'UTF-8') % $this->tab_width; + $line .= str_repeat(" ", $amount) . $block; + } + return $line; + } + function _initDetab() { + # + # Check for the availability of the function in the `utf8_strlen` property + # (initially `mb_strlen`). If the function is not available, create a + # function that will loosely count the number of UTF-8 characters with a + # regular expression. + # + if (function_exists($this->utf8_strlen)) return; + $this->utf8_strlen = create_function('$text', 'return preg_match_all( + "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", + $text, $m);'); + } + + + function unhash($text) { + # + # Swap back in all the tags hashed by _HashHTMLBlocks. + # + return preg_replace_callback('/(.)\x1A[0-9]+\1/', + array(&$this, '_unhash_callback'), $text); + } + function _unhash_callback($matches) { + return $this->html_hashes[$matches[0]]; + } + +} + + +# +# Markdown Extra Parser Class +# + +class MarkdownExtra_Parser extends Markdown_Parser { + + # Prefix for footnote ids. + var $fn_id_prefix = ""; + + # Optional title attribute for footnote links and backlinks. + var $fn_link_title = MARKDOWN_FN_LINK_TITLE; + var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE; + + # Optional class attribute for footnote links and backlinks. + var $fn_link_class = MARKDOWN_FN_LINK_CLASS; + var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS; + + # Predefined abbreviations. + var $predef_abbr = array(); + + + function MarkdownExtra_Parser() { + # + # Constructor function. Initialize the parser object. + # + # Add extra escapable characters before parent constructor + # initialize the table. + $this->escape_chars .= ':|'; + + # Insert extra document, block, and span transformations. + # Parent constructor will do the sorting. + $this->document_gamut += array( + "doFencedCodeBlocks" => 5, + "stripFootnotes" => 15, + "stripAbbreviations" => 25, + "appendFootnotes" => 50, + ); + $this->block_gamut += array( + "doFencedCodeBlocks" => 5, + "doTables" => 15, + "doDefLists" => 45, + ); + $this->span_gamut += array( + "doFootnotes" => 5, + "doAbbreviations" => 70, + ); + + parent::Markdown_Parser(); + } + + + # Extra variables used during extra transformations. + var $footnotes = array(); + var $footnotes_ordered = array(); + var $abbr_desciptions = array(); + var $abbr_word_re = ''; + + # Give the current footnote number. + var $footnote_counter = 1; + + + function setup() { + # + # Setting up Extra-specific variables. + # + parent::setup(); + + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + $this->footnote_counter = 1; + + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + } + } + + function teardown() { + # + # Clearing Extra-specific variables. + # + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + + parent::teardown(); + } + + + ### HTML Block Parser ### + + # Tags that are always treated as block tags: + var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; + + # Tags treated as block tags only if the opening tag is alone on it's line: + var $context_block_tags_re = 'script|noscript|math|ins|del'; + + # Tags where markdown="1" default to span mode: + var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; + + # Tags which must not have their contents modified, no matter where + # they appear: + var $clean_tags_re = 'script|math'; + + # Tags that do not need to be closed. + var $auto_close_tags_re = 'hr|img'; + + + function hashHTMLBlocks($text) { + # + # Hashify HTML Blocks and "clean tags". + # + # We only want to do this for block-level HTML tags, such as headers, + # lists, and tables. That's because we still want to wrap

    s around + # "paragraphs" that are wrapped in non-block-level tags, such as anchors, + # phrase emphasis, and spans. The list of tags we're looking for is + # hard-coded. + # + # This works by calling _HashHTMLBlocks_InMarkdown, which then calls + # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back + # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + # These two functions are calling each other. It's recursive! + # + # + # Call the HTML-in-Markdown hasher. + # + list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); + + return $text; + } + function _hashHTMLBlocks_inMarkdown($text, $indent = 0, + $enclosing_tag_re = '', $span = false) + { + # + # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + # + # * $indent is the number of space to be ignored when checking for code + # blocks. This is important because if we don't take the indent into + # account, something like this (which looks right) won't work as expected: + # + #

    + #
    + # Hello World. <-- Is this a Markdown code block or text? + #
    <-- Is this a Markdown code block or a real tag? + #
    + # + # If you don't like this, just don't indent the tag on which + # you apply the markdown="1" attribute. + # + # * If $enclosing_tag_re is not empty, stops at the first unmatched closing + # tag with that name. Nested tags supported. + # + # * If $span is true, text inside must treated as span. So any double + # newline will be replaced by a single newline so that it does not create + # paragraphs. + # + # Returns an array of that form: ( processed text , remaining text ) + # + if ($text === '') return array('', ''); + + # Regex to check for the presense of newlines around a block tag. + $newline_before_re = '/(?:^\n?|\n\n)*$/'; + $newline_after_re = + '{ + ^ # Start of text following the tag. + (?>[ ]*)? # Optional comment. + [ ]*\n # Must be followed by newline. + }xs'; + + # Regex to match any tag. + $block_tag_re = + '{ + ( # $2: Capture hole tag. + # Tag name. + '.$this->block_tags_re.' | + '.$this->context_block_tags_re.' | + '.$this->clean_tags_re.' | + (?!\s)'.$enclosing_tag_re.' + ) + (?: + (?=[\s"\'/]) # Allowed characters after tag name. + (?> + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + | + # Code span marker + `+ + '. ( !$span ? ' # If not in span. + | + # Indented code block + (?> ^[ ]*\n? | \n[ ]*\n ) + [ ]{'.($indent+4).'}[^\n]* \n + (?> + (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n + )* + | + # Fenced code block marker + (?> ^ | \n ) + [ ]{'.($indent).'}~~~+[ ]*\n + ' : '' ). ' # End (if not is span). + ) + }xs'; + + + $depth = 0; # Current depth inside the tag tree. + $parsed = ""; # Parsed text that will be returned. + + # + # Loop through every tag until we find the closing tag of the parent + # or loop until reaching the end of text if no parent tag specified. + # + do { + # + # Split the text using the first $tag_match pattern found. + # Text before pattern will be first in the array, text after + # pattern will be at the end, and between will be any catches made + # by the pattern. + # + $parts = preg_split($block_tag_re, $text, 2, + PREG_SPLIT_DELIM_CAPTURE); + + # If in Markdown span mode, add a empty-string span-level hash + # after each newline to prevent triggering any block element. + if ($span) { + $void = $this->hashPart("", ':'); + $newline = "$void\n"; + $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; + } + + $parsed .= $parts[0]; # Text before current tag. + + # If end of $text has been reached. Stop loop. + if (count($parts) < 3) { + $text = ""; + break; + } + + $tag = $parts[1]; # Tag to handle. + $text = $parts[2]; # Remaining text after current tag. + $tag_re = preg_quote($tag); # For use in a regular expression. + + # + # Check for: Code span marker + # + if ($tag{0} == "`") { + # Find corresponding end marker. + $tag_re = preg_quote($tag); + if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)+?'.$tag_re.' *\n}', $text, + $matches)) + { + # End marker found: pass text unchanged until marker. + $parsed .= $tag . $matches[0]; + $text = substr($text, strlen($matches[0])); + } + else { + # No end marker: just skip it. + $parsed .= $tag; + } + } + } + # + # Check for: Opening Block level tag or + # Opening Context Block tag (like ins and del) + # used as a block tag (tag is alone on it's line). + # + else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) || + ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && + preg_match($newline_before_re, $parsed) && + preg_match($newline_after_re, $text) ) + ) + { + # Need to parse tag and following text using the HTML parser. + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); + + # Make sure it stays outside of any paragraph by adding newlines. + $parsed .= "\n\n$block_text\n\n"; + } + # + # Check for: Clean tag (like script, math) + # HTML Comments, processing instructions. + # + else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + # Need to parse tag and following text using the HTML parser. + # (don't check for markdown attribute) + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); + + $parsed .= $block_text; + } + # + # Check for: Tag with same name as enclosing tag. + # + else if ($enclosing_tag_re !== '' && + # Same name as enclosing tag. + preg_match('{^= 0); + + return array($parsed, $text); + } + function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { + # + # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + # + # * Calls $hash_method to convert any blocks. + # * Stops when the first opening tag closes. + # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + # (it is not inside clean tags) + # + # Returns an array of that form: ( processed text , remaining text ) + # + if ($text === '') return array('', ''); + + # Regex to match `markdown` attribute inside of a tag. + $markdown_attr_re = ' + { + \s* # Eat whitespace before the `markdown` attribute + markdown + \s*=\s* + (?> + (["\']) # $1: quote delimiter + (.*?) # $2: attribute value + \1 # matching delimiter + | + ([^\s>]*) # $3: unquoted attribute value + ) + () # $4: make $3 always defined (avoid warnings) + }xs'; + + # Regex to match any tag. + $tag_re = '{ + ( # $2: Capture hole tag. + + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ) + }xs'; + + $original_text = $text; # Save original text in case of faliure. + + $depth = 0; # Current depth inside the tag tree. + $block_text = ""; # Temporary text holder for current text. + $parsed = ""; # Parsed text that will be returned. + + # + # Get the name of the starting tag. + # (This pattern makes $base_tag_name_re safe without quoting.) + # + if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) + $base_tag_name_re = $matches[1]; + + # + # Loop through every tag until we find the corresponding closing tag. + # + do { + # + # Split the text using the first $tag_match pattern found. + # Text before pattern will be first in the array, text after + # pattern will be at the end, and between will be any catches made + # by the pattern. + # + $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (count($parts) < 3) { + # + # End of $text reached with unbalenced tag(s). + # In that case, we return original text unchanged and pass the + # first character as filtered to prevent an infinite loop in the + # parent function. + # + return array($original_text{0}, substr($original_text, 1)); + } + + $block_text .= $parts[0]; # Text before current tag. + $tag = $parts[1]; # Tag to handle. + $text = $parts[2]; # Remaining text after current tag. + + # + # Check for: Auto-close tag (like
    ) + # Comments and Processing Instructions. + # + if (preg_match('{^auto_close_tags_re.')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + # Just add the tag to the block as if it was text. + $block_text .= $tag; + } + else { + # + # Increase/decrease nested tag count. Only do so if + # the tag's name match base tag's. + # + if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; + $span_mode = $this->mode == 'span' || $this->mode != 'block' && + preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); + + # Calculate indent before tag. + if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { + $strlen = $this->utf8_strlen; + $indent = $strlen($matches[1], 'UTF-8'); + } else { + $indent = 0; + } + + # End preceding block with this tag. + $block_text .= $tag; + $parsed .= $this->$hash_method($block_text); + + # Get enclosing tag name for the ParseMarkdown function. + # (This pattern makes $tag_name_re safe without quoting.) + preg_match('/^<([\w:$]*)\b/', $tag, $matches); + $tag_name_re = $matches[1]; + + # Parse the content using the HTML-in-Markdown parser. + list ($block_text, $text) + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + $tag_name_re, $span_mode); + + # Outdent markdown text. + if ($indent > 0) { + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text); + } + + # Append tag content to parsed text. + if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; + else $parsed .= "$block_text"; + + # Start over a new block. + $block_text = ""; + } + else $block_text .= $tag; + } + + } while ($depth > 0); + + # + # Hash last block text that wasn't processed inside the loop. + # + $parsed .= $this->$hash_method($block_text); + + return array($parsed, $text); + } + + + function hashClean($text) { + # + # Called whenever a tag must be hashed when a function insert a "clean" tag + # in $text, it pass through this function and is automaticaly escaped, + # blocking invalid nested overlap. + # + return $this->hashPart($text, 'C'); + } + + + function doHeaders($text) { + # + # Redefined to add id attribute support. + # + # Setext-style headers: + # Header 1 {#header1} + # ======== + # + # Header 2 {#header2} + # -------- + # + $text = preg_replace_callback( + '{ + (^.+?) # $1: Header text + (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute + [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer + }mx', + array(&$this, '_doHeaders_callback_setext'), $text); + + # atx-style headers: + # # Header 1 {#header1} + # ## Header 2 {#header2} + # ## Header 2 with closing hashes ## {#header3} + # ... + # ###### Header 6 {#header2} + # + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute + [ ]* + \n+ + }xm', + array(&$this, '_doHeaders_callback_atx'), $text); + + return $text; + } + function _doHeaders_attr($attr) { + if (empty($attr)) return ""; + return " id=\"$attr\""; + } + function _doHeaders_callback_setext($matches) { + if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) + return $matches[0]; + $level = $matches[3]{0} == '=' ? 1 : 2; + $attr = $this->_doHeaders_attr($id =& $matches[2]); + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + $attr = $this->_doHeaders_attr($id =& $matches[3]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + + function doTables($text) { + # + # Form HTML tables. + # + $less_than_tab = $this->tab_width - 1; + # + # Find tables with leading pipe. + # + # | Header 1 | Header 2 + # | -------- | -------- + # | Cell 1 | Cell 2 + # | Cell 3 | Cell 4 + # + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+) \n # $1: Header row (at least one pipe) + + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + [ ]* # Allowed whitespace. + [|] .* \n # Row content. + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array(&$this, '_doTable_leadingPipe_callback'), $text); + + # + # Find tables without leading pipe. + # + # Header 1 | Header 2 + # -------- | -------- + # Cell 1 | Cell 2 + # Cell 3 | Cell 4 + # + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + (\S.*[|].*) \n # $1: Header row (at least one pipe) + + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + .* [|] .* \n # Row content + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array(&$this, '_DoTable_callback'), $text); + + return $text; + } + function _doTable_leadingPipe_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + # Remove leading pipe for each row. + $content = preg_replace('/^ *[|]/m', '', $content); + + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + } + function _doTable_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + # Remove any tailing pipes for each line. + $head = preg_replace('/[|] *$/m', '', $head); + $underline = preg_replace('/[|] *$/m', '', $underline); + $content = preg_replace('/[|] *$/m', '', $content); + + # Reading alignement from header underline. + $separators = preg_split('/ *[|] */', $underline); + foreach ($separators as $n => $s) { + if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"'; + else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"'; + else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"'; + else $attr[$n] = ''; + } + + # Parsing span elements, including code spans, character escapes, + # and inline HTML tags, so that pipes inside those gets ignored. + $head = $this->parseSpan($head); + $headers = preg_split('/ *[|] */', $head); + $col_count = count($headers); + + # Write column headers. + $text = "\n"; + $text .= "\n"; + $text .= "\n"; + foreach ($headers as $n => $header) + $text .= " ".$this->runSpanGamut(trim($header))."\n"; + $text .= "\n"; + $text .= "\n"; + + # Split content by row. + $rows = explode("\n", trim($content, "\n")); + + $text .= "\n"; + foreach ($rows as $row) { + # Parsing span elements, including code spans, character escapes, + # and inline HTML tags, so that pipes inside those gets ignored. + $row = $this->parseSpan($row); + + # Split row by cell. + $row_cells = preg_split('/ *[|] */', $row, $col_count); + $row_cells = array_pad($row_cells, $col_count, ''); + + $text .= "\n"; + foreach ($row_cells as $n => $cell) + $text .= " ".$this->runSpanGamut(trim($cell))."\n"; + $text .= "\n"; + } + $text .= "\n"; + $text .= "
    "; + + return $this->hashBlock($text) . "\n"; + } + + + function doDefLists($text) { + # + # Form HTML definition lists. + # + $less_than_tab = $this->tab_width - 1; + + # Re-usable pattern to match any entire dl list: + $whole_list_re = '(?> + ( # $1 = whole list + ( # $2 + [ ]{0,'.$less_than_tab.'} + ((?>.*\S.*\n)+) # $3 = defined term + \n? + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another term + [ ]{0,'.$less_than_tab.'} + (?: \S.*\n )+? # defined term + \n? + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + (?! # Negative lookahead for another definition + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + ) + ) + )'; // mx + + $text = preg_replace_callback('{ + (?>\A\n?|(?<=\n\n)) + '.$whole_list_re.' + }mx', + array(&$this, '_doDefLists_callback'), $text); + + return $text; + } + function _doDefLists_callback($matches) { + # Re-usable patterns to match list item bullets and number markers: + $list = $matches[1]; + + # Turn double returns into triple returns, so that we can make a + # paragraph for the last item in a list, if necessary: + $result = trim($this->processDefListItems($list)); + $result = "
    \n" . $result . "\n
    "; + return $this->hashBlock($result) . "\n\n"; + } + + + function processDefListItems($list_str) { + # + # Process the contents of a single definition list, splitting it + # into individual term and definition list items. + # + $less_than_tab = $this->tab_width - 1; + + # trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + # Process definition terms. + $list_str = preg_replace_callback('{ + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,'.$less_than_tab.'} # leading whitespace + (?![:][ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. + }xm', + array(&$this, '_processDefListItems_callback_dt'), $list_str); + + # Process actual definitions. + $list_str = preg_replace_callback('{ + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,'.$less_than_tab.'} # whitespace before colon + [:][ ]+ # definition mark (colon) + ) + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,'.$less_than_tab.'} [:][ ] | +
    | \z + ) + ) + }xm', + array(&$this, '_processDefListItems_callback_dd'), $list_str); + + return $list_str; + } + function _processDefListItems_callback_dt($matches) { + $terms = explode("\n", trim($matches[1])); + $text = ''; + foreach ($terms as $term) { + $term = $this->runSpanGamut(trim($term)); + $text .= "\n
    " . $term . "
    "; + } + return $text . "\n"; + } + function _processDefListItems_callback_dd($matches) { + $leading_line = $matches[1]; + $marker_space = $matches[2]; + $def = $matches[3]; + + if ($leading_line || preg_match('/\n{2,}/', $def)) { + # Replace marker with the appropriate whitespace indentation + $def = str_repeat(' ', strlen($marker_space)) . $def; + $def = $this->runBlockGamut($this->outdent($def . "\n\n")); + $def = "\n". $def ."\n"; + } + else { + $def = rtrim($def); + $def = $this->runSpanGamut($this->outdent($def)); + } + + return "\n
    " . $def . "
    \n"; + } + + + function doFencedCodeBlocks($text) { + # + # Adding the fenced code block syntax to regular Markdown: + # + # ~~~ + # Code block + # ~~~ + # + $less_than_tab = $this->tab_width; + + $text = preg_replace_callback('{ + (?:\n|\A) + # 1: Opening marker + ( + ~{3,} # Marker: three tilde or more. + ) + [ ]* \n # Whitespace and newline following marker. + + # 2: Content + ( + (?> + (?!\1 [ ]* \n) # Not a closing marker. + .*\n+ + )+ + ) + + # Closing marker. + \1 [ ]* \n + }xm', + array(&$this, '_doFencedCodeBlocks_callback'), $text); + + return $text; + } + function _doFencedCodeBlocks_callback($matches) { + $codeblock = $matches[2]; + $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); + $codeblock = preg_replace_callback('/^\n+/', + array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); + $codeblock = "
    $codeblock
    "; + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + function _doFencedCodeBlocks_newlines($matches) { + return str_repeat("empty_element_suffix", + strlen($matches[0])); + } + + + # + # Redefining emphasis markers so that emphasis by underscore does not + # work in the middle of a word. + # + var $em_relist = array( + '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? tags + # + # Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + # + # Wrap

    tags and unhashify HTML blocks + # + foreach ($grafs as $key => $value) { + $value = trim($this->runSpanGamut($value)); + + # Check if this should be enclosed in a paragraph. + # Clean tag hashes & block tag hashes are left alone. + $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + + if ($is_p) { + $value = "

    $value

    "; + } + $grafs[$key] = $value; + } + + # Join grafs in one text, then unhash HTML tags. + $text = implode("\n\n", $grafs); + + # Finish by removing any tag hashes still present in $text. + $text = $this->unhash($text); + + return $text; + } + + + ### Footnotes + + function stripFootnotes($text) { + # + # Strips link definitions from text, stores the URLs and titles in + # hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: [^id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 + [ ]* + \n? # maybe *one* newline + ( # text = $2 (no blank lines allowed) + (?: + .+ # actual text + | + \n # newlines but + (?!\[\^.+?\]:\s)# negative lookahead for footnote marker. + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + # by non-indented content + )* + ) + }xm', + array(&$this, '_stripFootnotes_callback'), + $text); + return $text; + } + function _stripFootnotes_callback($matches) { + $note_id = $this->fn_id_prefix . $matches[1]; + $this->footnotes[$note_id] = $this->outdent($matches[2]); + return ''; # String that will replace the block + } + + + function doFootnotes($text) { + # + # Replace footnote references in $text [^id] with a special text-token + # which will be replaced by the actual footnote marker in appendFootnotes. + # + if (!$this->in_anchor) { + $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); + } + return $text; + } + + + function appendFootnotes($text) { + # + # Append footnote list to text. + # + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array(&$this, '_appendFootnotes_callback'), $text); + + if (!empty($this->footnotes_ordered)) { + $text .= "\n\n"; + $text .= "
    \n"; + $text .= "fn_backlink_class != "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_backlink_title != "") { + $title = $this->fn_backlink_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + $num = 0; + + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + + $footnote .= "\n"; # Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array(&$this, '_appendFootnotes_callback'), $footnote); + + $attr = str_replace("%%", ++$num, $attr); + $note_id = $this->encodeAttribute($note_id); + + # Add backlink to last paragraph; create new paragraph if needed. + $backlink = ""; + if (preg_match('{

    $}', $footnote)) { + $footnote = substr($footnote, 0, -4) . " $backlink

    "; + } else { + $footnote .= "\n\n

    $backlink

    "; + } + + $text .= "
  • \n"; + $text .= $footnote . "\n"; + $text .= "
  • \n\n"; + } + + $text .= "\n"; + $text .= "
    "; + } + return $text; + } + function _appendFootnotes_callback($matches) { + $node_id = $this->fn_id_prefix . $matches[1]; + + # Create footnote marker only if it has a corresponding footnote *and* + # the footnote hasn't been used by another marker. + if (isset($this->footnotes[$node_id])) { + # Transfert footnote content to the ordered list. + $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; + unset($this->footnotes[$node_id]); + + $num = $this->footnote_counter++; + $attr = " rel=\"footnote\""; + if ($this->fn_link_class != "") { + $class = $this->fn_link_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_link_title != "") { + $title = $this->fn_link_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + + $attr = str_replace("%%", $num, $attr); + $node_id = $this->encodeAttribute($node_id); + + return + "". + "$num". + ""; + } + + return "[^".$matches[1]."]"; + } + + + ### Abbreviations ### + + function stripAbbreviations($text) { + # + # Strips abbreviations from text, stores titles in hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: [id]*: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) + }xm', + array(&$this, '_stripAbbreviations_callback'), + $text); + return $text; + } + function _stripAbbreviations_callback($matches) { + $abbr_word = $matches[1]; + $abbr_desc = $matches[2]; + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + return ''; # String that will replace the block + } + + + function doAbbreviations($text) { + # + # Find defined abbreviations in text and wrap them in elements. + # + if ($this->abbr_word_re) { + // cannot use the /x modifier because abbr_word_re may + // contain significant spaces: + $text = preg_replace_callback('{'. + '(?abbr_word_re.')'. + '(?![\w\x1A])'. + '}', + array(&$this, '_doAbbreviations_callback'), $text); + } + return $text; + } + function _doAbbreviations_callback($matches) { + $abbr = $matches[0]; + if (isset($this->abbr_desciptions[$abbr])) { + $desc = $this->abbr_desciptions[$abbr]; + if (empty($desc)) { + return $this->hashPart("$abbr"); + } else { + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); + } + } else { + return $matches[0]; + } + } + +} + + +/* + +PHP Markdown Extra +================== + +Description +----------- + +This is a PHP port of the original Markdown formatter written in Perl +by John Gruber. This special "Extra" version of PHP Markdown features +further enhancements to the syntax for making additional constructs +such as tables and definition list. + +Markdown is a text-to-HTML filter; it translates an easy-to-read / +easy-to-write structured text format into HTML. Markdown's text format +is most similar to that of plain text email, and supports features such +as headers, *emphasis*, code blocks, blockquotes, and links. + +Markdown's syntax is designed not as a generic markup language, but +specifically to serve as a front-end to (X)HTML. You can use span-level +HTML tags anywhere in a Markdown document, and you can use block level +HTML tags (like
    and as well). + +For more information about Markdown's syntax, see: + + + + +Bugs +---- + +To file bug reports please send email to: + + + +Please include with your report: (1) the example input; (2) the output you +expected; (3) the output Markdown actually produced. + + +Version History +--------------- + +See the readme file for detailed release notes for this version. + + +Copyright and License +--------------------- + +PHP Markdown & Extra +Copyright (c) 2004-2008 Michel Fortin + +All rights reserved. + +Based on Markdown +Copyright (c) 2003-2006 John Gruber + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name "Markdown" nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as +is" and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. In no event shall the copyright owner +or contributors be liable for any direct, indirect, incidental, special, +exemplary, or consequential damages (including, but not limited to, +procurement of substitute goods or services; loss of use, data, or +profits; or business interruption) however caused and on any theory of +liability, whether in contract, strict liability, or tort (including +negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + +*/ +?> \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/page.php.svn-base b/system/application/libraries/.svn/text-base/page.php.svn-base new file mode 100644 index 0000000..e94d149 --- /dev/null +++ b/system/application/libraries/.svn/text-base/page.php.svn-base @@ -0,0 +1,210 @@ +currentPage = (integer) abs($reqCurrentPage); + } + + function SetItemCount($reqItemCount){ + $this->itemCount = (integer) abs($reqItemCount); + } + + function SetItemsPerPage($reqItemsPerPage){ + $this->itemsPerPage = (integer) abs($reqItemsPerPage); + } + + function SetLinksHref($reqLinksHref){ + $this->linksHref = $reqLinksHref; + } + + function SetLinksFormat($reqPageJumpBack, $reqPageSeparator, $reqPageJumpNext){ + $this->pageJumpBack = $reqPageJumpBack; + $this->pageSeparator = $reqPageSeparator; + $this->pageJumpNext = $reqPageJumpNext; + } + + function SetLinksToDisplay($reqLinksToDisplay){ + $this->linksToDisplay = (integer) abs($reqLinksToDisplay); + } + + function SetQueryStringVar($reqQueryStringVar){ + $this->queryStringVar = $reqQueryStringVar; + } + + function SetQueryString($reqQueryString){ + $this->queryString = $reqQueryString; + } + + function GetCurrentCollection($reqCollection){ + if($this->currentPage < 1){ + $start = 0; + } + elseif($this->currentPage > $this->GetPageCount()){ + $start = $this->GetPageCount() * $this->itemsPerPage - $this->itemsPerPage; + } + else { + $start = $this->currentPage * $this->itemsPerPage - $this->itemsPerPage; + } + + return array_slice($reqCollection, $start, $this->itemsPerPage); + } + + function GetPageCount(){ + return (integer)ceil($this->itemCount/$this->itemsPerPage); + } + + function GetPageLinks(){ + $strLinks = ''; + $pageCount = $this->GetPageCount(); + $queryString = $this->GetQueryString(); + $linksPad = floor($this->linksToDisplay/2); + + if($this->linksToDisplay == -1){ + $this->linksToDisplay = $pageCount; + } + + + if($pageCount == 0){ + $strLinks = '1'; + } + elseif($this->currentPage - 1 <= $linksPad || ($pageCount - $this->linksToDisplay + 1 == 0) || $this->linksToDisplay > $pageCount){ + $start = 1; + } + elseif($pageCount - $this->currentPage <= $linksPad){ + $start = $pageCount - $this->linksToDisplay + 1; + } + else { + $start = $this->currentPage - $linksPad; + } + + + if(isset($start)){ + if($start > 1){ + if(!empty($this->pageJumpBack)){ + $pageNum = $start - $this->linksToDisplay + $linksPad; + if($pageNum < 1){ + $pageNum = 1; + } + + $strLinks .= ''; + $strLinks .= $this->pageJumpBack.''.$this->pageSeparator; + } + + $strLinks .= '1...'.$this->pageSeparator; + } + + + if($start + $this->linksToDisplay > $pageCount){ + $end = $pageCount; + } + else { + $end = $start + $this->linksToDisplay - 1; + } + + + for($i = $start; $i <= $end; $i ++){ + if($i != $this->currentPage){ + $strLinks .= ''; + $strLinks .= ($i).''.$this->pageSeparator; + } + else { + $strLinks .= $i.$this->pageSeparator; + } + } + $strLinks = substr($strLinks, 0, -strlen($this->pageSeparator)); + + + if($start + $this->linksToDisplay - 1 < $pageCount){ + $strLinks .= $this->pageSeparator.''; + $strLinks .= '...'.$pageCount.''.$this->pageSeparator; + + if(!empty($this->pageJumpNext)){ + $pageNum = $start + $this->linksToDisplay + $linksPad; + if($pageNum > $pageCount){ + $pageNum = $pageCount; + } + + $strLinks .= ''; + $strLinks .= $this->pageJumpNext.''; + } + } + } + + + return $strLinks; + } + + function GetQueryString(){ + $pattern = array('/'.$this->queryStringVar.'=[^&]*&?/', '/&$/'); + $replace = array('', ''); + $queryString = preg_replace($pattern, $replace, $this->queryString); + $queryString = str_replace('&', '&', $queryString); + + if(!empty($queryString)){ + $queryString.= '&'; + } + + return "page/"; + } + + function GetSqlLimit(){ + return $this->itemsPerPage; + } + + function GetOffset(){ + return $this->currentPage * $this->itemsPerPage - $this->itemsPerPage; + } + + function GetLimit(){ + return $this->itemsPerPage; + } + + function __Construct(){ + $this->SetCurrentPage(1); + $this->SetItemsPerPage(10); + $this->SetItemCount(0); + $this->SetLinksFormat('« Back',' • ','Next »'); + $this->SetLinksHref($_SERVER['PHP_SELF']); + $this->SetLinksToDisplay(10); + $this->SetQueryStringVar('page'); + $this->SetQueryString($_SERVER['QUERY_STRING']); + + if(isset($_GET[$this->queryStringVar]) && is_numeric($_GET[$this->queryStringVar])){ + $this->SetCurrentPage($_GET[$this->queryStringVar]); + } + } +} + +?> \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/simplepie.php.svn-base b/system/application/libraries/.svn/text-base/simplepie.php.svn-base new file mode 100644 index 0000000..f5cd9a7 --- /dev/null +++ b/system/application/libraries/.svn/text-base/simplepie.php.svn-base @@ -0,0 +1,13284 @@ +' . SIMPLEPIE_NAME . ''); + +/** + * No Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_NONE', 0); + +/** + * Feed Link Element Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1); + +/** + * Local Feed Extension Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2); + +/** + * Local Feed Body Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4); + +/** + * Remote Feed Extension Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8); + +/** + * Remote Feed Body Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16); + +/** + * All Feed Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_ALL', 31); + +/** + * No known feed type + */ +define('SIMPLEPIE_TYPE_NONE', 0); + +/** + * RSS 0.90 + */ +define('SIMPLEPIE_TYPE_RSS_090', 1); + +/** + * RSS 0.91 (Netscape) + */ +define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2); + +/** + * RSS 0.91 (Userland) + */ +define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4); + +/** + * RSS 0.91 (both Netscape and Userland) + */ +define('SIMPLEPIE_TYPE_RSS_091', 6); + +/** + * RSS 0.92 + */ +define('SIMPLEPIE_TYPE_RSS_092', 8); + +/** + * RSS 0.93 + */ +define('SIMPLEPIE_TYPE_RSS_093', 16); + +/** + * RSS 0.94 + */ +define('SIMPLEPIE_TYPE_RSS_094', 32); + +/** + * RSS 1.0 + */ +define('SIMPLEPIE_TYPE_RSS_10', 64); + +/** + * RSS 2.0 + */ +define('SIMPLEPIE_TYPE_RSS_20', 128); + +/** + * RDF-based RSS + */ +define('SIMPLEPIE_TYPE_RSS_RDF', 65); + +/** + * Non-RDF-based RSS (truly intended as syndication format) + */ +define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190); + +/** + * All RSS + */ +define('SIMPLEPIE_TYPE_RSS_ALL', 255); + +/** + * Atom 0.3 + */ +define('SIMPLEPIE_TYPE_ATOM_03', 256); + +/** + * Atom 1.0 + */ +define('SIMPLEPIE_TYPE_ATOM_10', 512); + +/** + * All Atom + */ +define('SIMPLEPIE_TYPE_ATOM_ALL', 768); + +/** + * All feed types + */ +define('SIMPLEPIE_TYPE_ALL', 1023); + +/** + * No construct + */ +define('SIMPLEPIE_CONSTRUCT_NONE', 0); + +/** + * Text construct + */ +define('SIMPLEPIE_CONSTRUCT_TEXT', 1); + +/** + * HTML construct + */ +define('SIMPLEPIE_CONSTRUCT_HTML', 2); + +/** + * XHTML construct + */ +define('SIMPLEPIE_CONSTRUCT_XHTML', 4); + +/** + * base64-encoded construct + */ +define('SIMPLEPIE_CONSTRUCT_BASE64', 8); + +/** + * IRI construct + */ +define('SIMPLEPIE_CONSTRUCT_IRI', 16); + +/** + * A construct that might be HTML + */ +define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32); + +/** + * All constructs + */ +define('SIMPLEPIE_CONSTRUCT_ALL', 63); + +/** + * PCRE for HTML attributes + */ +define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*'); + +/** + * PCRE for XML attributes + */ +define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*'); + +/** + * XML Namespace + */ +define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace'); + +/** + * Atom 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom'); + +/** + * Atom 0.3 Namespace + */ +define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#'); + +/** + * RDF Namespace + */ +define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); + +/** + * RSS 0.90 Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/'); + +/** + * RSS 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/'); + +/** + * RSS 1.0 Content Module Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/'); + +/** + * DC 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/'); + +/** + * DC 1.1 Namespace + */ +define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/'); + +/** + * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace + */ +define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); + +/** + * GeoRSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss'); + +/** + * Media RSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/'); + +/** + * iTunes RSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); + +/** + * XHTML Namespace + */ +define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml'); + +/** + * IANA Link Relations Registry + */ +define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/'); + +/** + * Whether we're running on PHP5 + */ +define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>=')); + +/** + * No file source + */ +define('SIMPLEPIE_FILE_SOURCE_NONE', 0); + +/** + * Remote file source + */ +define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1); + +/** + * Local file source + */ +define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2); + +/** + * fsockopen() file source + */ +define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4); + +/** + * cURL file source + */ +define('SIMPLEPIE_FILE_SOURCE_CURL', 8); + +/** + * file_get_contents() file source + */ +define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); + +/** + * SimplePie + * + * @package SimplePie + * @version "Razzleberry" + * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon + * @author Ryan Parman + * @author Geoffrey Sneddon + * @todo Option for type of fetching (cache, not modified header, fetch, etc.) + */ +class SimplePie +{ + /** + * @var array Raw data + * @access private + */ + var $data = array(); + + /** + * @var mixed Error string + * @access private + */ + var $error; + + /** + * @var object Instance of SimplePie_Sanitize (or other class) + * @see SimplePie::set_sanitize_class() + * @access private + */ + var $sanitize; + + /** + * @var string SimplePie Useragent + * @see SimplePie::set_useragent() + * @access private + */ + var $useragent = SIMPLEPIE_USERAGENT; + + /** + * @var string Feed URL + * @see SimplePie::set_feed_url() + * @access private + */ + var $feed_url; + + /** + * @var object Instance of SimplePie_File to use as a feed + * @see SimplePie::set_file() + * @access private + */ + var $file; + + /** + * @var string Raw feed data + * @see SimplePie::set_raw_data() + * @access private + */ + var $raw_data; + + /** + * @var int Timeout for fetching remote files + * @see SimplePie::set_timeout() + * @access private + */ + var $timeout = 10; + + /** + * @var bool Forces fsockopen() to be used for remote files instead + * of cURL, even if a new enough version is installed + * @see SimplePie::force_fsockopen() + * @access private + */ + var $force_fsockopen = false; + + /** + * @var bool Force the given data/URL to be treated as a feed no matter what + * it appears like + * @see SimplePie::force_feed() + * @access private + */ + var $force_feed = false; + + /** + * @var bool Enable/Disable XML dump + * @see SimplePie::enable_xml_dump() + * @access private + */ + var $xml_dump = false; + + /** + * @var bool Enable/Disable Caching + * @see SimplePie::enable_cache() + * @access private + */ + var $cache = true; + + /** + * @var int Cache duration (in seconds) + * @see SimplePie::set_cache_duration() + * @access private + */ + var $cache_duration = 3600; + + /** + * @var int Auto-discovery cache duration (in seconds) + * @see SimplePie::set_autodiscovery_cache_duration() + * @access private + */ + var $autodiscovery_cache_duration = 604800; // 7 Days. + + /** + * @var string Cache location (relative to executing script) + * @see SimplePie::set_cache_location() + * @access private + */ + var $cache_location = './cache'; + + /** + * @var string Function that creates the cache filename + * @see SimplePie::set_cache_name_function() + * @access private + */ + var $cache_name_function = 'md5'; + + /** + * @var bool Reorder feed by date descending + * @see SimplePie::enable_order_by_date() + * @access private + */ + var $order_by_date = true; + + /** + * @var mixed Force input encoding to be set to the follow value + * (false, or anything type-cast to false, disables this feature) + * @see SimplePie::set_input_encoding() + * @access private + */ + var $input_encoding = false; + + /** + * @var int Feed Autodiscovery Level + * @see SimplePie::set_autodiscovery_level() + * @access private + */ + var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; + + /** + * @var string Class used for caching feeds + * @see SimplePie::set_cache_class() + * @access private + */ + var $cache_class = 'SimplePie_Cache'; + + /** + * @var string Class used for locating feeds + * @see SimplePie::set_locator_class() + * @access private + */ + var $locator_class = 'SimplePie_Locator'; + + /** + * @var string Class used for parsing feeds + * @see SimplePie::set_parser_class() + * @access private + */ + var $parser_class = 'SimplePie_Parser'; + + /** + * @var string Class used for fetching feeds + * @see SimplePie::set_file_class() + * @access private + */ + var $file_class = 'SimplePie_File'; + + /** + * @var string Class used for items + * @see SimplePie::set_item_class() + * @access private + */ + var $item_class = 'SimplePie_Item'; + + /** + * @var string Class used for authors + * @see SimplePie::set_author_class() + * @access private + */ + var $author_class = 'SimplePie_Author'; + + /** + * @var string Class used for categories + * @see SimplePie::set_category_class() + * @access private + */ + var $category_class = 'SimplePie_Category'; + + /** + * @var string Class used for enclosures + * @see SimplePie::set_enclosures_class() + * @access private + */ + var $enclosure_class = 'SimplePie_Enclosure'; + + /** + * @var string Class used for Media RSS captions + * @see SimplePie::set_caption_class() + * @access private + */ + var $caption_class = 'SimplePie_Caption'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_copyright_class() + * @access private + */ + var $copyright_class = 'SimplePie_Copyright'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_credit_class() + * @access private + */ + var $credit_class = 'SimplePie_Credit'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_rating_class() + * @access private + */ + var $rating_class = 'SimplePie_Rating'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_restriction_class() + * @access private + */ + var $restriction_class = 'SimplePie_Restriction'; + + /** + * @var string Class used for content-type sniffing + * @see SimplePie::set_content_type_sniffer_class() + * @access private + */ + var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; + + /** + * @var string Class used for item sources. + * @see SimplePie::set_source_class() + * @access private + */ + var $source_class = 'SimplePie_Source'; + + /** + * @var mixed Set javascript query string parameter (false, or + * anything type-cast to false, disables this feature) + * @see SimplePie::set_javascript() + * @access private + */ + var $javascript = 'js'; + + /** + * @var int Maximum number of feeds to check with autodiscovery + * @see SimplePie::set_max_checked_feeds() + * @access private + */ + var $max_checked_feeds = 10; + + /** + * @var string Web-accessible path to the handler_favicon.php file. + * @see SimplePie::set_favicon_handler() + * @access private + */ + var $favicon_handler = ''; + + /** + * @var string Web-accessible path to the handler_image.php file. + * @see SimplePie::set_image_handler() + * @access private + */ + var $image_handler = ''; + + /** + * @var array Stores the URLs when multiple feeds are being initialized. + * @see SimplePie::set_feed_url() + * @access private + */ + var $multifeed_url = array(); + + /** + * @var array Stores SimplePie objects when multiple feeds initialized. + * @access private + */ + var $multifeed_objects = array(); + + /** + * @var array Stores the get_object_vars() array for use with multifeeds. + * @see SimplePie::set_feed_url() + * @access private + */ + var $config_settings = null; + + /** + * @var integer Stores the number of items to return per-feed with multifeeds. + * @see SimplePie::set_item_limit() + * @access private + */ + var $item_limit = 0; + + /** + * @var array Stores the default attributes to be stripped by strip_attributes(). + * @see SimplePie::strip_attributes() + * @access private + */ + var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); + + /** + * @var array Stores the default tags to be stripped by strip_htmltags(). + * @see SimplePie::strip_htmltags() + * @access private + */ + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + + /** + * The SimplePie class contains feed level data and options + * + * There are two ways that you can create a new SimplePie object. The first + * is by passing a feed URL as a parameter to the SimplePie constructor + * (as well as optionally setting the cache location and cache expiry). This + * will initialise the whole feed with all of the default settings, and you + * can begin accessing methods and properties immediately. + * + * The second way is to create the SimplePie object with no parameters + * at all. This will enable you to set configuration options. After setting + * them, you must initialise the feed using $feed->init(). At that point the + * object's methods and properties will be available to you. This format is + * what is used throughout this documentation. + * + * @access public + * @since 1.0 Preview Release + * @param string $feed_url This is the URL you want to parse. + * @param string $cache_location This is where you want the cache to be stored. + * @param int $cache_duration This is the number of seconds that you want to store the cache file for. + */ + function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) + { + // Other objects, instances created here so we can set options on them + $this->sanitize =& new SimplePie_Sanitize; + + // Set options if they're passed to the constructor + if ($cache_location !== null) + { + $this->set_cache_location($cache_location); + } + + if ($cache_duration !== null) + { + $this->set_cache_duration($cache_duration); + } + + // Only init the script if we're passed a feed URL + if ($feed_url !== null) + { + $this->set_feed_url($feed_url); + $this->init(); + } + } + + /** + * Used for converting object to a string + */ + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + if (!empty($this->data['items'])) + { + foreach ($this->data['items'] as $item) + { + $item->__destruct(); + } + unset($this->data['items']); + } + if (!empty($this->data['ordered_items'])) + { + foreach ($this->data['ordered_items'] as $item) + { + $item->__destruct(); + } + unset($this->data['ordered_items']); + } + } + + /** + * Force the given data/URL to be treated as a feed no matter what it + * appears like + * + * @access public + * @since 1.1 + * @param bool $enable Force the given data/URL to be treated as a feed + */ + function force_feed($enable = false) + { + $this->force_feed = (bool) $enable; + } + + /** + * This is the URL of the feed you want to parse. + * + * This allows you to enter the URL of the feed you want to parse, or the + * website you want to try to use auto-discovery on. This takes priority + * over any set raw data. + * + * You can set multiple feeds to mash together by passing an array instead + * of a string for the $url. Remember that with each additional feed comes + * additional processing and resources. + * + * @access public + * @since 1.0 Preview Release + * @param mixed $url This is the URL (or array of URLs) that you want to parse. + * @see SimplePie::set_raw_data() + */ + function set_feed_url($url) + { + if (is_array($url)) + { + $this->multifeed_url = array(); + foreach ($url as $value) + { + $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1); + } + } + else + { + $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); + } + } + + /** + * Provides an instance of SimplePie_File to use as a feed + * + * @access public + * @param object &$file Instance of SimplePie_File (or subclass) + * @return bool True on success, false on failure + */ + function set_file(&$file) + { + if (is_a($file, 'SimplePie_File')) + { + $this->feed_url = $file->url; + $this->file =& $file; + return true; + } + return false; + } + + /** + * Allows you to use a string of RSS/Atom data instead of a remote feed. + * + * If you have a feed available as a string in PHP, you can tell SimplePie + * to parse that data string instead of a remote feed. Any set feed URL + * takes precedence. + * + * @access public + * @since 1.0 Beta 3 + * @param string $data RSS or Atom data as a string. + * @see SimplePie::set_feed_url() + */ + function set_raw_data($data) + { + $this->raw_data = trim($data); + } + + /** + * Allows you to override the default timeout for fetching remote feeds. + * + * This allows you to change the maximum time the feed's server to respond + * and send the feed back. + * + * @access public + * @since 1.0 Beta 3 + * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. + */ + function set_timeout($timeout = 10) + { + $this->timeout = (int) $timeout; + } + + /** + * Forces SimplePie to use fsockopen() instead of the preferred cURL + * functions. + * + * @access public + * @since 1.0 Beta 3 + * @param bool $enable Force fsockopen() to be used + */ + function force_fsockopen($enable = false) + { + $this->force_fsockopen = (bool) $enable; + } + + /** + * Outputs the raw XML content of the feed, after it has gone through + * SimplePie's filters. + * + * Used only for debugging, this function will output the XML content as + * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up + * before trying to parse it. Many parts of the feed are re-written in + * memory, and in the end, you have a parsable feed. XML dump shows you the + * actual XML that SimplePie tries to parse, which may or may not be very + * different from the original feed. + * + * @access public + * @since 1.0 Preview Release + * @param bool $enable Enable XML dump + */ + function enable_xml_dump($enable = false) + { + $this->xml_dump = (bool) $enable; + } + + /** + * Enables/disables caching in SimplePie. + * + * This option allows you to disable caching all-together in SimplePie. + * However, disabling the cache can lead to longer load times. + * + * @access public + * @since 1.0 Preview Release + * @param bool $enable Enable caching + */ + function enable_cache($enable = true) + { + $this->cache = (bool) $enable; + } + + /** + * Set the length of time (in seconds) that the contents of a feed + * will be cached. + * + * @access public + * @param int $seconds The feed content cache duration. + */ + function set_cache_duration($seconds = 3600) + { + $this->cache_duration = (int) $seconds; + } + + /** + * Set the length of time (in seconds) that the autodiscovered feed + * URL will be cached. + * + * @access public + * @param int $seconds The autodiscovered feed URL cache duration. + */ + function set_autodiscovery_cache_duration($seconds = 604800) + { + $this->autodiscovery_cache_duration = (int) $seconds; + } + + /** + * Set the file system location where the cached files should be stored. + * + * @access public + * @param string $location The file system location. + */ + function set_cache_location($location = './cache') + { + $this->cache_location = (string) $location; + } + + /** + * Determines whether feed items should be sorted into reverse chronological order. + * + * @access public + * @param bool $enable Sort as reverse chronological order. + */ + function enable_order_by_date($enable = true) + { + $this->order_by_date = (bool) $enable; + } + + /** + * Allows you to override the character encoding reported by the feed. + * + * @access public + * @param string $encoding Character encoding. + */ + function set_input_encoding($encoding = false) + { + if ($encoding) + { + $this->input_encoding = (string) $encoding; + } + else + { + $this->input_encoding = false; + } + } + + /** + * Set how much feed autodiscovery to do + * + * @access public + * @see SIMPLEPIE_LOCATOR_NONE + * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY + * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION + * @see SIMPLEPIE_LOCATOR_LOCAL_BODY + * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION + * @see SIMPLEPIE_LOCATOR_REMOTE_BODY + * @see SIMPLEPIE_LOCATOR_ALL + * @param int $level Feed Autodiscovery Level (level can be a + * combination of the above constants, see bitwise OR operator) + */ + function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) + { + $this->autodiscovery = (int) $level; + } + + /** + * Allows you to change which class SimplePie uses for caching. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_cache_class($class = 'SimplePie_Cache') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) + { + $this->cache_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for auto-discovery. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_locator_class($class = 'SimplePie_Locator') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) + { + $this->locator_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for XML parsing. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_parser_class($class = 'SimplePie_Parser') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) + { + $this->parser_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for remote file fetching. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_file_class($class = 'SimplePie_File') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) + { + $this->file_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for data sanitization. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_sanitize_class($class = 'SimplePie_Sanitize') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) + { + $this->sanitize =& new $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling feed items. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_item_class($class = 'SimplePie_Item') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) + { + $this->item_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling author data. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_author_class($class = 'SimplePie_Author') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) + { + $this->author_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling category data. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_category_class($class = 'SimplePie_Category') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) + { + $this->category_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for feed enclosures. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_enclosure_class($class = 'SimplePie_Enclosure') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) + { + $this->enclosure_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for captions + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_caption_class($class = 'SimplePie_Caption') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) + { + $this->caption_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_copyright_class($class = 'SimplePie_Copyright') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) + { + $this->copyright_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_credit_class($class = 'SimplePie_Credit') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) + { + $this->credit_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_rating_class($class = 'SimplePie_Rating') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) + { + $this->rating_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_restriction_class($class = 'SimplePie_Restriction') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) + { + $this->restriction_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for content-type sniffing. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) + { + $this->content_type_sniffer_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses item sources. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_source_class($class = 'SimplePie_Source') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) + { + $this->source_class = $class; + return true; + } + return false; + } + + /** + * Allows you to override the default user agent string. + * + * @access public + * @param string $ua New user agent string. + */ + function set_useragent($ua = SIMPLEPIE_USERAGENT) + { + $this->useragent = (string) $ua; + } + + /** + * Set callback function to create cache filename with + * + * @access public + * @param mixed $function Callback function + */ + function set_cache_name_function($function = 'md5') + { + if (is_callable($function)) + { + $this->cache_name_function = $function; + } + } + + /** + * Set javascript query string parameter + * + * @access public + * @param mixed $get Javascript query string parameter + */ + function set_javascript($get = 'js') + { + if ($get) + { + $this->javascript = (string) $get; + } + else + { + $this->javascript = false; + } + } + + /** + * Set options to make SP as fast as possible. Forgoes a + * substantial amount of data sanitization in favor of speed. + * + * @access public + * @param bool $set Whether to set them or not + */ + function set_stupidly_fast($set = false) + { + if ($set) + { + $this->enable_order_by_date(false); + $this->remove_div(false); + $this->strip_comments(false); + $this->strip_htmltags(false); + $this->strip_attributes(false); + $this->set_image_handler(false); + } + } + + /** + * Set maximum number of feeds to check with autodiscovery + * + * @access public + * @param int $max Maximum number of feeds to check + */ + function set_max_checked_feeds($max = 10) + { + $this->max_checked_feeds = (int) $max; + } + + function remove_div($enable = true) + { + $this->sanitize->remove_div($enable); + } + + function strip_htmltags($tags = '', $encode = null) + { + if ($tags === '') + { + $tags = $this->strip_htmltags; + } + $this->sanitize->strip_htmltags($tags); + if ($encode !== null) + { + $this->sanitize->encode_instead_of_strip($tags); + } + } + + function encode_instead_of_strip($enable = true) + { + $this->sanitize->encode_instead_of_strip($enable); + } + + function strip_attributes($attribs = '') + { + if ($attribs === '') + { + $attribs = $this->strip_attributes; + } + $this->sanitize->strip_attributes($attribs); + } + + function set_output_encoding($encoding = 'UTF-8') + { + $this->sanitize->set_output_encoding($encoding); + } + + function strip_comments($strip = false) + { + $this->sanitize->strip_comments($strip); + } + + /** + * Set element/attribute key/value pairs of HTML attributes + * containing URLs that need to be resolved relative to the feed + * + * @access public + * @since 1.0 + * @param array $element_attribute Element/attribute key/value pairs + */ + function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) + { + $this->sanitize->set_url_replacements($element_attribute); + } + + /** + * Set the handler to enable the display of cached favicons. + * + * @access public + * @param str $page Web-accessible path to the handler_favicon.php file. + * @param str $qs The query string that the value should be passed to. + */ + function set_favicon_handler($page = false, $qs = 'i') + { + if ($page != false) + { + $this->favicon_handler = $page . '?' . $qs . '='; + } + else + { + $this->favicon_handler = ''; + } + } + + /** + * Set the handler to enable the display of cached images. + * + * @access public + * @param str $page Web-accessible path to the handler_image.php file. + * @param str $qs The query string that the value should be passed to. + */ + function set_image_handler($page = false, $qs = 'i') + { + if ($page != false) + { + $this->sanitize->set_image_handler($page . '?' . $qs . '='); + } + else + { + $this->image_handler = ''; + } + } + + /** + * Set the limit for items returned per-feed with multifeeds. + * + * @access public + * @param integer $limit The maximum number of items to return. + */ + function set_item_limit($limit = 0) + { + $this->item_limit = (int) $limit; + } + + function init() + { + if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre')) + { + return false; + } + if (isset($_GET[$this->javascript])) + { + if (function_exists('ob_gzhandler')) + { + ob_start('ob_gzhandler'); + } + header('Content-type: text/javascript; charset: UTF-8'); + header('Cache-Control: must-revalidate'); + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days + ?> +function embed_odeo(link) { + document.writeln(''); +} + +function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) { + if (placeholder != '') { + document.writeln(''); + } + else { + document.writeln(''); + } +} + +function embed_flash(bgcolor, width, height, link, loop, type) { + document.writeln(''); +} + +function embed_flv(width, height, link, placeholder, loop, player) { + document.writeln(''); +} + +function embed_wmedia(width, height, link) { + document.writeln(''); +} + sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); + $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); + + if ($this->feed_url !== null || $this->raw_data !== null) + { + $this->data = array(); + $this->multifeed_objects = array(); + $cache = false; + + if ($this->feed_url !== null) + { + $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); + // Decide whether to enable caching + if ($this->cache && $parsed_feed_url['scheme'] !== '') + { + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); + } + // If it's enabled and we don't want an XML dump, use the cache + if ($cache && !$this->xml_dump) + { + // Load the Cache + $this->data = $cache->load(); + if (!empty($this->data)) + { + // If the cache is for an outdated build of SimplePie + if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD) + { + $cache->unlink(); + $this->data = array(); + } + // If we've hit a collision just rerun it with caching disabled + elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url) + { + $cache = false; + $this->data = array(); + } + // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. + elseif (isset($this->data['feed_url'])) + { + // If the autodiscovery cache is still valid use it. + if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) + { + // Do not need to do feed autodiscovery yet. + if ($this->data['feed_url'] == $this->data['url']) + { + $cache->unlink(); + $this->data = array(); + } + else + { + $this->set_feed_url($this->data['feed_url']); + return $this->init(); + } + } + } + // Check if the cache has been updated + elseif ($cache->mtime() + $this->cache_duration < time()) + { + // If we have last-modified and/or etag set + if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) + { + $headers = array(); + if (isset($this->data['headers']['last-modified'])) + { + $headers['if-modified-since'] = $this->data['headers']['last-modified']; + } + if (isset($this->data['headers']['etag'])) + { + $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; + } + $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); + if ($file->success) + { + if ($file->status_code == 304) + { + $cache->touch(); + return true; + } + else + { + $headers = $file->headers; + } + } + else + { + unset($file); + } + } + } + // If the cache is still valid, just return true + else + { + return true; + } + } + // If the cache is empty, delete it + else + { + $cache->unlink(); + $this->data = array(); + } + } + // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. + if (!isset($file)) + { + if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url) + { + $file =& $this->file; + } + else + { + $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); + } + } + // If the file connection has an error, set SimplePie::error to that and quit + if (!$file->success) + { + $this->error = $file->error; + if (!empty($this->data)) + { + return true; + } + else + { + return false; + } + } + + if (!$this->force_feed) + { + // Check if the supplied URL is a feed, if it isn't, look for it. + $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); + if (!$locate->is_feed($file)) + { + // We need to unset this so that if SimplePie::set_file() has been called that object is untouched + unset($file); + if ($file = $locate->find($this->autodiscovery)) + { + if ($cache) + { + $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); + if (!$cache->save($this)) + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); + } + $this->feed_url = $file->url; + } + else + { + $this->error = "A feed could not be found at $this->feed_url"; + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + } + $locate = null; + } + + $headers = $file->headers; + $data = $file->body; + $sniffer = new $this->content_type_sniffer_class($file); + $sniffed = $sniffer->get_type(); + } + else + { + $data = $this->raw_data; + } + + // Set up array of possible encodings + $encodings = array(); + + // First check to see if input has been overridden. + if ($this->input_encoding !== false) + { + $encodings[] = $this->input_encoding; + } + + $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); + $text_types = array('text/xml', 'text/xml-external-parsed-entity'); + + // RFC 3023 (only applies to sniffed content) + if (isset($sniffed)) + { + if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') + { + if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) + { + $encodings[] = strtoupper($charset[1]); + } + $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); + $encodings[] = 'UTF-8'; + } + elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') + { + if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) + { + $encodings[] = $charset[1]; + } + $encodings[] = 'US-ASCII'; + } + // Text MIME-type default + elseif (substr($sniffed, 0, 5) === 'text/') + { + $encodings[] = 'US-ASCII'; + } + } + + // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 + $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); + $encodings[] = 'UTF-8'; + $encodings[] = 'ISO-8859-1'; + + // There's no point in trying an encoding twice + $encodings = array_unique($encodings); + + // If we want the XML, just output that with the most likely encoding and quit + if ($this->xml_dump) + { + header('Content-type: text/xml; charset=' . $encodings[0]); + echo $data; + exit; + } + + // Loop through each possible encoding, till we return something, or run out of possibilities + foreach ($encodings as $encoding) + { + // Change the encoding to UTF-8 (as we always use UTF-8 internally) + $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'); + + // Create new parser + $parser =& new $this->parser_class(); + + // If it's parsed fine + if ($parser->parse($utf8_data, 'UTF-8')) + { + $this->data = $parser->get_data(); + if (isset($this->data['child'])) + { + if (isset($headers)) + { + $this->data['headers'] = $headers; + } + $this->data['build'] = SIMPLEPIE_BUILD; + + // Cache the file if caching is enabled + if ($cache && !$cache->save($this)) + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + return true; + } + else + { + $this->error = "A feed could not be found at $this->feed_url"; + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + } + } + // We have an error, just set SimplePie::error to it and quit + $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + elseif (!empty($this->multifeed_url)) + { + $i = 0; + $success = 0; + $this->multifeed_objects = array(); + foreach ($this->multifeed_url as $url) + { + if (SIMPLEPIE_PHP5) + { + // This keyword needs to defy coding standards for PHP4 compatibility + $this->multifeed_objects[$i] = clone($this); + } + else + { + $this->multifeed_objects[$i] = $this; + } + $this->multifeed_objects[$i]->set_feed_url($url); + $success |= $this->multifeed_objects[$i]->init(); + $i++; + } + return (bool) $success; + } + else + { + return false; + } + } + + /** + * Return the error message for the occured error + * + * @access public + * @return string Error message + */ + function error() + { + return $this->error; + } + + function get_encoding() + { + return $this->sanitize->output_encoding; + } + + function handle_content_type($mime = 'text/html') + { + if (!headers_sent()) + { + $header = "Content-type: $mime;"; + if ($this->get_encoding()) + { + $header .= ' charset=' . $this->get_encoding(); + } + else + { + $header .= ' charset=UTF-8'; + } + header($header); + } + } + + function get_type() + { + if (!isset($this->data['type'])) + { + $this->data['type'] = SIMPLEPIE_TYPE_ALL; + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; + } + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; + } + } + elseif (isset($this->data['child']['']['rss'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; + if (isset($this->data['child']['']['rss'][0]['attribs']['']['version'])) + { + switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version'])) + { + case '0.91': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; + if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data'])) + { + switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data'])) + { + case '0': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; + break; + + case '24': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; + break; + } + } + break; + + case '0.92': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; + break; + + case '0.93': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; + break; + + case '0.94': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; + break; + + case '2.0': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; + break; + } + } + } + else + { + $this->data['type'] = SIMPLEPIE_TYPE_NONE; + } + } + return $this->data['type']; + } + + /** + * Returns the URL for the favicon of the feed's website. + * + * @todo Cache atom:icon + * @access public + * @since 1.0 + */ + function get_favicon() + { + //chopped out a bit here because I always want to use the domain default favicon, not the one set in the feed + if (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) + { + $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); + + if ($this->cache && $this->favicon_handler) + { + $favicon_filename = call_user_func($this->cache_name_function, $favicon); + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); + + if ($cache->load()) + { + return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); + + if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0) + { + $sniffer = new $this->content_type_sniffer_class($file); + if (substr($sniffer->get_type(), 0, 6) === 'image/') + { + if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) + { + return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + } + } + else + { + return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); + } + } + return false; + } + + /** + * @todo If we have a perm redirect we should return the new URL + * @todo When we make the above change, let's support as well + * @todo Also, |atom:link|@rel=self + */ + function subscribe_url() + { + if ($this->feed_url !== null) + { + return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_feed() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_outlook() + { + if ($this->feed_url !== null) + { + return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_podcast() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_itunes() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + /** + * Creates the subscribe_* methods' return data + * + * @access private + * @param string $feed_url String to prefix to the feed URL + * @param string $site_url String to prefix to the site URL (and + * suffix to the feed URL) + * @return mixed URL if feed exists, false otherwise + */ + function subscribe_service($feed_url, $site_url = null) + { + if ($this->subscribe_url()) + { + $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url); + if ($site_url !== null && $this->get_link() !== null) + { + $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link()); + } + return $return; + } + else + { + return null; + } + } + + function subscribe_aol() + { + return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); + } + + function subscribe_bloglines() + { + return urldecode($this->subscribe_service('http://www.bloglines.com/sub/')); + } + + function subscribe_eskobo() + { + return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); + } + + function subscribe_feedfeeds() + { + return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); + } + + function subscribe_feedster() + { + return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); + } + + function subscribe_google() + { + return $this->subscribe_service('http://fusion.google.com/add?feedurl='); + } + + function subscribe_gritwire() + { + return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); + } + + function subscribe_msn() + { + return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); + } + + function subscribe_netvibes() + { + return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); + } + + function subscribe_newsburst() + { + return $this->subscribe_service('http://www.newsburst.com/Source/?add='); + } + + function subscribe_newsgator() + { + return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); + } + + function subscribe_odeo() + { + return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); + } + + function subscribe_podnova() + { + return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); + } + + function subscribe_rojo() + { + return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); + } + + function subscribe_yahoo() + { + return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); + } + + function get_feed_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_ATOM_10) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_ATOM_03) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_RDF) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag])) + { + return $this->data['child']['']['rss'][0]['child'][$namespace][$tag]; + } + } + return null; + } + + function get_channel_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_ATOM_ALL) + { + if ($return = $this->get_feed_tags($namespace, $tag)) + { + return $return; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_10) + { + if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_090) + { + if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if ($channel = $this->get_feed_tags('', 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + return null; + } + + function get_image_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_RSS_10) + { + if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_090) + { + if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if ($image = $this->get_channel_tags('', 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + return null; + } + + function get_base($element = array()) + { + if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) + { + return $element['xml_base']; + } + elseif ($this->get_link() !== null) + { + return $this->get_link(); + } + else + { + return $this->subscribe_url(); + } + } + + function sanitize($data, $type, $base = '') + { + return $this->sanitize->sanitize($data, $type, $base); + } + + function get_title() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_channel_tags('', 'category') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->author_class($name, $uri, $email); + } + } + if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->author_class($name, $url, $email); + } + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if (isset($links[$key])) + { + return $links[$key]; + } + else + { + return null; + } + } + + /** + * Added for parity between the parent-level and the item/entry-level. + */ + function get_permalink() + { + return $this->get_link(0); + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_channel_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + function get_description() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'copyright')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_language() + { + if ($return = $this->get_channel_tags('', 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['headers']['content-language'])) + { + return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_image_title() + { + if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_image_url() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) + { + return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags('', 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_image_link() + { + if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags('', 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_image_width() + { + if ($return = $this->get_image_tags('', 'width')) + { + return round($return[0]['data']); + } + elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url')) + { + return 88.0; + } + else + { + return null; + } + } + + function get_image_height() + { + if ($return = $this->get_image_tags('', 'height')) + { + return round($return[0]['data']); + } + elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url')) + { + return 31.0; + } + else + { + return null; + } + } + + function get_item_quantity($max = 0) + { + $qty = count($this->get_items()); + if ($max == 0) + { + return $qty; + } + else + { + return ($qty > $max) ? $max : $qty; + } + } + + function get_item($key = 0) + { + $items = $this->get_items(); + if (isset($items[$key])) + { + return $items[$key]; + } + else + { + return null; + } + } + + function get_items($start = 0, $end = 0) + { + if (!empty($this->multifeed_objects)) + { + return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); + } + elseif (!isset($this->data['items'])) + { + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_channel_tags('', 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + } + + if (!empty($this->data['items'])) + { + // If we want to order it by date, check if all items have a date, and then sort it + if ($this->order_by_date) + { + if (!isset($this->data['ordered_items'])) + { + $do_sort = true; + foreach ($this->data['items'] as $item) + { + if (!$item->get_date('U')) + { + $do_sort = false; + break; + } + } + $item = null; + $this->data['ordered_items'] = $this->data['items']; + if ($do_sort) + { + usort($this->data['ordered_items'], array(&$this, 'sort_items')); + } + } + $items = $this->data['ordered_items']; + } + else + { + $items = $this->data['items']; + } + + // Slice the data as desired + if ($end == 0) + { + return array_slice($items, $start); + } + else + { + return array_slice($items, $start, $end); + } + } + else + { + return array(); + } + } + + function sort_items($a, $b) + { + return $a->get_date('U') <= $b->get_date('U'); + } + + function merge_items($urls, $start = 0, $end = 0, $limit = 0) + { + if (is_array($urls) && sizeof($urls) > 0) + { + $items = array(); + foreach ($urls as $arg) + { + if (is_a($arg, 'SimplePie')) + { + $items = array_merge($items, $arg->get_items(0, $limit)); + } + else + { + trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); + } + } + + $do_sort = true; + foreach ($items as $item) + { + if (!$item->get_date('U')) + { + $do_sort = false; + break; + } + } + $item = null; + if ($do_sort) + { + usort($items, array('SimplePie', 'sort_items')); + } + + if ($end == 0) + { + return array_slice($items, $start); + } + else + { + return array_slice($items, $start, $end); + } + } + else + { + trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); + return array(); + } + } +} + +class SimplePie_Item +{ + var $feed; + var $data = array(); + + function SimplePie_Item($feed, $data) + { + $this->feed = $feed; + $this->data = $data; + } + + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + unset($this->feed); + } + + function get_item_tags($namespace, $tag) + { + if (isset($this->data['child'][$namespace][$tag])) + { + return $this->data['child'][$namespace][$tag]; + } + else + { + return null; + } + } + + function get_base($element = array()) + { + return $this->feed->get_base($element); + } + + function sanitize($data, $type, $base = '') + { + return $this->feed->sanitize($data, $type, $base); + } + + function get_feed() + { + return $this->feed; + } + + function get_id($hash = false) + { + if (!$hash) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags('', 'guid')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (($return = $this->get_permalink()) !== null) + { + return $return; + } + elseif (($return = $this->get_title()) !== null) + { + return $return; + } + } + if ($this->get_permalink() !== null || $this->get_title() !== null) + { + return md5($this->get_permalink() . $this->get_title()); + } + else + { + return md5(serialize($this->data)); + } + } + + function get_title() + { + if (!isset($this->data['title'])) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags('', 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $this->data['title'] = null; + } + } + return $this->data['title']; + } + + function get_description($description_only = false) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (!$description_only) + { + return $this->get_content(true); + } + else + { + return null; + } + } + + function get_content($content_only = false) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif (!$content_only) + { + return $this->get_description(true); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_item_tags('', 'category') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->feed->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->feed->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + /** + * @todo Atom inheritance (item author, source author, feed author) + */ + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->feed->author_class($name, $uri, $email); + } + } + if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->feed->author_class($name, $url, $email); + } + } + if ($author = $this->get_item_tags('', 'author')) + { + $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) + { + return $authors; + } + elseif ($authors = $this->feed->get_authors()) + { + return $authors; + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_date($date_format = 'j F Y, g:i a') + { + if (!isset($this->data['date'])) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags('', 'pubDate')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + + if (!empty($this->data['date']['raw'])) + { + $parser = SimplePie_Parse_Date::get(); + $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']); + } + else + { + $this->data['date'] = null; + } + } + if ($this->data['date']) + { + $date_format = (string) $date_format; + switch ($date_format) + { + case '': + return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT); + + case 'U': + return $this->data['date']['parsed']; + + default: + return date($date_format, $this->data['date']['parsed']); + } + } + else + { + return null; + } + } + + function get_local_date($date_format = '%c') + { + if (!$date_format) + { + return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (($date = $this->get_date('U')) !== null) + { + return strftime($date_format, $date); + } + else + { + return null; + } + } + + function get_permalink() + { + $link = $this->get_link(); + $enclosure = $this->get_enclosure(0); + if ($link !== null) + { + return $link; + } + elseif ($enclosure !== null) + { + return $enclosure->get_link(); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if ($links[$key] !== null) + { + return $links[$key]; + } + else + { + return null; + } + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags('', 'guid')) + { + if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true') + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + /** + * @todo Add ability to prefer one type of content over another (in a media group). + */ + function get_enclosure($key = 0, $prefer = null) + { + $enclosures = $this->get_enclosures(); + if (isset($enclosures[$key])) + { + return $enclosures[$key]; + } + else + { + return null; + } + } + + /** + * Grabs all available enclosures (podcasts, etc.) + * + * Supports the RSS tag, as well as Media RSS and iTunes RSS. + * + * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support. + * + * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). + * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists). + */ + function get_enclosures() + { + if (!isset($this->data['enclosures'])) + { + $this->data['enclosures'] = array(); + + // Elements + $captions_parent = null; + $categories_parent = null; + $copyrights_parent = null; + $credits_parent = null; + $description_parent = null; + $duration_parent = null; + $hashes_parent = null; + $keywords_parent = null; + $player_parent = null; + $ratings_parent = null; + $restrictions_parent = null; + $thumbnails_parent = null; + $title_parent = null; + + // Let's do the channel and item-level ones first, and just re-use them if we need to. + $parent = $this->get_feed(); + + // CAPTIONS + if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) + { + foreach ($captions as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + } + elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) + { + foreach ($captions as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + } + if (is_array($captions_parent)) + { + $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent)); + } + + // CATEGORIES + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category) + { + $term = null; + $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd'; + $label = null; + if (isset($category['attribs']['']['text'])) + { + $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + + if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'])) + { + foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory) + { + if (isset($subcategory['attribs']['']['text'])) + { + $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + } + if (is_array($categories_parent)) + { + $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + + // COPYRIGHT + if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) + { + $copyright_url = null; + $copyright_label = null; + if (isset($copyright[0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($copyright[0]['data'])) + { + $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) + { + $copyright_url = null; + $copyright_label = null; + if (isset($copyright[0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($copyright[0]['data'])) + { + $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + + // CREDITS + if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) + { + foreach ($credits as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + } + elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) + { + foreach ($credits as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + } + if (is_array($credits_parent)) + { + $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent)); + } + + // DESCRIPTION + if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) + { + if (isset($description_parent[0]['data'])) + { + $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) + { + if (isset($description_parent[0]['data'])) + { + $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + + // DURATION + if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration')) + { + $seconds = null; + $minutes = null; + $hours = null; + if (isset($duration_parent[0]['data'])) + { + $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + if (sizeof($temp) > 0) + { + (int) $seconds = array_pop($temp); + } + if (sizeof($temp) > 0) + { + (int) $minutes = array_pop($temp); + $seconds += $minutes * 60; + } + if (sizeof($temp) > 0) + { + (int) $hours = array_pop($temp); + $seconds += $hours * 3600; + } + unset($temp); + $duration_parent = $seconds; + } + } + + // HASHES + if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) + { + foreach ($hashes_iterator as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes_parent[] = $algo.':'.$value; + } + } + elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) + { + foreach ($hashes_iterator as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes_parent[] = $algo.':'.$value; + } + } + if (is_array($hashes_parent)) + { + $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent)); + } + + // KEYWORDS + if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + if (is_array($keywords_parent)) + { + $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent)); + } + + // PLAYER + if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) + { + if (isset($player_parent[0]['attribs']['']['url'])) + { + $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) + { + if (isset($player_parent[0]['attribs']['']['url'])) + { + $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + + // RATINGS + if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) + { + foreach ($ratings as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) + { + foreach ($ratings as $rating) + { + $rating_scheme = 'urn:itunes'; + $rating_value = null; + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) + { + foreach ($ratings as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) + { + foreach ($ratings as $rating) + { + $rating_scheme = 'urn:itunes'; + $rating_value = null; + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + if (is_array($ratings_parent)) + { + $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent)); + } + + // RESTRICTIONS + if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = 'allow'; + $restriction_type = null; + $restriction_value = 'itunes'; + if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes') + { + $restriction_relationship = 'deny'; + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = 'allow'; + $restriction_type = null; + $restriction_value = 'itunes'; + if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes') + { + $restriction_relationship = 'deny'; + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + if (is_array($restrictions_parent)) + { + $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent)); + } + + // THUMBNAILS + if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) + { + foreach ($thumbnails as $thumbnail) + { + if (isset($thumbnail['attribs']['']['url'])) + { + $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) + { + foreach ($thumbnails as $thumbnail) + { + if (isset($thumbnail['attribs']['']['url'])) + { + $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + + // TITLES + if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) + { + if (isset($title_parent[0]['data'])) + { + $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) + { + if (isset($title_parent[0]['data'])) + { + $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + + // Clear the memory + unset($parent); + + // If we have media:group tags, loop through them. + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group) + { + // If we have media:content tags, loop through them. + foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) + { + if (isset($content['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + // Elements + $captions = null; + $categories = null; + $copyrights = null; + $credits = null; + $description = null; + $hashes = null; + $keywords = null; + $player = null; + $ratings = null; + $restrictions = null; + $thumbnails = null; + $title = null; + + // Start checking the attributes of media:content + if (isset($content['attribs']['']['bitrate'])) + { + $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['channels'])) + { + $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['duration'])) + { + $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $duration = $duration_parent; + } + if (isset($content['attribs']['']['expression'])) + { + $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['framerate'])) + { + $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['height'])) + { + $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['lang'])) + { + $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['fileSize'])) + { + $length = ceil($content['attribs']['']['fileSize']); + } + if (isset($content['attribs']['']['medium'])) + { + $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['samplingrate'])) + { + $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['type'])) + { + $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['width'])) + { + $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + + // Checking the other optional media: elements. Priority: media:content, media:group, item, channel + + // CAPTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + else + { + $captions = $captions_parent; + } + + // CATEGORIES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (is_array($categories) && is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); + } + elseif (is_array($categories)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories)); + } + elseif (is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + + // COPYRIGHTS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + else + { + $copyrights = $copyrights_parent; + } + + // CREDITS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + else + { + $credits = $credits_parent; + } + + // DESCRIPTION + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $description = $description_parent; + } + + // HASHES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + else + { + $hashes = $hashes_parent; + } + + // KEYWORDS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + else + { + $keywords = $keywords_parent; + } + + // PLAYER + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $player = $player_parent; + } + + // RATINGS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + else + { + $ratings = $ratings_parent; + } + + // RESTRICTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + else + { + $restrictions = $restrictions_parent; + } + + // THUMBNAILS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + else + { + $thumbnails = $thumbnails_parent; + } + + // TITLES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $title = $title_parent; + } + + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); + } + } + } + + // If we have standalone media:content tags, loop through them. + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'])) + { + foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) + { + if (isset($content['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + // Elements + $captions = null; + $categories = null; + $copyrights = null; + $credits = null; + $description = null; + $hashes = null; + $keywords = null; + $player = null; + $ratings = null; + $restrictions = null; + $thumbnails = null; + $title = null; + + // Start checking the attributes of media:content + if (isset($content['attribs']['']['bitrate'])) + { + $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['channels'])) + { + $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['duration'])) + { + $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $duration = $duration_parent; + } + if (isset($content['attribs']['']['expression'])) + { + $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['framerate'])) + { + $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['height'])) + { + $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['lang'])) + { + $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['fileSize'])) + { + $length = ceil($content['attribs']['']['fileSize']); + } + if (isset($content['attribs']['']['medium'])) + { + $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['samplingrate'])) + { + $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['type'])) + { + $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['width'])) + { + $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + + // Checking the other optional media: elements. Priority: media:content, media:group, item, channel + + // CAPTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + else + { + $captions = $captions_parent; + } + + // CATEGORIES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (is_array($categories) && is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); + } + elseif (is_array($categories)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories)); + } + elseif (is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + else + { + $categories = null; + } + + // COPYRIGHTS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + else + { + $copyrights = $copyrights_parent; + } + + // CREDITS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + else + { + $credits = $credits_parent; + } + + // DESCRIPTION + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $description = $description_parent; + } + + // HASHES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + else + { + $hashes = $hashes_parent; + } + + // KEYWORDS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + else + { + $keywords = $keywords_parent; + } + + // PLAYER + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $player = $player_parent; + } + + // RATINGS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + else + { + $ratings = $ratings_parent; + } + + // RESTRICTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + else + { + $restrictions = $restrictions_parent; + } + + // THUMBNAILS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + else + { + $thumbnails = $thumbnails_parent; + } + + // TITLES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $title = $title_parent; + } + + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); + } + } + } + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) + { + if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure') + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + if (isset($link['attribs']['']['type'])) + { + $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($link['attribs']['']['length'])) + { + $length = ceil($link['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) + { + if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure') + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + if (isset($link['attribs']['']['type'])) + { + $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($link['attribs']['']['length'])) + { + $length = ceil($link['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + if ($enclosure = $this->get_item_tags('', 'enclosure')) + { + if (isset($enclosure[0]['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); + if (isset($enclosure[0]['attribs']['']['type'])) + { + $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($enclosure[0]['attribs']['']['length'])) + { + $length = ceil($enclosure[0]['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + if (sizeof($this->data['enclosures']) == 0) + { + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + + $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures'])); + } + if (!empty($this->data['enclosures'])) + { + return $this->data['enclosures']; + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_source() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source')) + { + return new $this->feed->source_class($this, $return[0]); + } + else + { + return null; + } + } + + /** + * Creates the add_to_* methods' return data + * + * @access private + * @param string $item_url String to prefix to the item permalink + * @param string $title_url String to prefix to the item title + * (and suffix to the item permalink) + * @return mixed URL if feed exists, false otherwise + */ + function add_to_service($item_url, $title_url = null) + { + if ($this->get_permalink() !== null) + { + $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink()); + if ($title_url !== null && $this->get_title() !== null) + { + $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title()); + } + return $return; + } + else + { + return null; + } + } + + function add_to_blinklist() + { + return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title='); + } + + function add_to_blogmarks() + { + return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title='); + } + + function add_to_delicious() + { + return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title='); + } + + function add_to_digg() + { + return $this->add_to_service('http://digg.com/submit?phase=2&URL='); + } + + function add_to_furl() + { + return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t='); + } + + function add_to_magnolia() + { + return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title='); + } + + function add_to_myweb20() + { + return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t='); + } + + function add_to_newsvine() + { + return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h='); + } + + function add_to_reddit() + { + return $this->add_to_service('http://reddit.com/submit?url=', '&title='); + } + + function add_to_segnalo() + { + return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title='); + } + + function add_to_simpy() + { + return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title='); + } + + function add_to_spurl() + { + return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title='); + } + + function add_to_wists() + { + return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title='); + } + + function search_technorati() + { + return $this->add_to_service('http://www.technorati.com/search/'); + } +} + +class SimplePie_Source +{ + var $item; + var $data = array(); + + function SimplePie_Source($item, $data) + { + $this->item = $item; + $this->data = $data; + } + + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + unset($this->item); + } + + function get_source_tags($namespace, $tag) + { + if (isset($this->data['child'][$namespace][$tag])) + { + return $this->data['child'][$namespace][$tag]; + } + else + { + return null; + } + } + + function get_base($element = array()) + { + return $this->item->get_base($element); + } + + function sanitize($data, $type, $base = '') + { + return $this->item->sanitize($data, $type, $base); + } + + function get_item() + { + return $this->item; + } + + function get_title() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->item->feed->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_source_tags('', 'category') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->item->feed->author_class($name, $uri, $email); + } + } + if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->item->feed->author_class($name, $url, $email); + } + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->item->feed->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->item->feed->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if (isset($links[$key])) + { + return $links[$key]; + } + else + { + return null; + } + } + + /** + * Added for parity between the parent-level and the item/entry-level. + */ + function get_permalink() + { + return $this->get_link(0); + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_source_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + function get_description() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'copyright')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_language() + { + if ($return = $this->get_source_tags('', 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['xml_lang'])) + { + return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_image_url() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) + { + return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } +} + +class SimplePie_Author +{ + var $name; + var $link; + var $email; + + // Constructor, used to input the data + function SimplePie_Author($name = null, $link = null, $email = null) + { + $this->name = $name; + $this->link = $link; + $this->email = $email; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_name() + { + if ($this->name !== null) + { + return $this->name; + } + else + { + return null; + } + } + + function get_link() + { + if ($this->link !== null) + { + return $this->link; + } + else + { + return null; + } + } + + function get_email() + { + if ($this->email !== null) + { + return $this->email; + } + else + { + return null; + } + } +} + +class SimplePie_Category +{ + var $term; + var $scheme; + var $label; + + // Constructor, used to input the data + function SimplePie_Category($term = null, $scheme = null, $label = null) + { + $this->term = $term; + $this->scheme = $scheme; + $this->label = $label; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_term() + { + if ($this->term !== null) + { + return $this->term; + } + else + { + return null; + } + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_label() + { + if ($this->label !== null) + { + return $this->label; + } + else + { + return $this->get_term(); + } + } +} + +class SimplePie_Enclosure +{ + var $bitrate; + var $captions; + var $categories; + var $channels; + var $copyright; + var $credits; + var $description; + var $duration; + var $expression; + var $framerate; + var $handler; + var $hashes; + var $height; + var $javascript; + var $keywords; + var $lang; + var $length; + var $link; + var $medium; + var $player; + var $ratings; + var $restrictions; + var $samplingrate; + var $thumbnails; + var $title; + var $type; + var $width; + + // Constructor, used to input the data + function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null) + { + $this->bitrate = $bitrate; + $this->captions = $captions; + $this->categories = $categories; + $this->channels = $channels; + $this->copyright = $copyright; + $this->credits = $credits; + $this->description = $description; + $this->duration = $duration; + $this->expression = $expression; + $this->framerate = $framerate; + $this->hashes = $hashes; + $this->height = $height; + $this->javascript = $javascript; + $this->keywords = $keywords; + $this->lang = $lang; + $this->length = $length; + $this->link = $link; + $this->medium = $medium; + $this->player = $player; + $this->ratings = $ratings; + $this->restrictions = $restrictions; + $this->samplingrate = $samplingrate; + $this->thumbnails = $thumbnails; + $this->title = $title; + $this->type = $type; + $this->width = $width; + if (class_exists('idna_convert')) + { + $idn =& new idna_convert; + $parsed = SimplePie_Misc::parse_url($link); + $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); + } + $this->handler = $this->get_handler(); // Needs to load last + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_bitrate() + { + if ($this->bitrate !== null) + { + return $this->bitrate; + } + else + { + return null; + } + } + + function get_caption($key = 0) + { + $captions = $this->get_captions(); + if (isset($captions[$key])) + { + return $captions[$key]; + } + else + { + return null; + } + } + + function get_captions() + { + if ($this->captions !== null) + { + return $this->captions; + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + if ($this->categories !== null) + { + return $this->categories; + } + else + { + return null; + } + } + + function get_channels() + { + if ($this->channels !== null) + { + return $this->channels; + } + else + { + return null; + } + } + + function get_copyright() + { + if ($this->copyright !== null) + { + return $this->copyright; + } + else + { + return null; + } + } + + function get_credit($key = 0) + { + $credits = $this->get_credits(); + if (isset($credits[$key])) + { + return $credits[$key]; + } + else + { + return null; + } + } + + function get_credits() + { + if ($this->credits !== null) + { + return $this->credits; + } + else + { + return null; + } + } + + function get_description() + { + if ($this->description !== null) + { + return $this->description; + } + else + { + return null; + } + } + + function get_duration($convert = false) + { + if ($this->duration !== null) + { + if ($convert) + { + $time = SimplePie_Misc::time_hms($this->duration); + return $time; + } + else + { + return $this->duration; + } + } + else + { + return null; + } + } + + function get_expression() + { + if ($this->expression !== null) + { + return $this->expression; + } + else + { + return 'full'; + } + } + + function get_extension() + { + if ($this->link !== null) + { + $url = SimplePie_Misc::parse_url($this->link); + if ($url['path'] !== '') + { + return pathinfo($url['path'], PATHINFO_EXTENSION); + } + } + return null; + } + + function get_framerate() + { + if ($this->framerate !== null) + { + return $this->framerate; + } + else + { + return null; + } + } + + function get_handler() + { + return $this->get_real_type(true); + } + + function get_hash($key = 0) + { + $hashes = $this->get_hashes(); + if (isset($hashes[$key])) + { + return $hashes[$key]; + } + else + { + return null; + } + } + + function get_hashes() + { + if ($this->hashes !== null) + { + return $this->hashes; + } + else + { + return null; + } + } + + function get_height() + { + if ($this->height !== null) + { + return $this->height; + } + else + { + return null; + } + } + + function get_language() + { + if ($this->lang !== null) + { + return $this->lang; + } + else + { + return null; + } + } + + function get_keyword($key = 0) + { + $keywords = $this->get_keywords(); + if (isset($keywords[$key])) + { + return $keywords[$key]; + } + else + { + return null; + } + } + + function get_keywords() + { + if ($this->keywords !== null) + { + return $this->keywords; + } + else + { + return null; + } + } + + function get_length() + { + if ($this->length !== null) + { + return $this->length; + } + else + { + return null; + } + } + + function get_link() + { + if ($this->link !== null) + { + return urldecode($this->link); + } + else + { + return null; + } + } + + function get_medium() + { + if ($this->medium !== null) + { + return $this->medium; + } + else + { + return null; + } + } + + function get_player() + { + if ($this->player !== null) + { + return $this->player; + } + else + { + return null; + } + } + + function get_rating($key = 0) + { + $ratings = $this->get_ratings(); + if (isset($ratings[$key])) + { + return $ratings[$key]; + } + else + { + return null; + } + } + + function get_ratings() + { + if ($this->ratings !== null) + { + return $this->ratings; + } + else + { + return null; + } + } + + function get_restriction($key = 0) + { + $restrictions = $this->get_restrictions(); + if (isset($restrictions[$key])) + { + return $restrictions[$key]; + } + else + { + return null; + } + } + + function get_restrictions() + { + if ($this->restrictions !== null) + { + return $this->restrictions; + } + else + { + return null; + } + } + + function get_sampling_rate() + { + if ($this->samplingrate !== null) + { + return $this->samplingrate; + } + else + { + return null; + } + } + + function get_size() + { + $length = $this->get_length(); + if ($length !== null) + { + return round($length/1048576, 2); + } + else + { + return null; + } + } + + function get_thumbnail($key = 0) + { + $thumbnails = $this->get_thumbnails(); + if (isset($thumbnails[$key])) + { + return $thumbnails[$key]; + } + else + { + return null; + } + } + + function get_thumbnails() + { + if ($this->thumbnails !== null) + { + return $this->thumbnails; + } + else + { + return null; + } + } + + function get_title() + { + if ($this->title !== null) + { + return $this->title; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } + + function get_width() + { + if ($this->width !== null) + { + return $this->width; + } + else + { + return null; + } + } + + function native_embed($options='') + { + return $this->embed($options, true); + } + + /** + * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'. + */ + function embed($options = '', $native = false) + { + // Set up defaults + $audio = ''; + $video = ''; + $alt = ''; + $altclass = ''; + $loop = 'false'; + $width = 'auto'; + $height = 'auto'; + $bgcolor = '#ffffff'; + $mediaplayer = ''; + $widescreen = false; + $handler = $this->get_handler(); + $type = $this->get_real_type(); + + // Process options and reassign values as necessary + if (is_array($options)) + { + extract($options); + } + else + { + $options = explode(',', $options); + foreach($options as $option) + { + $opt = explode(':', $option, 2); + if (isset($opt[0], $opt[1])) + { + $opt[0] = trim($opt[0]); + $opt[1] = trim($opt[1]); + switch ($opt[0]) + { + case 'audio': + $audio = $opt[1]; + break; + + case 'video': + $video = $opt[1]; + break; + + case 'alt': + $alt = $opt[1]; + break; + + case 'altclass': + $altclass = $opt[1]; + break; + + case 'loop': + $loop = $opt[1]; + break; + + case 'width': + $width = $opt[1]; + break; + + case 'height': + $height = $opt[1]; + break; + + case 'bgcolor': + $bgcolor = $opt[1]; + break; + + case 'mediaplayer': + $mediaplayer = $opt[1]; + break; + + case 'widescreen': + $widescreen = $opt[1]; + break; + } + } + } + } + + $mime = explode('/', $type, 2); + $mime = $mime[0]; + + // Process values for 'auto' + if ($width == 'auto') + { + if ($mime == 'video') + { + if ($height == 'auto') + { + $width = 480; + } + elseif ($widescreen) + { + $width = round((intval($height)/9)*16); + } + else + { + $width = round((intval($height)/3)*4); + } + } + else + { + $width = '100%'; + } + } + + if ($height == 'auto') + { + if ($mime == 'audio') + { + $height = 0; + } + elseif ($mime == 'video') + { + if ($width == 'auto') + { + if ($widescreen) + { + $height = 270; + } + else + { + $height = 360; + } + } + elseif ($widescreen) + { + $height = round((intval($width)/16)*9); + } + else + { + $height = round((intval($width)/4)*3); + } + } + else + { + $height = 376; + } + } + elseif ($mime == 'audio') + { + $height = 0; + } + + // Set proper placeholder value + if ($mime == 'audio') + { + $placeholder = $audio; + } + elseif ($mime == 'video') + { + $placeholder = $video; + } + + $embed = ''; + + // Make sure the JS library is included + if (!$native) + { + static $javascript_outputted = null; + if (!$javascript_outputted && $this->javascript) + { + $embed .= ''; + $javascript_outputted = true; + } + } + + // Odeo Feed MP3's + if ($handler == 'odeo') + { + if ($native) + { + $embed .= ''; + } + else + { + $embed .= ''; + } + } + + // Flash + elseif ($handler == 'flash') + { + if ($native) + { + $embed .= "get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\">"; + } + else + { + $embed .= ""; + } + } + + // Flash Media Player file types. + // Preferred handler for MP3 file types. + elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != '')) + { + $height += 20; + if ($native) + { + $embed .= "get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\">"; + } + else + { + $embed .= ""; + } + } + + // QuickTime 7 file types. Need to test with QuickTime 6. + // Only handle MP3's if the Flash Media Player is not present. + elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == '')) + { + $height += 16; + if ($native) + { + if ($placeholder != ""){ + $embed .= "get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\">"; + } + else { + $embed .= "get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\">"; + } + } + else + { + $embed .= ""; + } + } + + // Windows Media + elseif ($handler == 'wmedia') + { + $height += 45; + if ($native) + { + $embed .= "get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\">"; + } + else + { + $embed .= ""; + } + } + + // Everything else + else $embed .= '' . $alt . ''; + + return $embed; + } + + function get_real_type($find_handler = false) + { + // If it's Odeo, let's get it out of the way. + if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com') + { + return 'odeo'; + } + + // Mime-types by handler. + $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash + $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player + $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime + $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media + $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3 + + if ($this->get_type() !== null) + { + $type = strtolower($this->type); + } + else + { + $type = null; + } + + // If we encounter an unsupported mime-type, check the file extension and guess intelligently. + if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) + { + switch (strtolower($this->get_extension())) + { + // Audio mime-types + case 'aac': + case 'adts': + $type = 'audio/acc'; + break; + + case 'aif': + case 'aifc': + case 'aiff': + case 'cdda': + $type = 'audio/aiff'; + break; + + case 'bwf': + $type = 'audio/wav'; + break; + + case 'kar': + case 'mid': + case 'midi': + case 'smf': + $type = 'audio/midi'; + break; + + case 'm4a': + $type = 'audio/x-m4a'; + break; + + case 'mp3': + case 'swa': + $type = 'audio/mp3'; + break; + + case 'wav': + $type = 'audio/wav'; + break; + + case 'wax': + $type = 'audio/x-ms-wax'; + break; + + case 'wma': + $type = 'audio/x-ms-wma'; + break; + + // Video mime-types + case '3gp': + case '3gpp': + $type = 'video/3gpp'; + break; + + case '3g2': + case '3gp2': + $type = 'video/3gpp2'; + break; + + case 'asf': + $type = 'video/x-ms-asf'; + break; + + case 'flv': + $type = 'video/x-flv'; + break; + + case 'm1a': + case 'm1s': + case 'm1v': + case 'm15': + case 'm75': + case 'mp2': + case 'mpa': + case 'mpeg': + case 'mpg': + case 'mpm': + case 'mpv': + $type = 'video/mpeg'; + break; + + case 'm4v': + $type = 'video/x-m4v'; + break; + + case 'mov': + case 'qt': + $type = 'video/quicktime'; + break; + + case 'mp4': + case 'mpg4': + $type = 'video/mp4'; + break; + + case 'sdv': + $type = 'video/sd-video'; + break; + + case 'wm': + $type = 'video/x-ms-wm'; + break; + + case 'wmv': + $type = 'video/x-ms-wmv'; + break; + + case 'wvx': + $type = 'video/x-ms-wvx'; + break; + + // Flash mime-types + case 'spl': + $type = 'application/futuresplash'; + break; + + case 'swf': + $type = 'application/x-shockwave-flash'; + break; + } + } + + if ($find_handler) + { + if (in_array($type, $types_flash)) + { + return 'flash'; + } + elseif (in_array($type, $types_fmedia)) + { + return 'fmedia'; + } + elseif (in_array($type, $types_quicktime)) + { + return 'quicktime'; + } + elseif (in_array($type, $types_wmedia)) + { + return 'wmedia'; + } + elseif (in_array($type, $types_mp3)) + { + return 'mp3'; + } + else + { + return null; + } + } + else + { + return $type; + } + } +} + +class SimplePie_Caption +{ + var $type; + var $lang; + var $startTime; + var $endTime; + var $text; + + // Constructor, used to input the data + function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null) + { + $this->type = $type; + $this->lang = $lang; + $this->startTime = $startTime; + $this->endTime = $endTime; + $this->text = $text; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_endtime() + { + if ($this->endTime !== null) + { + return $this->endTime; + } + else + { + return null; + } + } + + function get_language() + { + if ($this->lang !== null) + { + return $this->lang; + } + else + { + return null; + } + } + + function get_starttime() + { + if ($this->startTime !== null) + { + return $this->startTime; + } + else + { + return null; + } + } + + function get_text() + { + if ($this->text !== null) + { + return $this->text; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } +} + +class SimplePie_Credit +{ + var $role; + var $scheme; + var $name; + + // Constructor, used to input the data + function SimplePie_Credit($role = null, $scheme = null, $name = null) + { + $this->role = $role; + $this->scheme = $scheme; + $this->name = $name; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_role() + { + if ($this->role !== null) + { + return $this->role; + } + else + { + return null; + } + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_name() + { + if ($this->name !== null) + { + return $this->name; + } + else + { + return null; + } + } +} + +class SimplePie_Copyright +{ + var $url; + var $label; + + // Constructor, used to input the data + function SimplePie_Copyright($url = null, $label = null) + { + $this->url = $url; + $this->label = $label; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_url() + { + if ($this->url !== null) + { + return $this->url; + } + else + { + return null; + } + } + + function get_attribution() + { + if ($this->label !== null) + { + return $this->label; + } + else + { + return null; + } + } +} + +class SimplePie_Rating +{ + var $scheme; + var $value; + + // Constructor, used to input the data + function SimplePie_Rating($scheme = null, $value = null) + { + $this->scheme = $scheme; + $this->value = $value; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_value() + { + if ($this->value !== null) + { + return $this->value; + } + else + { + return null; + } + } +} + +class SimplePie_Restriction +{ + var $relationship; + var $type; + var $value; + + // Constructor, used to input the data + function SimplePie_Restriction($relationship = null, $type = null, $value = null) + { + $this->relationship = $relationship; + $this->type = $type; + $this->value = $value; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_relationship() + { + if ($this->relationship !== null) + { + return $this->relationship; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } + + function get_value() + { + if ($this->value !== null) + { + return $this->value; + } + else + { + return null; + } + } +} + +/** + * @todo Move to properly supporting RFC2616 (HTTP/1.1) + */ +class SimplePie_File +{ + var $url; + var $useragent; + var $success = true; + var $headers = array(); + var $body; + var $status_code; + var $redirects = 0; + var $error; + var $method = SIMPLEPIE_FILE_SOURCE_NONE; + + function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) + { + if (class_exists('idna_convert')) + { + $idn =& new idna_convert; + $parsed = SimplePie_Misc::parse_url($url); + $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); + } + $this->url = $url; + $this->useragent = $useragent; + if (preg_match('/^http(s)?:\/\//i', $url)) + { + if ($useragent === null) + { + $useragent = ini_get('user_agent'); + $this->useragent = $useragent; + } + if (!is_array($headers)) + { + $headers = array(); + } + if (!$force_fsockopen && function_exists('curl_exec')) + { + $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; + $fp = curl_init(); + $headers2 = array(); + foreach ($headers as $key => $value) + { + $headers2[] = "$key: $value"; + } + if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) + { + curl_setopt($fp, CURLOPT_ENCODING, ''); + } + curl_setopt($fp, CURLOPT_URL, $url); + curl_setopt($fp, CURLOPT_HEADER, 1); + curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); + curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); + curl_setopt($fp, CURLOPT_REFERER, $url); + curl_setopt($fp, CURLOPT_USERAGENT, $useragent); + curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); + if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) + { + curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); + } + + $this->headers = curl_exec($fp); + if (curl_errno($fp) == 23 || curl_errno($fp) == 61) + { + curl_setopt($fp, CURLOPT_ENCODING, 'none'); + $this->headers = curl_exec($fp); + } + if (curl_errno($fp)) + { + $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); + $this->success = false; + } + else + { + $info = curl_getinfo($fp); + curl_close($fp); + $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); + $this->headers = array_pop($this->headers); + $parser =& new SimplePie_HTTP_Parser($this->headers); + if ($parser->parse()) + { + $this->headers = $parser->headers; + $this->body = $parser->body; + $this->status_code = $parser->status_code; + if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) + { + $this->redirects++; + $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); + return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + } + } + } + } + else + { + $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN; + $url_parts = parse_url($url); + if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https') + { + $url_parts['host'] = "ssl://$url_parts[host]"; + $url_parts['port'] = 443; + } + if (!isset($url_parts['port'])) + { + $url_parts['port'] = 80; + } + $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout); + if (!$fp) + { + $this->error = 'fsockopen error: ' . $errstr; + $this->success = false; + } + else + { + stream_set_timeout($fp, $timeout); + if (isset($url_parts['path'])) + { + if (isset($url_parts['query'])) + { + $get = "$url_parts[path]?$url_parts[query]"; + } + else + { + $get = $url_parts['path']; + } + } + else + { + $get = '/'; + } + $out = "GET $get HTTP/1.0\r\n"; + $out .= "Host: $url_parts[host]\r\n"; + $out .= "User-Agent: $useragent\r\n"; + if (function_exists('gzinflate')) + { + $out .= "Accept-Encoding: gzip,deflate\r\n"; + } + + if (isset($url_parts['user']) && isset($url_parts['pass'])) + { + $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n"; + } + foreach ($headers as $key => $value) + { + $out .= "$key: $value\r\n"; + } + $out .= "Connection: Close\r\n\r\n"; + fwrite($fp, $out); + + $info = stream_get_meta_data($fp); + + $this->headers = ''; + while (!$info['eof'] && !$info['timed_out']) + { + $this->headers .= fread($fp, 1160); + $info = stream_get_meta_data($fp); + } + if (!$info['timed_out']) + { + $parser =& new SimplePie_HTTP_Parser($this->headers); + if ($parser->parse()) + { + $this->headers = $parser->headers; + $this->body = $parser->body; + $this->status_code = $parser->status_code; + if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) + { + $this->redirects++; + $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); + return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + } + if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate')) + { + if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00") + { + $this->body = substr($this->body, 10); + } + $this->body = gzinflate($this->body); + } + } + } + else + { + $this->error = 'fsocket timed out'; + $this->success = false; + } + fclose($fp); + } + } + } + else + { + $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; + if (!$this->body = file_get_contents($url)) + { + $this->error = 'file_get_contents could not read the file'; + $this->success = false; + } + } + } +} + +/** + * HTTP Response Parser + * + * @package SimplePie + */ +class SimplePie_HTTP_Parser +{ + /** + * HTTP Version + * + * @access public + * @var float + */ + var $http_version = 0.0; + + /** + * Status code + * + * @access public + * @var int + */ + var $status_code = 0; + + /** + * Reason phrase + * + * @access public + * @var string + */ + var $reason = ''; + + /** + * Key/value pairs of the headers + * + * @access public + * @var array + */ + var $headers = array(); + + /** + * Body of the response + * + * @access public + * @var string + */ + var $body = ''; + + /** + * Current state of the state machine + * + * @access private + * @var string + */ + var $state = 'http_version'; + + /** + * Input data + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Input data length (to avoid calling strlen() everytime this is needed) + * + * @access private + * @var int + */ + var $data_length = 0; + + /** + * Current position of the pointer + * + * @var int + * @access private + */ + var $position = 0; + + /** + * Name of the hedaer currently being parsed + * + * @access private + * @var string + */ + var $name = ''; + + /** + * Value of the hedaer currently being parsed + * + * @access private + * @var string + */ + var $value = ''; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_HTTP_Parser($data) + { + $this->data = $data; + $this->data_length = strlen($this->data); + } + + /** + * Parse the input data + * + * @access public + * @return bool true on success, false on failure + */ + function parse() + { + while ($this->state && $this->state !== 'emit' && $this->has_data()) + { + $state = $this->state; + $this->$state(); + } + $this->data = ''; + if ($this->state === 'emit') + { + return true; + } + else + { + $this->http_version = ''; + $this->status_code = ''; + $this->reason = ''; + $this->headers = array(); + $this->body = ''; + return false; + } + } + + /** + * Check whether there is data beyond the pointer + * + * @access private + * @return bool true if there is further data, false if not + */ + function has_data() + { + return (bool) ($this->position < $this->data_length); + } + + /** + * See if the next character is LWS + * + * @access private + * @return bool true if the next character is LWS, false if not + */ + function is_linear_whitespace() + { + return (bool) ($this->data[$this->position] === "\x09" + || $this->data[$this->position] === "\x20" + || ($this->data[$this->position] === "\x0A" + && isset($this->data[$this->position + 1]) + && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20"))); + } + + /** + * Parse the HTTP version + * + * @access private + */ + function http_version() + { + if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/') + { + $len = strspn($this->data, '0123456789.', 5); + $this->http_version = substr($this->data, 5, $len); + $this->position += 5 + $len; + if (substr_count($this->http_version, '.') <= 1) + { + $this->http_version = (float) $this->http_version; + $this->position += strspn($this->data, "\x09\x20", $this->position); + $this->state = 'status'; + } + else + { + $this->state = false; + } + } + else + { + $this->state = false; + } + } + + /** + * Parse the status code + * + * @access private + */ + function status() + { + if ($len = strspn($this->data, '0123456789', $this->position)) + { + $this->status_code = (int) substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'reason'; + } + else + { + $this->state = false; + } + } + + /** + * Parse the reason phrase + * + * @access private + */ + function reason() + { + $len = strcspn($this->data, "\x0A", $this->position); + $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20"); + $this->position += $len + 1; + $this->state = 'new_line'; + } + + /** + * Deal with a new line, shifting data around as needed + * + * @access private + */ + function new_line() + { + $this->value = trim($this->value, "\x0D\x20"); + if ($this->name !== '' && $this->value !== '') + { + $this->name = strtolower($this->name); + if (isset($this->headers[$this->name])) + { + $this->headers[$this->name] .= ', ' . $this->value; + } + else + { + $this->headers[$this->name] = $this->value; + } + } + $this->name = ''; + $this->value = ''; + if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A") + { + $this->position += 2; + $this->state = 'body'; + } + elseif ($this->data[$this->position] === "\x0A") + { + $this->position++; + $this->state = 'body'; + } + else + { + $this->state = 'name'; + } + } + + /** + * Parse a header name + * + * @access private + */ + function name() + { + $len = strcspn($this->data, "\x0A:", $this->position); + if (isset($this->data[$this->position + $len])) + { + if ($this->data[$this->position + $len] === "\x0A") + { + $this->position += $len; + $this->state = 'new_line'; + } + else + { + $this->name = substr($this->data, $this->position, $len); + $this->position += $len + 1; + $this->state = 'value'; + } + } + else + { + $this->state = false; + } + } + + /** + * Parse LWS, replacing consecutive LWS characters with a single space + * + * @access private + */ + function linear_whitespace() + { + do + { + if (substr($this->data, $this->position, 2) === "\x0D\x0A") + { + $this->position += 2; + } + elseif ($this->data[$this->position] === "\x0A") + { + $this->position++; + } + $this->position += strspn($this->data, "\x09\x20", $this->position); + } while ($this->has_data() && $this->is_linear_whitespace()); + $this->value .= "\x20"; + } + + /** + * See what state to move to while within non-quoted header values + * + * @access private + */ + function value() + { + if ($this->is_linear_whitespace()) + { + $this->linear_whitespace(); + } + else + { + switch ($this->data[$this->position]) + { + case '"': + $this->position++; + $this->state = 'quote'; + break; + + case "\x0A": + $this->position++; + $this->state = 'new_line'; + break; + + default: + $this->state = 'value_char'; + break; + } + } + } + + /** + * Parse a header value while outside quotes + * + * @access private + */ + function value_char() + { + $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position); + $this->value .= substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'value'; + } + + /** + * See what state to move to while within quoted header values + * + * @access private + */ + function quote() + { + if ($this->is_linear_whitespace()) + { + $this->linear_whitespace(); + } + else + { + switch ($this->data[$this->position]) + { + case '"': + $this->position++; + $this->state = 'value'; + break; + + case "\x0A": + $this->position++; + $this->state = 'new_line'; + break; + + case '\\': + $this->position++; + $this->state = 'quote_escaped'; + break; + + default: + $this->state = 'quote_char'; + break; + } + } + } + + /** + * Parse a header value while within quotes + * + * @access private + */ + function quote_char() + { + $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position); + $this->value .= substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'value'; + } + + /** + * Parse an escaped character within quotes + * + * @access private + */ + function quote_escaped() + { + $this->value .= $this->data[$this->position]; + $this->position++; + $this->state = 'quote'; + } + + /** + * Parse the body + * + * @access private + */ + function body() + { + $this->body = substr($this->data, $this->position); + $this->state = 'emit'; + } +} + +class SimplePie_Cache +{ + /** + * Don't call the constructor. Please. + * + * @access private + */ + function SimplePie_Cache() + { + trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR); + } + + /** + * Create a new SimplePie_Cache object + * + * @static + * @access public + */ + function create($location, $filename, $extension) + { + return new SimplePie_Cache_File($location, $filename, $extension); + } +} + +class SimplePie_Cache_File +{ + var $location; + var $filename; + var $extension; + var $name; + + function SimplePie_Cache_File($location, $filename, $extension) + { + $this->location = $location; + $this->filename = rawurlencode($filename); + $this->extension = rawurlencode($extension); + $this->name = "$location/$this->filename.$this->extension"; + } + + function save($data) + { + if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location)) + { + if (is_a($data, 'SimplePie')) + { + $data = $data->data; + } + + $data = serialize($data); + + if (function_exists('file_put_contents')) + { + return (bool) file_put_contents($this->name, $data); + } + else + { + $fp = fopen($this->name, 'wb'); + if ($fp) + { + fwrite($fp, $data); + fclose($fp); + return true; + } + } + } + return false; + } + + function load() + { + if (file_exists($this->name) && is_readable($this->name)) + { + return unserialize(file_get_contents($this->name)); + } + return false; + } + + function mtime() + { + if (file_exists($this->name)) + { + return filemtime($this->name); + } + return false; + } + + function touch() + { + if (file_exists($this->name)) + { + return touch($this->name); + } + return false; + } + + function unlink() + { + if (file_exists($this->name)) + { + return unlink($this->name); + } + return false; + } +} + +class SimplePie_Misc +{ + function time_hms($seconds) + { + $time = ''; + + $hours = floor($seconds / 3600); + $remainder = $seconds % 3600; + if ($hours > 0) + { + $time .= $hours.':'; + } + + $minutes = floor($remainder / 60); + $seconds = $remainder % 60; + if ($minutes < 10 && $hours > 0) + { + $minutes = '0' . $minutes; + } + if ($seconds < 10) + { + $seconds = '0' . $seconds; + } + + $time .= $minutes.':'; + $time .= $seconds; + + return $time; + } + + function absolutize_url($relative, $base) + { + if ($relative !== '') + { + $relative = SimplePie_Misc::parse_url($relative); + if ($relative['scheme'] !== '') + { + $target = $relative; + } + elseif ($base !== '') + { + $base = SimplePie_Misc::parse_url($base); + $target = SimplePie_Misc::parse_url(''); + if ($relative['authority'] !== '') + { + $target = $relative; + $target['scheme'] = $base['scheme']; + } + else + { + $target['scheme'] = $base['scheme']; + $target['authority'] = $base['authority']; + if ($relative['path'] !== '') + { + if (strpos($relative['path'], '/') === 0) + { + $target['path'] = $relative['path']; + } + elseif ($base['authority'] !== '' && $base['path'] === '') + { + $target['path'] = '/' . $relative['path']; + } + elseif (($last_segment = strrpos($base['path'], '/')) !== false) + { + $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path']; + } + else + { + $target['path'] = $relative['path']; + } + $target['query'] = $relative['query']; + } + else + { + $target['path'] = $base['path']; + if ($relative['query'] !== '') + { + $target['query'] = $relative['query']; + } + elseif ($base['query'] !== '') + { + $target['query'] = $base['query']; + } + } + } + $target['fragment'] = $relative['fragment']; + } + else + { + // No base URL, just return the relative URL + $target = $relative; + } + $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']); + } + else + { + $return = $base; + } + $return = SimplePie_Misc::normalize_url($return); + return $return; + } + + function remove_dot_segments($input) + { + $output = ''; + while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..') + { + // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, + if (strpos($input, '../') === 0) + { + $input = substr($input, 3); + } + elseif (strpos($input, './') === 0) + { + $input = substr($input, 2); + } + // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise, + elseif (strpos($input, '/./') === 0) + { + $input = substr_replace($input, '/', 0, 3); + } + elseif ($input == '/.') + { + $input = '/'; + } + // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise, + elseif (strpos($input, '/../') === 0) + { + $input = substr_replace($input, '/', 0, 4); + $output = substr_replace($output, '', strrpos($output, '/')); + } + elseif ($input == '/..') + { + $input = '/'; + $output = substr_replace($output, '', strrpos($output, '/')); + } + // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, + elseif ($input == '.' || $input == '..') + { + $input = ''; + } + // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer + elseif (($pos = strpos($input, '/', 1)) !== false) + { + $output .= substr($input, 0, $pos); + $input = substr_replace($input, '', 0, $pos); + } + else + { + $output .= $input; + $input = ''; + } + } + return $output . $input; + } + + function get_element($realname, $string) + { + $return = array(); + $name = preg_quote($realname, '/'); + if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) + { + for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++) + { + $return[$i]['tag'] = $realname; + $return[$i]['full'] = $matches[$i][0][0]; + $return[$i]['offset'] = $matches[$i][0][1]; + if (strlen($matches[$i][3][0]) <= 2) + { + $return[$i]['self_closing'] = true; + } + else + { + $return[$i]['self_closing'] = false; + $return[$i]['content'] = $matches[$i][4][0]; + } + $return[$i]['attribs'] = array(); + if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER)) + { + for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++) + { + if (count($attribs[$j]) == 2) + { + $attribs[$j][2] = $attribs[$j][1]; + } + $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8'); + } + } + } + } + return $return; + } + + function element_implode($element) + { + $full = "<$element[tag]"; + foreach ($element['attribs'] as $key => $value) + { + $key = strtolower($key); + $full .= " $key=\"" . htmlspecialchars($value['data']) . '"'; + } + if ($element['self_closing']) + { + $full .= ' />'; + } + else + { + $full .= ">$element[content]"; + } + return $full; + } + + function error($message, $level, $file, $line) + { + switch ($level) + { + case E_USER_ERROR: + $note = 'PHP Error'; + break; + case E_USER_WARNING: + $note = 'PHP Warning'; + break; + case E_USER_NOTICE: + $note = 'PHP Notice'; + break; + default: + $note = 'Unknown Error'; + break; + } + error_log("$note: $message in $file on line $line", 0); + return $message; + } + + /** + * If a file has been cached, retrieve and display it. + * + * This is most useful for caching images (get_favicon(), etc.), + * however it works for all cached files. This WILL NOT display ANY + * file/image/page/whatever, but rather only display what has already + * been cached by SimplePie. + * + * @access public + * @see SimplePie::get_favicon() + * @param str $identifier_url URL that is used to identify the content. + * This may or may not be the actual URL of the live content. + * @param str $cache_location Location of SimplePie's cache. Defaults + * to './cache'. + * @param str $cache_extension The file extension that the file was + * cached with. Defaults to 'spc'. + * @param str $cache_class Name of the cache-handling class being used + * in SimplePie. Defaults to 'SimplePie_Cache', and should be left + * as-is unless you've overloaded the class. + * @param str $cache_name_function Obsolete. Exists for backwards + * compatibility reasons only. + */ + function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5') + { + $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension); + + if ($file = $cache->load()) + { + if (isset($file['headers']['content-type'])) + { + header('Content-type:' . $file['headers']['content-type']); + } + else + { + header('Content-type: application/octet-stream'); + } + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days + echo $file['body']; + exit; + } + + die('Cached file for ' . $identifier_url . ' cannot be found.'); + } + + function fix_protocol($url, $http = 1) + { + $url = SimplePie_Misc::normalize_url($url); + $parsed = SimplePie_Misc::parse_url($url); + if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https') + { + return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http); + } + + if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url)) + { + return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http); + } + + if ($http == 2 && $parsed['scheme'] !== '') + { + return "feed:$url"; + } + elseif ($http == 3 && strtolower($parsed['scheme']) == 'http') + { + return substr_replace($url, 'podcast', 0, 4); + } + elseif ($http == 4 && strtolower($parsed['scheme']) == 'http') + { + return substr_replace($url, 'itpc', 0, 4); + } + else + { + return $url; + } + } + + function parse_url($url) + { + static $cache = array(); + if (isset($cache[$url])) + { + return $cache[$url]; + } + elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match)) + { + for ($i = count($match); $i <= 9; $i++) + { + $match[$i] = ''; + } + return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]); + } + else + { + return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => ''); + } + } + + function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '') + { + $return = ''; + if ($scheme !== '') + { + $return .= "$scheme:"; + } + if ($authority !== '') + { + $return .= "//$authority"; + } + if ($path !== '') + { + $return .= $path; + } + if ($query !== '') + { + $return .= "?$query"; + } + if ($fragment !== '') + { + $return .= "#$fragment"; + } + return $return; + } + + function normalize_url($url) + { + $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url); + $url = SimplePie_Misc::parse_url($url); + $url['scheme'] = strtolower($url['scheme']); + if ($url['authority'] !== '') + { + $url['authority'] = strtolower($url['authority']); + $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']); + } + return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']); + } + + function percent_encoding_normalization($match) + { + $integer = hexdec($match[1]); + if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E) + { + return chr($integer); + } + else + { + return strtoupper($match[0]); + } + } + + /** + * Remove bad UTF-8 bytes + * + * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C + * FAQ: Multilingual Forms (modified to include full ASCII range) + * + * @author Geoffrey Sneddon + * @see http://www.w3.org/International/questions/qa-forms-utf-8 + * @param string $str String to remove bad UTF-8 bytes from + * @return string UTF-8 string + */ + function utf8_bad_replace($str) + { + if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str))) + { + return $return; + } + elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8'))) + { + return $return; + } + elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches)) + { + return implode("\xEF\xBF\xBD", $matches[0]); + } + elseif ($str !== '') + { + return "\xEF\xBF\xBD"; + } + else + { + return ''; + } + } + + /** + * Converts a Windows-1252 encoded string to a UTF-8 encoded string + * + * @static + * @access public + * @param string $string Windows-1252 encoded string + * @return string UTF-8 encoded string + */ + function windows_1252_to_utf8($string) + { + static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF"); + + return strtr($string, $convert_table); + } + + function change_encoding($data, $input, $output) + { + $input = SimplePie_Misc::encoding($input); + $output = SimplePie_Misc::encoding($output); + + // We fail to fail on non US-ASCII bytes + if ($input === 'US-ASCII') + { + static $non_ascii_octects = ''; + if (!$non_ascii_octects) + { + for ($i = 0x80; $i <= 0xFF; $i++) + { + $non_ascii_octects .= chr($i); + } + } + $data = substr($data, 0, strcspn($data, $non_ascii_octects)); + } + + if (function_exists('iconv') && ($return = @iconv($input, $output, $data))) + { + return $return; + } + elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input))) + { + return $return; + } + elseif ($input == 'windows-1252' && $output == 'UTF-8') + { + return SimplePie_Misc::windows_1252_to_utf8($data); + } + elseif ($input == 'UTF-8' && $output == 'windows-1252') + { + return utf8_decode($data); + } + return $data; + } + + function encoding($encoding) + { + // Character sets are case-insensitive (though we'll return them in the form given in their registration) + switch (strtoupper($encoding)) + { + case 'ANSI_X3.110-1983': + case 'CSA_T500-1983': + case 'CSISO99NAPLPS': + case 'ISO-IR-99': + case 'NAPLPS': + return 'ANSI_X3.110-1983'; + + case 'ARABIC7': + case 'ASMO_449': + case 'CSISO89ASMO449': + case 'ISO-IR-89': + case 'ISO_9036': + return 'ASMO_449'; + + case 'ADOBE-STANDARD-ENCODING': + case 'CSADOBESTANDARDENCODING': + return 'Adobe-Standard-Encoding'; + + case 'ADOBE-SYMBOL-ENCODING': + case 'CSHPPSMATH': + return 'Adobe-Symbol-Encoding'; + + case 'AMI-1251': + case 'AMI1251': + case 'AMIGA-1251': + case 'AMIGA1251': + return 'Amiga-1251'; + + case 'BOCU-1': + case 'CSBOCU-1': + return 'BOCU-1'; + + case 'BRF': + case 'CSBRF': + return 'BRF'; + + case 'BS_4730': + case 'CSISO4UNITEDKINGDOM': + case 'GB': + case 'ISO-IR-4': + case 'ISO646-GB': + case 'UK': + return 'BS_4730'; + + case 'BS_VIEWDATA': + case 'CSISO47BSVIEWDATA': + case 'ISO-IR-47': + return 'BS_viewdata'; + + case 'BIG5': + case 'CSBIG5': + return 'Big5'; + + case 'BIG5-HKSCS': + return 'Big5-HKSCS'; + + case 'CESU-8': + case 'CSCESU-8': + return 'CESU-8'; + + case 'CA': + case 'CSA7-1': + case 'CSA_Z243.4-1985-1': + case 'CSISO121CANADIAN1': + case 'ISO-IR-121': + case 'ISO646-CA': + return 'CSA_Z243.4-1985-1'; + + case 'CSA7-2': + case 'CSA_Z243.4-1985-2': + case 'CSISO122CANADIAN2': + case 'ISO-IR-122': + case 'ISO646-CA2': + return 'CSA_Z243.4-1985-2'; + + case 'CSA_Z243.4-1985-GR': + case 'CSISO123CSAZ24341985GR': + case 'ISO-IR-123': + return 'CSA_Z243.4-1985-gr'; + + case 'CSISO139CSN369103': + case 'CSN_369103': + case 'ISO-IR-139': + return 'CSN_369103'; + + case 'CSDECMCS': + case 'DEC': + case 'DEC-MCS': + return 'DEC-MCS'; + + case 'CSISO21GERMAN': + case 'DE': + case 'DIN_66003': + case 'ISO-IR-21': + case 'ISO646-DE': + return 'DIN_66003'; + + case 'CSISO646DANISH': + case 'DK': + case 'DS2089': + case 'DS_2089': + case 'ISO646-DK': + return 'DS_2089'; + + case 'CSIBMEBCDICATDE': + case 'EBCDIC-AT-DE': + return 'EBCDIC-AT-DE'; + + case 'CSEBCDICATDEA': + case 'EBCDIC-AT-DE-A': + return 'EBCDIC-AT-DE-A'; + + case 'CSEBCDICCAFR': + case 'EBCDIC-CA-FR': + return 'EBCDIC-CA-FR'; + + case 'CSEBCDICDKNO': + case 'EBCDIC-DK-NO': + return 'EBCDIC-DK-NO'; + + case 'CSEBCDICDKNOA': + case 'EBCDIC-DK-NO-A': + return 'EBCDIC-DK-NO-A'; + + case 'CSEBCDICES': + case 'EBCDIC-ES': + return 'EBCDIC-ES'; + + case 'CSEBCDICESA': + case 'EBCDIC-ES-A': + return 'EBCDIC-ES-A'; + + case 'CSEBCDICESS': + case 'EBCDIC-ES-S': + return 'EBCDIC-ES-S'; + + case 'CSEBCDICFISE': + case 'EBCDIC-FI-SE': + return 'EBCDIC-FI-SE'; + + case 'CSEBCDICFISEA': + case 'EBCDIC-FI-SE-A': + return 'EBCDIC-FI-SE-A'; + + case 'CSEBCDICFR': + case 'EBCDIC-FR': + return 'EBCDIC-FR'; + + case 'CSEBCDICIT': + case 'EBCDIC-IT': + return 'EBCDIC-IT'; + + case 'CSEBCDICPT': + case 'EBCDIC-PT': + return 'EBCDIC-PT'; + + case 'CSEBCDICUK': + case 'EBCDIC-UK': + return 'EBCDIC-UK'; + + case 'CSEBCDICUS': + case 'EBCDIC-US': + return 'EBCDIC-US'; + + case 'CSISO111ECMACYRILLIC': + case 'ECMA-CYRILLIC': + case 'ISO-IR-111': + case 'KOI8-E': + return 'ECMA-cyrillic'; + + case 'CSISO17SPANISH': + case 'ES': + case 'ISO-IR-17': + case 'ISO646-ES': + return 'ES'; + + case 'CSISO85SPANISH2': + case 'ES2': + case 'ISO-IR-85': + case 'ISO646-ES2': + return 'ES2'; + + case 'CSEUCPKDFMTJAPANESE': + case 'EUC-JP': + case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE': + return 'EUC-JP'; + + case 'CSEUCKR': + case 'EUC-KR': + return 'EUC-KR'; + + case 'CSEUCFIXWIDJAPANESE': + case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE': + return 'Extended_UNIX_Code_Fixed_Width_for_Japanese'; + + case 'GB18030': + return 'GB18030'; + + case 'CSGB2312': + case 'GB2312': + return 'GB2312'; + + case 'CP936': + case 'GBK': + case 'MS936': + case 'WINDOWS-936': + return 'GBK'; + + case 'CN': + case 'CSISO57GB1988': + case 'GB_1988-80': + case 'ISO-IR-57': + case 'ISO646-CN': + return 'GB_1988-80'; + + case 'CHINESE': + case 'CSISO58GB231280': + case 'GB_2312-80': + case 'ISO-IR-58': + return 'GB_2312-80'; + + case 'CSISO153GOST1976874': + case 'GOST_19768-74': + case 'ISO-IR-153': + case 'ST_SEV_358-88': + return 'GOST_19768-74'; + + case 'CSHPDESKTOP': + case 'HP-DESKTOP': + return 'HP-DeskTop'; + + case 'CSHPLEGAL': + case 'HP-LEGAL': + return 'HP-Legal'; + + case 'CSHPMATH8': + case 'HP-MATH8': + return 'HP-Math8'; + + case 'CSHPPIFONT': + case 'HP-PI-FONT': + return 'HP-Pi-font'; + + case 'HZ-GB-2312': + return 'HZ-GB-2312'; + + case 'CSIBMSYMBOLS': + case 'IBM-SYMBOLS': + return 'IBM-Symbols'; + + case 'CSIBMTHAI': + case 'IBM-THAI': + return 'IBM-Thai'; + + case 'CCSID00858': + case 'CP00858': + case 'IBM00858': + case 'PC-MULTILINGUAL-850+EURO': + return 'IBM00858'; + + case 'CCSID00924': + case 'CP00924': + case 'EBCDIC-LATIN9--EURO': + case 'IBM00924': + return 'IBM00924'; + + case 'CCSID01140': + case 'CP01140': + case 'EBCDIC-US-37+EURO': + case 'IBM01140': + return 'IBM01140'; + + case 'CCSID01141': + case 'CP01141': + case 'EBCDIC-DE-273+EURO': + case 'IBM01141': + return 'IBM01141'; + + case 'CCSID01142': + case 'CP01142': + case 'EBCDIC-DK-277+EURO': + case 'EBCDIC-NO-277+EURO': + case 'IBM01142': + return 'IBM01142'; + + case 'CCSID01143': + case 'CP01143': + case 'EBCDIC-FI-278+EURO': + case 'EBCDIC-SE-278+EURO': + case 'IBM01143': + return 'IBM01143'; + + case 'CCSID01144': + case 'CP01144': + case 'EBCDIC-IT-280+EURO': + case 'IBM01144': + return 'IBM01144'; + + case 'CCSID01145': + case 'CP01145': + case 'EBCDIC-ES-284+EURO': + case 'IBM01145': + return 'IBM01145'; + + case 'CCSID01146': + case 'CP01146': + case 'EBCDIC-GB-285+EURO': + case 'IBM01146': + return 'IBM01146'; + + case 'CCSID01147': + case 'CP01147': + case 'EBCDIC-FR-297+EURO': + case 'IBM01147': + return 'IBM01147'; + + case 'CCSID01148': + case 'CP01148': + case 'EBCDIC-INTERNATIONAL-500+EURO': + case 'IBM01148': + return 'IBM01148'; + + case 'CCSID01149': + case 'CP01149': + case 'EBCDIC-IS-871+EURO': + case 'IBM01149': + return 'IBM01149'; + + case 'CP037': + case 'CSIBM037': + case 'EBCDIC-CP-CA': + case 'EBCDIC-CP-NL': + case 'EBCDIC-CP-US': + case 'EBCDIC-CP-WT': + case 'IBM037': + return 'IBM037'; + + case 'CP038': + case 'CSIBM038': + case 'EBCDIC-INT': + case 'IBM038': + return 'IBM038'; + + case 'CP1026': + case 'CSIBM1026': + case 'IBM1026': + return 'IBM1026'; + + case 'IBM-1047': + case 'IBM1047': + return 'IBM1047'; + + case 'CP273': + case 'CSIBM273': + case 'IBM273': + return 'IBM273'; + + case 'CP274': + case 'CSIBM274': + case 'EBCDIC-BE': + case 'IBM274': + return 'IBM274'; + + case 'CP275': + case 'CSIBM275': + case 'EBCDIC-BR': + case 'IBM275': + return 'IBM275'; + + case 'CSIBM277': + case 'EBCDIC-CP-DK': + case 'EBCDIC-CP-NO': + case 'IBM277': + return 'IBM277'; + + case 'CP278': + case 'CSIBM278': + case 'EBCDIC-CP-FI': + case 'EBCDIC-CP-SE': + case 'IBM278': + return 'IBM278'; + + case 'CP280': + case 'CSIBM280': + case 'EBCDIC-CP-IT': + case 'IBM280': + return 'IBM280'; + + case 'CP281': + case 'CSIBM281': + case 'EBCDIC-JP-E': + case 'IBM281': + return 'IBM281'; + + case 'CP284': + case 'CSIBM284': + case 'EBCDIC-CP-ES': + case 'IBM284': + return 'IBM284'; + + case 'CP285': + case 'CSIBM285': + case 'EBCDIC-CP-GB': + case 'IBM285': + return 'IBM285'; + + case 'CP290': + case 'CSIBM290': + case 'EBCDIC-JP-KANA': + case 'IBM290': + return 'IBM290'; + + case 'CP297': + case 'CSIBM297': + case 'EBCDIC-CP-FR': + case 'IBM297': + return 'IBM297'; + + case 'CP420': + case 'CSIBM420': + case 'EBCDIC-CP-AR1': + case 'IBM420': + return 'IBM420'; + + case 'CP423': + case 'CSIBM423': + case 'EBCDIC-CP-GR': + case 'IBM423': + return 'IBM423'; + + case 'CP424': + case 'CSIBM424': + case 'EBCDIC-CP-HE': + case 'IBM424': + return 'IBM424'; + + case '437': + case 'CP437': + case 'CSPC8CODEPAGE437': + case 'IBM437': + return 'IBM437'; + + case 'CP500': + case 'CSIBM500': + case 'EBCDIC-CP-BE': + case 'EBCDIC-CP-CH': + case 'IBM500': + return 'IBM500'; + + case 'CP775': + case 'CSPC775BALTIC': + case 'IBM775': + return 'IBM775'; + + case '850': + case 'CP850': + case 'CSPC850MULTILINGUAL': + case 'IBM850': + return 'IBM850'; + + case '851': + case 'CP851': + case 'CSIBM851': + case 'IBM851': + return 'IBM851'; + + case '852': + case 'CP852': + case 'CSPCP852': + case 'IBM852': + return 'IBM852'; + + case '855': + case 'CP855': + case 'CSIBM855': + case 'IBM855': + return 'IBM855'; + + case '857': + case 'CP857': + case 'CSIBM857': + case 'IBM857': + return 'IBM857'; + + case '860': + case 'CP860': + case 'CSIBM860': + case 'IBM860': + return 'IBM860'; + + case '861': + case 'CP-IS': + case 'CP861': + case 'CSIBM861': + case 'IBM861': + return 'IBM861'; + + case '862': + case 'CP862': + case 'CSPC862LATINHEBREW': + case 'IBM862': + return 'IBM862'; + + case '863': + case 'CP863': + case 'CSIBM863': + case 'IBM863': + return 'IBM863'; + + case 'CP864': + case 'CSIBM864': + case 'IBM864': + return 'IBM864'; + + case '865': + case 'CP865': + case 'CSIBM865': + case 'IBM865': + return 'IBM865'; + + case '866': + case 'CP866': + case 'CSIBM866': + case 'IBM866': + return 'IBM866'; + + case 'CP-AR': + case 'CP868': + case 'CSIBM868': + case 'IBM868': + return 'IBM868'; + + case '869': + case 'CP-GR': + case 'CP869': + case 'CSIBM869': + case 'IBM869': + return 'IBM869'; + + case 'CP870': + case 'CSIBM870': + case 'EBCDIC-CP-ROECE': + case 'EBCDIC-CP-YU': + case 'IBM870': + return 'IBM870'; + + case 'CP871': + case 'CSIBM871': + case 'EBCDIC-CP-IS': + case 'IBM871': + return 'IBM871'; + + case 'CP880': + case 'CSIBM880': + case 'EBCDIC-CYRILLIC': + case 'IBM880': + return 'IBM880'; + + case 'CP891': + case 'CSIBM891': + case 'IBM891': + return 'IBM891'; + + case 'CP903': + case 'CSIBM903': + case 'IBM903': + return 'IBM903'; + + case '904': + case 'CP904': + case 'CSIBBM904': + case 'IBM904': + return 'IBM904'; + + case 'CP905': + case 'CSIBM905': + case 'EBCDIC-CP-TR': + case 'IBM905': + return 'IBM905'; + + case 'CP918': + case 'CSIBM918': + case 'EBCDIC-CP-AR2': + case 'IBM918': + return 'IBM918'; + + case 'CSISO143IECP271': + case 'IEC_P27-1': + case 'ISO-IR-143': + return 'IEC_P27-1'; + + case 'CSISO49INIS': + case 'INIS': + case 'ISO-IR-49': + return 'INIS'; + + case 'CSISO50INIS8': + case 'INIS-8': + case 'ISO-IR-50': + return 'INIS-8'; + + case 'CSISO51INISCYRILLIC': + case 'INIS-CYRILLIC': + case 'ISO-IR-51': + return 'INIS-cyrillic'; + + case 'CSINVARIANT': + case 'INVARIANT': + return 'INVARIANT'; + + case 'ISO-10646-J-1': + return 'ISO-10646-J-1'; + + case 'CSUNICODE': + case 'ISO-10646-UCS-2': + return 'ISO-10646-UCS-2'; + + case 'CSUCS4': + case 'ISO-10646-UCS-4': + return 'ISO-10646-UCS-4'; + + case 'CSUNICODEASCII': + case 'ISO-10646-UCS-BASIC': + return 'ISO-10646-UCS-Basic'; + + case 'CSISO10646UTF1': + case 'ISO-10646-UTF-1': + return 'ISO-10646-UTF-1'; + + case 'CSUNICODELATIN1': + case 'ISO-10646': + case 'ISO-10646-UNICODE-LATIN1': + return 'ISO-10646-Unicode-Latin1'; + + case 'CSISO115481': + case 'ISO-11548-1': + case 'ISO_11548-1': + case 'ISO_TR_11548-1': + return 'ISO-11548-1'; + + case 'ISO-2022-CN': + return 'ISO-2022-CN'; + + case 'ISO-2022-CN-EXT': + return 'ISO-2022-CN-EXT'; + + case 'CSISO2022JP': + case 'ISO-2022-JP': + return 'ISO-2022-JP'; + + case 'CSISO2022JP2': + case 'ISO-2022-JP-2': + return 'ISO-2022-JP-2'; + + case 'CSISO2022KR': + case 'ISO-2022-KR': + return 'ISO-2022-KR'; + + case 'CSWINDOWS30LATIN1': + case 'ISO-8859-1-WINDOWS-3.0-LATIN-1': + return 'ISO-8859-1-Windows-3.0-Latin-1'; + + case 'CSWINDOWS31LATIN1': + case 'ISO-8859-1-WINDOWS-3.1-LATIN-1': + return 'ISO-8859-1-Windows-3.1-Latin-1'; + + case 'CSISOLATIN6': + case 'ISO-8859-10': + case 'ISO-IR-157': + case 'ISO_8859-10:1992': + case 'L6': + case 'LATIN6': + return 'ISO-8859-10'; + + case 'ISO-8859-13': + return 'ISO-8859-13'; + + case 'ISO-8859-14': + case 'ISO-CELTIC': + case 'ISO-IR-199': + case 'ISO_8859-14': + case 'ISO_8859-14:1998': + case 'L8': + case 'LATIN8': + return 'ISO-8859-14'; + + case 'ISO-8859-15': + case 'ISO_8859-15': + case 'LATIN-9': + return 'ISO-8859-15'; + + case 'ISO-8859-16': + case 'ISO-IR-226': + case 'ISO_8859-16': + case 'ISO_8859-16:2001': + case 'L10': + case 'LATIN10': + return 'ISO-8859-16'; + + case 'CSISOLATIN2': + case 'ISO-8859-2': + case 'ISO-IR-101': + case 'ISO_8859-2': + case 'ISO_8859-2:1987': + case 'L2': + case 'LATIN2': + return 'ISO-8859-2'; + + case 'CSWINDOWS31LATIN2': + case 'ISO-8859-2-WINDOWS-LATIN-2': + return 'ISO-8859-2-Windows-Latin-2'; + + case 'CSISOLATIN3': + case 'ISO-8859-3': + case 'ISO-IR-109': + case 'ISO_8859-3': + case 'ISO_8859-3:1988': + case 'L3': + case 'LATIN3': + return 'ISO-8859-3'; + + case 'CSISOLATIN4': + case 'ISO-8859-4': + case 'ISO-IR-110': + case 'ISO_8859-4': + case 'ISO_8859-4:1988': + case 'L4': + case 'LATIN4': + return 'ISO-8859-4'; + + case 'CSISOLATINCYRILLIC': + case 'CYRILLIC': + case 'ISO-8859-5': + case 'ISO-IR-144': + case 'ISO_8859-5': + case 'ISO_8859-5:1988': + return 'ISO-8859-5'; + + case 'ARABIC': + case 'ASMO-708': + case 'CSISOLATINARABIC': + case 'ECMA-114': + case 'ISO-8859-6': + case 'ISO-IR-127': + case 'ISO_8859-6': + case 'ISO_8859-6:1987': + return 'ISO-8859-6'; + + case 'CSISO88596E': + case 'ISO-8859-6-E': + case 'ISO_8859-6-E': + return 'ISO-8859-6-E'; + + case 'CSISO88596I': + case 'ISO-8859-6-I': + case 'ISO_8859-6-I': + return 'ISO-8859-6-I'; + + case 'CSISOLATINGREEK': + case 'ECMA-118': + case 'ELOT_928': + case 'GREEK': + case 'GREEK8': + case 'ISO-8859-7': + case 'ISO-IR-126': + case 'ISO_8859-7': + case 'ISO_8859-7:1987': + return 'ISO-8859-7'; + + case 'CSISOLATINHEBREW': + case 'HEBREW': + case 'ISO-8859-8': + case 'ISO-IR-138': + case 'ISO_8859-8': + case 'ISO_8859-8:1988': + return 'ISO-8859-8'; + + case 'CSISO88598E': + case 'ISO-8859-8-E': + case 'ISO_8859-8-E': + return 'ISO-8859-8-E'; + + case 'CSISO88598I': + case 'ISO-8859-8-I': + case 'ISO_8859-8-I': + return 'ISO-8859-8-I'; + + case 'CSISOLATIN5': + case 'ISO-8859-9': + case 'ISO-IR-148': + case 'ISO_8859-9': + case 'ISO_8859-9:1989': + case 'L5': + case 'LATIN5': + return 'ISO-8859-9'; + + case 'CSWINDOWS31LATIN5': + case 'ISO-8859-9-WINDOWS-LATIN-5': + return 'ISO-8859-9-Windows-Latin-5'; + + case 'CSUNICODEIBM1261': + case 'ISO-UNICODE-IBM-1261': + return 'ISO-Unicode-IBM-1261'; + + case 'CSUNICODEIBM1264': + case 'ISO-UNICODE-IBM-1264': + return 'ISO-Unicode-IBM-1264'; + + case 'CSUNICODEIBM1265': + case 'ISO-UNICODE-IBM-1265': + return 'ISO-Unicode-IBM-1265'; + + case 'CSUNICODEIBM1268': + case 'ISO-UNICODE-IBM-1268': + return 'ISO-Unicode-IBM-1268'; + + case 'CSUNICODEIBM1276': + case 'ISO-UNICODE-IBM-1276': + return 'ISO-Unicode-IBM-1276'; + + case 'CSISO10367BOX': + case 'ISO-IR-155': + case 'ISO_10367-BOX': + return 'ISO_10367-box'; + + case 'CSISO2033': + case 'E13B': + case 'ISO-IR-98': + case 'ISO_2033-1983': + return 'ISO_2033-1983'; + + case 'CSISO5427CYRILLIC': + case 'ISO-IR-37': + case 'ISO_5427': + return 'ISO_5427'; + + case 'ISO-IR-54': + case 'ISO5427CYRILLIC1981': + case 'ISO_5427:1981': + return 'ISO_5427:1981'; + + case 'CSISO5428GREEK': + case 'ISO-IR-55': + case 'ISO_5428:1980': + return 'ISO_5428:1980'; + + case 'CSISO646BASIC1983': + case 'ISO_646.BASIC:1983': + case 'REF': + return 'ISO_646.basic:1983'; + + case 'CSISO2INTLREFVERSION': + case 'IRV': + case 'ISO-IR-2': + case 'ISO_646.IRV:1983': + return 'ISO_646.irv:1983'; + + case 'CSISO6937ADD': + case 'ISO-IR-152': + case 'ISO_6937-2-25': + return 'ISO_6937-2-25'; + + case 'CSISOTEXTCOMM': + case 'ISO-IR-142': + case 'ISO_6937-2-ADD': + return 'ISO_6937-2-add'; + + case 'CSISO8859SUPP': + case 'ISO-IR-154': + case 'ISO_8859-SUPP': + case 'LATIN1-2-5': + return 'ISO_8859-supp'; + + case 'CSISO15ITALIAN': + case 'ISO-IR-15': + case 'ISO646-IT': + case 'IT': + return 'IT'; + + case 'CSISO13JISC6220JP': + case 'ISO-IR-13': + case 'JIS_C6220-1969': + case 'JIS_C6220-1969-JP': + case 'KATAKANA': + case 'X0201-7': + return 'JIS_C6220-1969-jp'; + + case 'CSISO14JISC6220RO': + case 'ISO-IR-14': + case 'ISO646-JP': + case 'JIS_C6220-1969-RO': + case 'JP': + return 'JIS_C6220-1969-ro'; + + case 'CSISO42JISC62261978': + case 'ISO-IR-42': + case 'JIS_C6226-1978': + return 'JIS_C6226-1978'; + + case 'CSISO87JISX0208': + case 'ISO-IR-87': + case 'JIS_C6226-1983': + case 'JIS_X0208-1983': + case 'X0208': + return 'JIS_C6226-1983'; + + case 'CSISO91JISC62291984A': + case 'ISO-IR-91': + case 'JIS_C6229-1984-A': + case 'JP-OCR-A': + return 'JIS_C6229-1984-a'; + + case 'CSISO92JISC62991984B': + case 'ISO-IR-92': + case 'ISO646-JP-OCR-B': + case 'JIS_C6229-1984-B': + case 'JP-OCR-B': + return 'JIS_C6229-1984-b'; + + case 'CSISO93JIS62291984BADD': + case 'ISO-IR-93': + case 'JIS_C6229-1984-B-ADD': + case 'JP-OCR-B-ADD': + return 'JIS_C6229-1984-b-add'; + + case 'CSISO94JIS62291984HAND': + case 'ISO-IR-94': + case 'JIS_C6229-1984-HAND': + case 'JP-OCR-HAND': + return 'JIS_C6229-1984-hand'; + + case 'CSISO95JIS62291984HANDADD': + case 'ISO-IR-95': + case 'JIS_C6229-1984-HAND-ADD': + case 'JP-OCR-HAND-ADD': + return 'JIS_C6229-1984-hand-add'; + + case 'CSISO96JISC62291984KANA': + case 'ISO-IR-96': + case 'JIS_C6229-1984-KANA': + return 'JIS_C6229-1984-kana'; + + case 'CSJISENCODING': + case 'JIS_ENCODING': + return 'JIS_Encoding'; + + case 'CSHALFWIDTHKATAKANA': + case 'JIS_X0201': + case 'X0201': + return 'JIS_X0201'; + + case 'CSISO159JISX02121990': + case 'ISO-IR-159': + case 'JIS_X0212-1990': + case 'X0212': + return 'JIS_X0212-1990'; + + case 'CSISO141JUSIB1002': + case 'ISO-IR-141': + case 'ISO646-YU': + case 'JS': + case 'JUS_I.B1.002': + case 'YU': + return 'JUS_I.B1.002'; + + case 'CSISO147MACEDONIAN': + case 'ISO-IR-147': + case 'JUS_I.B1.003-MAC': + case 'MACEDONIAN': + return 'JUS_I.B1.003-mac'; + + case 'CSISO146SERBIAN': + case 'ISO-IR-146': + case 'JUS_I.B1.003-SERB': + case 'SERBIAN': + return 'JUS_I.B1.003-serb'; + + case 'KOI7-SWITCHED': + return 'KOI7-switched'; + + case 'CSKOI8R': + case 'KOI8-R': + return 'KOI8-R'; + + case 'KOI8-U': + return 'KOI8-U'; + + case 'CSKSC5636': + case 'ISO646-KR': + case 'KSC5636': + return 'KSC5636'; + + case 'CSKSC56011987': + case 'ISO-IR-149': + case 'KOREAN': + case 'KSC_5601': + case 'KS_C_5601-1987': + case 'KS_C_5601-1989': + return 'KS_C_5601-1987'; + + case 'CSKZ1048': + case 'KZ-1048': + case 'RK1048': + case 'STRK1048-2002': + return 'KZ-1048'; + + case 'CSISO27LATINGREEK1': + case 'ISO-IR-27': + case 'LATIN-GREEK-1': + return 'Latin-greek-1'; + + case 'CSMNEM': + case 'MNEM': + return 'MNEM'; + + case 'CSMNEMONIC': + case 'MNEMONIC': + return 'MNEMONIC'; + + case 'CSISO86HUNGARIAN': + case 'HU': + case 'ISO-IR-86': + case 'ISO646-HU': + case 'MSZ_7795.3': + return 'MSZ_7795.3'; + + case 'CSMICROSOFTPUBLISHING': + case 'MICROSOFT-PUBLISHING': + return 'Microsoft-Publishing'; + + case 'CSNATSDANO': + case 'ISO-IR-9-1': + case 'NATS-DANO': + return 'NATS-DANO'; + + case 'CSNATSDANOADD': + case 'ISO-IR-9-2': + case 'NATS-DANO-ADD': + return 'NATS-DANO-ADD'; + + case 'CSNATSSEFI': + case 'ISO-IR-8-1': + case 'NATS-SEFI': + return 'NATS-SEFI'; + + case 'CSNATSSEFIADD': + case 'ISO-IR-8-2': + case 'NATS-SEFI-ADD': + return 'NATS-SEFI-ADD'; + + case 'CSISO151CUBA': + case 'CUBA': + case 'ISO-IR-151': + case 'ISO646-CU': + case 'NC_NC00-10:81': + return 'NC_NC00-10:81'; + + case 'CSISO69FRENCH': + case 'FR': + case 'ISO-IR-69': + case 'ISO646-FR': + case 'NF_Z_62-010': + return 'NF_Z_62-010'; + + case 'CSISO25FRENCH': + case 'ISO-IR-25': + case 'ISO646-FR1': + case 'NF_Z_62-010_(1973)': + return 'NF_Z_62-010_(1973)'; + + case 'CSISO60DANISHNORWEGIAN': + case 'CSISO60NORWEGIAN1': + case 'ISO-IR-60': + case 'ISO646-NO': + case 'NO': + case 'NS_4551-1': + return 'NS_4551-1'; + + case 'CSISO61NORWEGIAN2': + case 'ISO-IR-61': + case 'ISO646-NO2': + case 'NO2': + case 'NS_4551-2': + return 'NS_4551-2'; + + case 'OSD_EBCDIC_DF03_IRV': + return 'OSD_EBCDIC_DF03_IRV'; + + case 'OSD_EBCDIC_DF04_1': + return 'OSD_EBCDIC_DF04_1'; + + case 'OSD_EBCDIC_DF04_15': + return 'OSD_EBCDIC_DF04_15'; + + case 'CSPC8DANISHNORWEGIAN': + case 'PC8-DANISH-NORWEGIAN': + return 'PC8-Danish-Norwegian'; + + case 'CSPC8TURKISH': + case 'PC8-TURKISH': + return 'PC8-Turkish'; + + case 'CSISO16PORTUGUESE': + case 'ISO-IR-16': + case 'ISO646-PT': + case 'PT': + return 'PT'; + + case 'CSISO84PORTUGUESE2': + case 'ISO-IR-84': + case 'ISO646-PT2': + case 'PT2': + return 'PT2'; + + case 'CP154': + case 'CSPTCP154': + case 'CYRILLIC-ASIAN': + case 'PT154': + case 'PTCP154': + return 'PTCP154'; + + case 'SCSU': + return 'SCSU'; + + case 'CSISO10SWEDISH': + case 'FI': + case 'ISO-IR-10': + case 'ISO646-FI': + case 'ISO646-SE': + case 'SE': + case 'SEN_850200_B': + return 'SEN_850200_B'; + + case 'CSISO11SWEDISHFORNAMES': + case 'ISO-IR-11': + case 'ISO646-SE2': + case 'SE2': + case 'SEN_850200_C': + return 'SEN_850200_C'; + + case 'CSSHIFTJIS': + case 'MS_KANJI': + case 'SHIFT_JIS': + return 'Shift_JIS'; + + case 'CSISO128T101G2': + case 'ISO-IR-128': + case 'T.101-G2': + return 'T.101-G2'; + + case 'CSISO102T617BIT': + case 'ISO-IR-102': + case 'T.61-7BIT': + return 'T.61-7bit'; + + case 'CSISO103T618BIT': + case 'ISO-IR-103': + case 'T.61': + case 'T.61-8BIT': + return 'T.61-8bit'; + + case 'CSTSCII': + case 'TSCII': + return 'TSCII'; + + case 'CSUNICODE11': + case 'UNICODE-1-1': + return 'UNICODE-1-1'; + + case 'CSUNICODE11UTF7': + case 'UNICODE-1-1-UTF-7': + return 'UNICODE-1-1-UTF-7'; + + case 'CSUNKNOWN8BIT': + case 'UNKNOWN-8BIT': + return 'UNKNOWN-8BIT'; + + case 'ANSI': + case 'ANSI_X3.4-1968': + case 'ANSI_X3.4-1986': + case 'ASCII': + case 'CP367': + case 'CSASCII': + case 'IBM367': + case 'ISO-IR-6': + case 'ISO646-US': + case 'ISO_646.IRV:1991': + case 'US': + case 'US-ASCII': + return 'US-ASCII'; + + case 'UTF-16': + return 'UTF-16'; + + case 'UTF-16BE': + return 'UTF-16BE'; + + case 'UTF-16LE': + return 'UTF-16LE'; + + case 'UTF-32': + return 'UTF-32'; + + case 'UTF-32BE': + return 'UTF-32BE'; + + case 'UTF-32LE': + return 'UTF-32LE'; + + case 'UTF-7': + return 'UTF-7'; + + case 'UTF-8': + return 'UTF-8'; + + case 'CSVIQR': + case 'VIQR': + return 'VIQR'; + + case 'CSVISCII': + case 'VISCII': + return 'VISCII'; + + case 'CSVENTURAINTERNATIONAL': + case 'VENTURA-INTERNATIONAL': + return 'Ventura-International'; + + case 'CSVENTURAMATH': + case 'VENTURA-MATH': + return 'Ventura-Math'; + + case 'CSVENTURAUS': + case 'VENTURA-US': + return 'Ventura-US'; + + case 'CSWINDOWS31J': + case 'WINDOWS-31J': + return 'Windows-31J'; + + case 'CSDKUS': + case 'DK-US': + return 'dk-us'; + + case 'CSISO150': + case 'CSISO150GREEKCCITT': + case 'GREEK-CCITT': + case 'ISO-IR-150': + return 'greek-ccitt'; + + case 'CSISO88GREEK7': + case 'GREEK7': + case 'ISO-IR-88': + return 'greek7'; + + case 'CSISO18GREEK7OLD': + case 'GREEK7-OLD': + case 'ISO-IR-18': + return 'greek7-old'; + + case 'CSHPROMAN8': + case 'HP-ROMAN8': + case 'R8': + case 'ROMAN8': + return 'hp-roman8'; + + case 'CSISO90': + case 'ISO-IR-90': + return 'iso-ir-90'; + + case 'CSISO19LATINGREEK': + case 'ISO-IR-19': + case 'LATIN-GREEK': + return 'latin-greek'; + + case 'CSISO158LAP': + case 'ISO-IR-158': + case 'LAP': + case 'LATIN-LAP': + return 'latin-lap'; + + case 'CSMACINTOSH': + case 'MAC': + case 'MACINTOSH': + return 'macintosh'; + + case 'CSUSDK': + case 'US-DK': + return 'us-dk'; + + case 'CSISO70VIDEOTEXSUPP1': + case 'ISO-IR-70': + case 'VIDEOTEX-SUPPL': + return 'videotex-suppl'; + + case 'WINDOWS-1250': + return 'windows-1250'; + + case 'WINDOWS-1251': + return 'windows-1251'; + + case 'CP819': + case 'CSISOLATIN1': + case 'IBM819': + case 'ISO-8859-1': + case 'ISO-IR-100': + case 'ISO_8859-1': + case 'ISO_8859-1:1987': + case 'L1': + case 'LATIN1': + case 'WINDOWS-1252': + return 'windows-1252'; + + case 'WINDOWS-1253': + return 'windows-1253'; + + case 'WINDOWS-1254': + return 'windows-1254'; + + case 'WINDOWS-1255': + return 'windows-1255'; + + case 'WINDOWS-1256': + return 'windows-1256'; + + case 'WINDOWS-1257': + return 'windows-1257'; + + case 'WINDOWS-1258': + return 'windows-1258'; + + default: + return $encoding; + } + } + + function get_curl_version() + { + if (is_array($curl = curl_version())) + { + $curl = $curl['version']; + } + elseif (substr($curl, 0, 5) == 'curl/') + { + $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5)); + } + elseif (substr($curl, 0, 8) == 'libcurl/') + { + $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8)); + } + else + { + $curl = 0; + } + return $curl; + } + + function is_subclass_of($class1, $class2) + { + if (func_num_args() != 2) + { + trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING); + } + elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1)) + { + return is_subclass_of($class1, $class2); + } + elseif (is_string($class1) && is_string($class2)) + { + if (class_exists($class1)) + { + if (class_exists($class2)) + { + $class2 = strtolower($class2); + while ($class1 = strtolower(get_parent_class($class1))) + { + if ($class1 == $class2) + { + return true; + } + } + } + } + else + { + trigger_error('Unknown class passed as parameter', E_USER_WARNNG); + } + } + return false; + } + + /** + * Strip HTML comments + * + * @access public + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function strip_comments($data) + { + $output = ''; + while (($start = strpos($data, '', $start)) !== false) + { + $data = substr_replace($data, '', 0, $end + 3); + } + else + { + $data = ''; + } + } + return $output . $data; + } + + function parse_date($dt) + { + $parser = SimplePie_Parse_Date::get(); + return $parser->parse($dt); + } + + /** + * Decode HTML entities + * + * @static + * @access public + * @param string $data Input data + * @return string Output data + */ + function entities_decode($data) + { + $decoder = new SimplePie_Decode_HTML_Entities($data); + return $decoder->parse(); + } + + /** + * Remove RFC822 comments + * + * @access public + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function uncomment_rfc822($string) + { + $string = (string) $string; + $position = 0; + $length = strlen($string); + $depth = 0; + + $output = ''; + + while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) + { + $output .= substr($string, $position, $pos - $position); + $position = $pos + 1; + if ($string[$pos - 1] !== '\\') + { + $depth++; + while ($depth && $position < $length) + { + $position += strcspn($string, '()', $position); + if ($string[$position - 1] === '\\') + { + $position++; + continue; + } + elseif (isset($string[$position])) + { + switch ($string[$position]) + { + case '(': + $depth++; + break; + + case ')': + $depth--; + break; + } + $position++; + } + else + { + break; + } + } + } + else + { + $output .= '('; + } + } + $output .= substr($string, $position); + + return $output; + } + + function parse_mime($mime) + { + if (($pos = strpos($mime, ';')) === false) + { + return trim($mime); + } + else + { + return trim(substr($mime, 0, $pos)); + } + } + + function htmlspecialchars_decode($string, $quote_style) + { + if (function_exists('htmlspecialchars_decode')) + { + return htmlspecialchars_decode($string, $quote_style); + } + else + { + return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style))); + } + } + + function atom_03_construct_type($attribs) + { + if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64')) + { + $mode = SIMPLEPIE_CONSTRUCT_BASE64; + } + else + { + $mode = SIMPLEPIE_CONSTRUCT_NONE; + } + if (isset($attribs['']['type'])) + { + switch (strtolower(trim($attribs['']['type']))) + { + case 'text': + case 'text/plain': + return SIMPLEPIE_CONSTRUCT_TEXT | $mode; + + case 'html': + case 'text/html': + return SIMPLEPIE_CONSTRUCT_HTML | $mode; + + case 'xhtml': + case 'application/xhtml+xml': + return SIMPLEPIE_CONSTRUCT_XHTML | $mode; + + default: + return SIMPLEPIE_CONSTRUCT_NONE | $mode; + } + } + else + { + return SIMPLEPIE_CONSTRUCT_TEXT | $mode; + } + } + + function atom_10_construct_type($attribs) + { + if (isset($attribs['']['type'])) + { + switch (strtolower(trim($attribs['']['type']))) + { + case 'text': + return SIMPLEPIE_CONSTRUCT_TEXT; + + case 'html': + return SIMPLEPIE_CONSTRUCT_HTML; + + case 'xhtml': + return SIMPLEPIE_CONSTRUCT_XHTML; + + default: + return SIMPLEPIE_CONSTRUCT_NONE; + } + } + return SIMPLEPIE_CONSTRUCT_TEXT; + } + + function atom_10_content_construct_type($attribs) + { + if (isset($attribs['']['type'])) + { + $type = strtolower(trim($attribs['']['type'])); + switch ($type) + { + case 'text': + return SIMPLEPIE_CONSTRUCT_TEXT; + + case 'html': + return SIMPLEPIE_CONSTRUCT_HTML; + + case 'xhtml': + return SIMPLEPIE_CONSTRUCT_XHTML; + } + if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/') + { + return SIMPLEPIE_CONSTRUCT_NONE; + } + else + { + return SIMPLEPIE_CONSTRUCT_BASE64; + } + } + else + { + return SIMPLEPIE_CONSTRUCT_TEXT; + } + } + + function is_isegment_nz_nc($string) + { + return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string); + } + + function space_seperated_tokens($string) + { + $space_characters = "\x20\x09\x0A\x0B\x0C\x0D"; + $string_length = strlen($string); + + $position = strspn($string, $space_characters); + $tokens = array(); + + while ($position < $string_length) + { + $len = strcspn($string, $space_characters, $position); + $tokens[] = substr($string, $position, $len); + $position += $len; + $position += strspn($string, $space_characters, $position); + } + + return $tokens; + } + + function array_unique($array) + { + if (version_compare(PHP_VERSION, '5.2', '>=')) + { + return array_unique($array); + } + else + { + $array = (array) $array; + $new_array = array(); + $new_array_strings = array(); + foreach ($array as $key => $value) + { + if (is_object($value)) + { + if (method_exists($value, '__toString')) + { + $cmp = $value->__toString(); + } + else + { + trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR); + } + } + elseif (is_array($value)) + { + $cmp = (string) reset($value); + } + else + { + $cmp = (string) $value; + } + if (!in_array($cmp, $new_array_strings)) + { + $new_array[$key] = $value; + $new_array_strings[] = $cmp; + } + } + return $new_array; + } + } + + /** + * Converts a unicode codepoint to a UTF-8 character + * + * @static + * @access public + * @param int $codepoint Unicode codepoint + * @return string UTF-8 character + */ + function codepoint_to_utf8($codepoint) + { + static $cache = array(); + $codepoint = (int) $codepoint; + if (isset($cache[$codepoint])) + { + return $cache[$codepoint]; + } + elseif ($codepoint < 0) + { + return $cache[$codepoint] = false; + } + else if ($codepoint <= 0x7f) + { + return $cache[$codepoint] = chr($codepoint); + } + else if ($codepoint <= 0x7ff) + { + return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f)); + } + else if ($codepoint <= 0xffff) + { + return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); + } + else if ($codepoint <= 0x10ffff) + { + return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); + } + else + { + // U+FFFD REPLACEMENT CHARACTER + return $cache[$codepoint] = "\xEF\xBF\xBD"; + } + } + + /** + * Re-implementation of PHP 5's stripos() + * + * Returns the numeric position of the first occurrence of needle in the + * haystack string. + * + * @static + * @access string + * @param object $haystack + * @param string $needle Note that the needle may be a string of one or more + * characters. If needle is not a string, it is converted to an integer + * and applied as the ordinal value of a character. + * @param int $offset The optional offset parameter allows you to specify which + * character in haystack to start searching. The position returned is still + * relative to the beginning of haystack. + * @return bool If needle is not found, stripos() will return boolean false. + */ + function stripos($haystack, $needle, $offset = 0) + { + if (function_exists('stripos')) + { + return stripos($haystack, $needle, $offset); + } + else + { + if (is_string($needle)) + { + $needle = strtolower($needle); + } + elseif (is_int($needle) || is_bool($needle) || is_double($needle)) + { + $needle = strtolower(chr($needle)); + } + else + { + trigger_error('needle is not a string or an integer', E_USER_WARNING); + return false; + } + + return strpos(strtolower($haystack), $needle, $offset); + } + } + + /** + * Similar to parse_str() + * + * Returns an associative array of name/value pairs, where the value is an + * array of values that have used the same name + * + * @static + * @access string + * @param string $str The input string. + * @return array + */ + function parse_str($str) + { + $return = array(); + $str = explode('&', $str); + + foreach ($str as $section) + { + if (strpos($section, '=') !== false) + { + list($name, $value) = explode('=', $section, 2); + $return[urldecode($name)][] = urldecode($value); + } + else + { + $return[urldecode($section)][] = null; + } + } + + return $return; + } + + /** + * Detect XML encoding, as per XML 1.0 Appendix F.1 + * + * @todo Add support for EBCDIC + * @param string $data XML data + * @return array Possible encodings + */ + function xml_encoding($data) + { + // UTF-32 Big Endian BOM + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") + { + $encoding[] = 'UTF-32BE'; + } + // UTF-32 Little Endian BOM + elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") + { + $encoding[] = 'UTF-32LE'; + } + // UTF-16 Big Endian BOM + elseif (substr($data, 0, 2) === "\xFE\xFF") + { + $encoding[] = 'UTF-16BE'; + } + // UTF-16 Little Endian BOM + elseif (substr($data, 0, 2) === "\xFF\xFE") + { + $encoding[] = 'UTF-16LE'; + } + // UTF-8 BOM + elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") + { + $encoding[] = 'UTF-8'; + } + // UTF-32 Big Endian Without BOM + elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C") + { + if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-32BE'; + } + // UTF-32 Little Endian Without BOM + elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00") + { + if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-32LE'; + } + // UTF-16 Big Endian Without BOM + elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C") + { + if ($pos = strpos($data, "\x00\x3F\x00\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-16BE'; + } + // UTF-16 Little Endian Without BOM + elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00") + { + if ($pos = strpos($data, "\x3F\x00\x3E\x00")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-16LE'; + } + // US-ASCII (or superset) + elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C") + { + if ($pos = strpos($data, "\x3F\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-8'; + } + // Fallback to UTF-8 + else + { + $encoding[] = 'UTF-8'; + } + return $encoding; + } +} + +/** + * Decode HTML Entities + * + * This implements HTML5 as of revision 967 (2007-06-28) + * + * @package SimplePie + */ +class SimplePie_Decode_HTML_Entities +{ + /** + * Data to be parsed + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Currently consumed bytes + * + * @access private + * @var string + */ + var $consumed = ''; + + /** + * Position of the current byte being parsed + * + * @access private + * @var int + */ + var $position = 0; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_Decode_HTML_Entities($data) + { + $this->data = $data; + } + + /** + * Parse the input data + * + * @access public + * @return string Output data + */ + function parse() + { + while (($this->position = strpos($this->data, '&', $this->position)) !== false) + { + $this->consume(); + $this->entity(); + $this->consumed = ''; + } + return $this->data; + } + + /** + * Consume the next byte + * + * @access private + * @return mixed The next byte, or false, if there is no more data + */ + function consume() + { + if (isset($this->data[$this->position])) + { + $this->consumed .= $this->data[$this->position]; + return $this->data[$this->position++]; + } + else + { + $this->consumed = false; + return false; + } + } + + /** + * Consume a range of characters + * + * @access private + * @param string $chars Characters to consume + * @return mixed A series of characters that match the range, or false + */ + function consume_range($chars) + { + if ($len = strspn($this->data, $chars, $this->position)) + { + $data = substr($this->data, $this->position, $len); + $this->consumed .= $data; + $this->position += $len; + return $data; + } + else + { + $this->consumed = false; + return false; + } + } + + /** + * Unconsume one byte + * + * @access private + */ + function unconsume() + { + $this->consumed = substr($this->consumed, 0, -1); + $this->position--; + } + + /** + * Decode an entity + * + * @access private + */ + function entity() + { + switch ($this->consume()) + { + case "\x09": + case "\x0A": + case "\x0B": + case "\x0B": + case "\x0C": + case "\x20": + case "\x3C": + case "\x26": + case false: + break; + + case "\x23": + switch ($this->consume()) + { + case "\x78": + case "\x58": + $range = '0123456789ABCDEFabcdef'; + $hex = true; + break; + + default: + $range = '0123456789'; + $hex = false; + $this->unconsume(); + break; + } + + if ($codepoint = $this->consume_range($range)) + { + static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8"); + + if ($hex) + { + $codepoint = hexdec($codepoint); + } + else + { + $codepoint = intval($codepoint); + } + + if (isset($windows_1252_specials[$codepoint])) + { + $replacement = $windows_1252_specials[$codepoint]; + } + else + { + $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint); + } + + if ($this->consume() != ';') + { + $this->unconsume(); + } + + $consumed_length = strlen($this->consumed); + $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length); + $this->position += strlen($replacement) - $consumed_length; + } + break; + + default: + static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C"); + + for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++) + { + $consumed = substr($this->consumed, 1); + if (isset($entities[$consumed])) + { + $match = $consumed; + } + } + + if ($match !== null) + { + $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1); + $this->position += strlen($entities[$match]) - strlen($consumed) - 1; + } + break; + } + } +} + +/** + * Date Parser + * + * @package SimplePie + */ +class SimplePie_Parse_Date +{ + /** + * Input data + * + * @access protected + * @var string + */ + var $date; + + /** + * List of days, calendar day name => ordinal day number in the week + * + * @access protected + * @var array + */ + var $day = array( + // English + 'mon' => 1, + 'monday' => 1, + 'tue' => 2, + 'tuesday' => 2, + 'wed' => 3, + 'wednesday' => 3, + 'thu' => 4, + 'thursday' => 4, + 'fri' => 5, + 'friday' => 5, + 'sat' => 6, + 'saturday' => 6, + 'sun' => 7, + 'sunday' => 7, + // Dutch + 'maandag' => 1, + 'dinsdag' => 2, + 'woensdag' => 3, + 'donderdag' => 4, + 'vrijdag' => 5, + 'zaterdag' => 6, + 'zondag' => 7, + // French + 'lundi' => 1, + 'mardi' => 2, + 'mercredi' => 3, + 'jeudi' => 4, + 'vendredi' => 5, + 'samedi' => 6, + 'dimanche' => 7, + // German + 'montag' => 1, + 'dienstag' => 2, + 'mittwoch' => 3, + 'donnerstag' => 4, + 'freitag' => 5, + 'samstag' => 6, + 'sonnabend' => 6, + 'sonntag' => 7, + // Italian + 'lunedì' => 1, + 'martedì' => 2, + 'mercoledì' => 3, + 'giovedì' => 4, + 'venerdì' => 5, + 'sabato' => 6, + 'domenica' => 7, + // Spanish + 'lunes' => 1, + 'martes' => 2, + 'miércoles' => 3, + 'jueves' => 4, + 'viernes' => 5, + 'sábado' => 6, + 'domingo' => 7, + // Finnish + 'maanantai' => 1, + 'tiistai' => 2, + 'keskiviikko' => 3, + 'torstai' => 4, + 'perjantai' => 5, + 'lauantai' => 6, + 'sunnuntai' => 7, + // Hungarian + 'hétfő' => 1, + 'kedd' => 2, + 'szerda' => 3, + 'csütörtok' => 4, + 'péntek' => 5, + 'szombat' => 6, + 'vasárnap' => 7, + // Greek + 'Δευ' => 1, + 'Τρι' => 2, + 'Τετ' => 3, + 'Πεμ' => 4, + 'Παρ' => 5, + 'Σαβ' => 6, + 'Κυρ' => 7, + ); + + /** + * List of months, calendar month name => calendar month number + * + * @access protected + * @var array + */ + var $month = array( + // English + 'jan' => 1, + 'january' => 1, + 'feb' => 2, + 'february' => 2, + 'mar' => 3, + 'march' => 3, + 'apr' => 4, + 'april' => 4, + 'may' => 5, + // No long form of May + 'jun' => 6, + 'june' => 6, + 'jul' => 7, + 'july' => 7, + 'aug' => 8, + 'august' => 8, + 'sep' => 9, + 'september' => 8, + 'oct' => 10, + 'october' => 10, + 'nov' => 11, + 'november' => 11, + 'dec' => 12, + 'december' => 12, + // Dutch + 'januari' => 1, + 'februari' => 2, + 'maart' => 3, + 'april' => 4, + 'mei' => 5, + 'juni' => 6, + 'juli' => 7, + 'augustus' => 8, + 'september' => 9, + 'oktober' => 10, + 'november' => 11, + 'december' => 12, + // French + 'janvier' => 1, + 'février' => 2, + 'mars' => 3, + 'avril' => 4, + 'mai' => 5, + 'juin' => 6, + 'juillet' => 7, + 'août' => 8, + 'septembre' => 9, + 'octobre' => 10, + 'novembre' => 11, + 'décembre' => 12, + // German + 'januar' => 1, + 'februar' => 2, + 'märz' => 3, + 'april' => 4, + 'mai' => 5, + 'juni' => 6, + 'juli' => 7, + 'august' => 8, + 'september' => 9, + 'oktober' => 10, + 'november' => 11, + 'dezember' => 12, + // Italian + 'gennaio' => 1, + 'febbraio' => 2, + 'marzo' => 3, + 'aprile' => 4, + 'maggio' => 5, + 'giugno' => 6, + 'luglio' => 7, + 'agosto' => 8, + 'settembre' => 9, + 'ottobre' => 10, + 'novembre' => 11, + 'dicembre' => 12, + // Spanish + 'enero' => 1, + 'febrero' => 2, + 'marzo' => 3, + 'abril' => 4, + 'mayo' => 5, + 'junio' => 6, + 'julio' => 7, + 'agosto' => 8, + 'septiembre' => 9, + 'setiembre' => 9, + 'octubre' => 10, + 'noviembre' => 11, + 'diciembre' => 12, + // Finnish + 'tammikuu' => 1, + 'helmikuu' => 2, + 'maaliskuu' => 3, + 'huhtikuu' => 4, + 'toukokuu' => 5, + 'kesäkuu' => 6, + 'heinäkuu' => 7, + 'elokuu' => 8, + 'suuskuu' => 9, + 'lokakuu' => 10, + 'marras' => 11, + 'joulukuu' => 12, + // Hungarian + 'január' => 1, + 'február' => 2, + 'március' => 3, + 'április' => 4, + 'május' => 5, + 'június' => 6, + 'július' => 7, + 'augusztus' => 8, + 'szeptember' => 9, + 'október' => 10, + 'november' => 11, + 'december' => 12, + // Greek + 'Ιαν' => 1, + 'Φεβ' => 2, + 'Μάώ' => 3, + 'Μαώ' => 3, + 'Απρ' => 4, + 'Μάι' => 5, + 'Μαϊ' => 5, + 'Μαι' => 5, + 'Ιούν' => 6, + 'Ιον' => 6, + 'Ιούλ' => 7, + 'Ιολ' => 7, + 'Αύγ' => 8, + 'Αυγ' => 8, + 'Σεπ' => 9, + 'Οκτ' => 10, + 'Νοέ' => 11, + 'Δεκ' => 12, + ); + + /** + * List of timezones, abbreviation => offset from UTC + * + * @access protected + * @var array + */ + var $timezone = array( + 'ACDT' => 37800, + 'ACIT' => 28800, + 'ACST' => 34200, + 'ACT' => -18000, + 'ACWDT' => 35100, + 'ACWST' => 31500, + 'AEDT' => 39600, + 'AEST' => 36000, + 'AFT' => 16200, + 'AKDT' => -28800, + 'AKST' => -32400, + 'AMDT' => 18000, + 'AMT' => -14400, + 'ANAST' => 46800, + 'ANAT' => 43200, + 'ART' => -10800, + 'AZOST' => -3600, + 'AZST' => 18000, + 'AZT' => 14400, + 'BIOT' => 21600, + 'BIT' => -43200, + 'BOT' => -14400, + 'BRST' => -7200, + 'BRT' => -10800, + 'BST' => 3600, + 'BTT' => 21600, + 'CAST' => 18000, + 'CAT' => 7200, + 'CCT' => 23400, + 'CDT' => -18000, + 'CEDT' => 7200, + 'CET' => 3600, + 'CGST' => -7200, + 'CGT' => -10800, + 'CHADT' => 49500, + 'CHAST' => 45900, + 'CIST' => -28800, + 'CKT' => -36000, + 'CLDT' => -10800, + 'CLST' => -14400, + 'COT' => -18000, + 'CST' => -21600, + 'CVT' => -3600, + 'CXT' => 25200, + 'DAVT' => 25200, + 'DTAT' => 36000, + 'EADT' => -18000, + 'EAST' => -21600, + 'EAT' => 10800, + 'ECT' => -18000, + 'EDT' => -14400, + 'EEST' => 10800, + 'EET' => 7200, + 'EGT' => -3600, + 'EKST' => 21600, + 'EST' => -18000, + 'FJT' => 43200, + 'FKDT' => -10800, + 'FKST' => -14400, + 'FNT' => -7200, + 'GALT' => -21600, + 'GEDT' => 14400, + 'GEST' => 10800, + 'GFT' => -10800, + 'GILT' => 43200, + 'GIT' => -32400, + 'GST' => 14400, + 'GST' => -7200, + 'GYT' => -14400, + 'HAA' => -10800, + 'HAC' => -18000, + 'HADT' => -32400, + 'HAE' => -14400, + 'HAP' => -25200, + 'HAR' => -21600, + 'HAST' => -36000, + 'HAT' => -9000, + 'HAY' => -28800, + 'HKST' => 28800, + 'HMT' => 18000, + 'HNA' => -14400, + 'HNC' => -21600, + 'HNE' => -18000, + 'HNP' => -28800, + 'HNR' => -25200, + 'HNT' => -12600, + 'HNY' => -32400, + 'IRDT' => 16200, + 'IRKST' => 32400, + 'IRKT' => 28800, + 'IRST' => 12600, + 'JFDT' => -10800, + 'JFST' => -14400, + 'JST' => 32400, + 'KGST' => 21600, + 'KGT' => 18000, + 'KOST' => 39600, + 'KOVST' => 28800, + 'KOVT' => 25200, + 'KRAST' => 28800, + 'KRAT' => 25200, + 'KST' => 32400, + 'LHDT' => 39600, + 'LHST' => 37800, + 'LINT' => 50400, + 'LKT' => 21600, + 'MAGST' => 43200, + 'MAGT' => 39600, + 'MAWT' => 21600, + 'MDT' => -21600, + 'MESZ' => 7200, + 'MEZ' => 3600, + 'MHT' => 43200, + 'MIT' => -34200, + 'MNST' => 32400, + 'MSDT' => 14400, + 'MSST' => 10800, + 'MST' => -25200, + 'MUT' => 14400, + 'MVT' => 18000, + 'MYT' => 28800, + 'NCT' => 39600, + 'NDT' => -9000, + 'NFT' => 41400, + 'NMIT' => 36000, + 'NOVST' => 25200, + 'NOVT' => 21600, + 'NPT' => 20700, + 'NRT' => 43200, + 'NST' => -12600, + 'NUT' => -39600, + 'NZDT' => 46800, + 'NZST' => 43200, + 'OMSST' => 25200, + 'OMST' => 21600, + 'PDT' => -25200, + 'PET' => -18000, + 'PETST' => 46800, + 'PETT' => 43200, + 'PGT' => 36000, + 'PHOT' => 46800, + 'PHT' => 28800, + 'PKT' => 18000, + 'PMDT' => -7200, + 'PMST' => -10800, + 'PONT' => 39600, + 'PST' => -28800, + 'PWT' => 32400, + 'PYST' => -10800, + 'PYT' => -14400, + 'RET' => 14400, + 'ROTT' => -10800, + 'SAMST' => 18000, + 'SAMT' => 14400, + 'SAST' => 7200, + 'SBT' => 39600, + 'SCDT' => 46800, + 'SCST' => 43200, + 'SCT' => 14400, + 'SEST' => 3600, + 'SGT' => 28800, + 'SIT' => 28800, + 'SRT' => -10800, + 'SST' => -39600, + 'SYST' => 10800, + 'SYT' => 7200, + 'TFT' => 18000, + 'THAT' => -36000, + 'TJT' => 18000, + 'TKT' => -36000, + 'TMT' => 18000, + 'TOT' => 46800, + 'TPT' => 32400, + 'TRUT' => 36000, + 'TVT' => 43200, + 'TWT' => 28800, + 'UYST' => -7200, + 'UYT' => -10800, + 'UZT' => 18000, + 'VET' => -14400, + 'VLAST' => 39600, + 'VLAT' => 36000, + 'VOST' => 21600, + 'VUT' => 39600, + 'WAST' => 7200, + 'WAT' => 3600, + 'WDT' => 32400, + 'WEST' => 3600, + 'WFT' => 43200, + 'WIB' => 25200, + 'WIT' => 32400, + 'WITA' => 28800, + 'WKST' => 18000, + 'WST' => 28800, + 'YAKST' => 36000, + 'YAKT' => 32400, + 'YAPT' => 36000, + 'YEKST' => 21600, + 'YEKT' => 18000, + ); + + /** + * Cached PCRE for SimplePie_Parse_Date::$day + * + * @access protected + * @var string + */ + var $day_pcre; + + /** + * Cached PCRE for SimplePie_Parse_Date::$month + * + * @access protected + * @var string + */ + var $month_pcre; + + /** + * Array of user-added callback methods + * + * @access private + * @var array + */ + var $built_in = array(); + + /** + * Array of user-added callback methods + * + * @access private + * @var array + */ + var $user = array(); + + /** + * Create new SimplePie_Parse_Date object, and set self::day_pcre, + * self::month_pcre, and self::built_in + * + * @access private + */ + function SimplePie_Parse_Date() + { + $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')'; + $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')'; + + static $cache; + if (!isset($cache[get_class($this)])) + { + if (extension_loaded('Reflection')) + { + $class = new ReflectionClass(get_class($this)); + $methods = $class->getMethods(); + $all_methods = array(); + foreach ($methods as $method) + { + $all_methods[] = $method->getName(); + } + } + else + { + $all_methods = get_class_methods($this); + } + + foreach ($all_methods as $method) + { + if (strtolower(substr($method, 0, 5)) === 'date_') + { + $cache[get_class($this)][] = $method; + } + } + } + + foreach ($cache[get_class($this)] as $method) + { + $this->built_in[] = $method; + } + } + + /** + * Get the object + * + * @access public + */ + function get() + { + static $object; + if (!$object) + { + $object = new SimplePie_Parse_Date; + } + return $object; + } + + /** + * Parse a date + * + * @final + * @access public + * @param string $date Date to parse + * @return int Timestamp corresponding to date string, or false on failure + */ + function parse($date) + { + foreach ($this->user as $method) + { + if (($returned = call_user_func($method, $date)) !== false) + { + return $returned; + } + } + + foreach ($this->built_in as $method) + { + if (($returned = call_user_func(array(&$this, $method), $date)) !== false) + { + return $returned; + } + } + + return false; + } + + /** + * Add a callback method to parse a date + * + * @final + * @access public + * @param callback $callback + */ + function add_callback($callback) + { + if (is_callable($callback)) + { + $this->user[] = $callback; + } + else + { + trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); + } + } + + /** + * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as + * well as allowing any of upper or lower case "T", horizontal tabs, or + * spaces to be used as the time seperator (including more than one)) + * + * @access protected + * @return int Timestamp + */ + function date_w3cdtf($date) + { + static $pcre; + if (!$pcre) + { + $year = '([0-9]{4})'; + $month = $day = $hour = $minute = $second = '([0-9]{2})'; + $decimal = '([0-9]*)'; + $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))'; + $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Year + 2: Month + 3: Day + 4: Hour + 5: Minute + 6: Second + 7: Decimal fraction of a second + 8: Zulu + 9: Timezone ± + 10: Timezone hours + 11: Timezone minutes + */ + + // Fill in empty matches + for ($i = count($match); $i <= 3; $i++) + { + $match[$i] = '1'; + } + + for ($i = count($match); $i <= 7; $i++) + { + $match[$i] = '0'; + } + + // Numeric timezone + if (isset($match[9]) && $match[9] !== '') + { + $timezone = $match[10] * 3600; + $timezone += $match[11] * 60; + if ($match[9] === '-') + { + $timezone = 0 - $timezone; + } + } + else + { + $timezone = 0; + } + + // Convert the number of seconds to an integer, taking decimals into account + $second = round($match[6] + $match[7] / pow(10, strlen($match[7]))); + + return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; + } + else + { + return false; + } + } + + /** + * Remove RFC822 comments + * + * @access protected + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function remove_rfc2822_comments($string) + { + $string = (string) $string; + $position = 0; + $length = strlen($string); + $depth = 0; + + $output = ''; + + while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) + { + $output .= substr($string, $position, $pos - $position); + $position = $pos + 1; + if ($string[$pos - 1] !== '\\') + { + $depth++; + while ($depth && $position < $length) + { + $position += strcspn($string, '()', $position); + if ($string[$position - 1] === '\\') + { + $position++; + continue; + } + elseif (isset($string[$position])) + { + switch ($string[$position]) + { + case '(': + $depth++; + break; + + case ')': + $depth--; + break; + } + $position++; + } + else + { + break; + } + } + } + else + { + $output .= '('; + } + } + $output .= substr($string, $position); + + return $output; + } + + /** + * Parse RFC2822's date format + * + * @access protected + * @return int Timestamp + */ + function date_rfc2822($date) + { + static $pcre; + if (!$pcre) + { + $wsp = '[\x09\x20]'; + $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; + $optional_fws = $fws . '?'; + $day_name = $this->day_pcre; + $month = $this->month_pcre; + $day = '([0-9]{1,2})'; + $hour = $minute = $second = '([0-9]{2})'; + $year = '([0-9]{2,4})'; + $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; + $character_zone = '([A-Z]{1,5})'; + $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; + $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i'; + } + if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Day + 3: Month + 4: Year + 5: Hour + 6: Minute + 7: Second + 8: Timezone ± + 9: Timezone hours + 10: Timezone minutes + 11: Alphabetic timezone + */ + + // Find the month number + $month = $this->month[strtolower($match[3])]; + + // Numeric timezone + if ($match[8] !== '') + { + $timezone = $match[9] * 3600; + $timezone += $match[10] * 60; + if ($match[8] === '-') + { + $timezone = 0 - $timezone; + } + } + // Character timezone + elseif (isset($this->timezone[strtoupper($match[11])])) + { + $timezone = $this->timezone[strtoupper($match[11])]; + } + // Assume everything else to be -0000 + else + { + $timezone = 0; + } + + // Deal with 2/3 digit years + if ($match[4] < 50) + { + $match[4] += 2000; + } + elseif ($match[4] < 1000) + { + $match[4] += 1900; + } + + // Second is optional, if it is empty set it to zero + if ($match[7] !== '') + { + $second = $match[7]; + } + else + { + $second = 0; + } + + return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; + } + else + { + return false; + } + } + + /** + * Parse RFC850's date format + * + * @access protected + * @return int Timestamp + */ + function date_rfc850($date) + { + static $pcre; + if (!$pcre) + { + $space = '[\x09\x20]+'; + $day_name = $this->day_pcre; + $month = $this->month_pcre; + $day = '([0-9]{1,2})'; + $year = $hour = $minute = $second = '([0-9]{2})'; + $zone = '([A-Z]{1,5})'; + $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Day + 3: Month + 4: Year + 5: Hour + 6: Minute + 7: Second + 8: Timezone + */ + + // Month + $month = $this->month[strtolower($match[3])]; + + // Character timezone + if (isset($this->timezone[strtoupper($match[8])])) + { + $timezone = $this->timezone[strtoupper($match[8])]; + } + // Assume everything else to be -0000 + else + { + $timezone = 0; + } + + // Deal with 2 digit year + if ($match[4] < 50) + { + $match[4] += 2000; + } + else + { + $match[4] += 1900; + } + + return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; + } + else + { + return false; + } + } + + /** + * Parse C99's asctime()'s date format + * + * @access protected + * @return int Timestamp + */ + function date_asctime($date) + { + static $pcre; + if (!$pcre) + { + $space = '[\x09\x20]+'; + $wday_name = $this->day_pcre; + $mon_name = $this->month_pcre; + $day = '([0-9]{1,2})'; + $hour = $sec = $min = '([0-9]{2})'; + $year = '([0-9]{4})'; + $terminator = '\x0A?\x00?'; + $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Month + 3: Day + 4: Hour + 5: Minute + 6: Second + 7: Year + */ + + $month = $this->month[strtolower($match[2])]; + return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); + } + else + { + return false; + } + } + + /** + * Parse dates using strtotime() + * + * @access protected + * @return int Timestamp + */ + function date_strtotime($date) + { + $strtotime = strtotime($date); + if ($strtotime === -1 || $strtotime === false) + { + return false; + } + else + { + return $strtotime; + } + } +} + +/** + * Content-type sniffing + * + * @package SimplePie + */ +class SimplePie_Content_Type_Sniffer +{ + /** + * File object + * + * @var SimplePie_File + * @access private + */ + var $file; + + /** + * Create an instance of the class with the input file + * + * @access public + * @param SimplePie_Content_Type_Sniffer $file Input file + */ + function SimplePie_Content_Type_Sniffer($file) + { + $this->file = $file; + } + + /** + * Get the Content-Type of the specified file + * + * @access public + * @return string Actual Content-Type + */ + function get_type() + { + if (isset($this->file->headers['content-type'])) + { + if (!isset($this->file->headers['content-encoding']) + && ($this->file->headers['content-type'] === 'text/plain' + || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1' + || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1')) + { + return $this->text_or_binary(); + } + + if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) + { + $official = substr($this->file->headers['content-type'], 0, $pos); + } + else + { + $official = $this->file->headers['content-type']; + } + $official = strtolower($official); + + if ($official === 'unknown/unknown' + || $official === 'application/unknown') + { + return $this->unknown(); + } + elseif (substr($official, -4) === '+xml' + || $official === 'text/xml' + || $official === 'application/xml') + { + return $official; + } + elseif (substr($official, 0, 6) === 'image/') + { + if ($return = $this->image()) + { + return $return; + } + else + { + return $official; + } + } + elseif ($official === 'text/html') + { + return $this->feed_or_html(); + } + else + { + return $official; + } + } + else + { + return $this->unknown(); + } + } + + /** + * Sniff text or binary + * + * @access private + * @return string Actual Content-Type + */ + function text_or_binary() + { + if (substr($this->file->body, 0, 2) === "\xFE\xFF" + || substr($this->file->body, 0, 2) === "\xFF\xFE" + || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF" + || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") + { + return 'text/plain'; + } + elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) + { + return 'application/octect-stream'; + } + else + { + return 'text/plain'; + } + } + + /** + * Sniff unknown + * + * @access private + * @return string Actual Content-Type + */ + function unknown() + { + $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20"); + if (strtolower(substr($this->file->body, $ws, 14)) === 'file->body, $ws, 5)) === 'file->body, $ws, 7)) === 'file->body, 0, 5) === '%PDF-') + { + return 'application/pdf'; + } + elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') + { + return 'application/postscript'; + } + elseif (substr($this->file->body, 0, 6) === 'GIF87a' + || substr($this->file->body, 0, 6) === 'GIF89a') + { + return 'image/gif'; + } + elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") + { + return 'image/png'; + } + elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") + { + return 'image/jpeg'; + } + elseif (substr($this->file->body, 0, 2) === "\x42\x4D") + { + return 'image/bmp'; + } + else + { + return $this->text_or_binary(); + } + } + + /** + * Sniff images + * + * @access private + * @return string Actual Content-Type + */ + function image() + { + if (substr($this->file->body, 0, 6) === 'GIF87a' + || substr($this->file->body, 0, 6) === 'GIF89a') + { + return 'image/gif'; + } + elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") + { + return 'image/png'; + } + elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") + { + return 'image/jpeg'; + } + elseif (substr($this->file->body, 0, 2) === "\x42\x4D") + { + return 'image/bmp'; + } + else + { + return false; + } + } + + /** + * Sniff HTML + * + * @access private + * @return string Actual Content-Type + */ + function feed_or_html() + { + $len = strlen($this->file->body); + $pos = strspn($this->file->body, "\x09\x0A\x0D\x20"); + + while ($pos < $len) + { + switch ($this->file->body[$pos]) + { + case "\x09": + case "\x0A": + case "\x0D": + case "\x20": + $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos); + continue 2; + + case '<': + $pos++; + break; + + default: + return 'text/html'; + } + + if (substr($this->file->body, $pos, 3) === '!--') + { + $pos += 3; + if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) + { + $pos += 3; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 1) === '!') + { + if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) + { + $pos++; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 1) === '?') + { + if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) + { + $pos += 2; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 3) === 'rss' + || substr($this->file->body, $pos, 7) === 'rdf:RDF') + { + return 'application/rss+xml'; + } + elseif (substr($this->file->body, $pos, 4) === 'feed') + { + return 'application/atom+xml'; + } + else + { + return 'text/html'; + } + } + + return 'text/html'; + } +} + +/** + * Parses the XML Declaration + * + * @package SimplePie + */ +class SimplePie_XML_Declaration_Parser +{ + /** + * XML Version + * + * @access public + * @var string + */ + var $version = '1.0'; + + /** + * Encoding + * + * @access public + * @var string + */ + var $encoding = 'UTF-8'; + + /** + * Standalone + * + * @access public + * @var bool + */ + var $standalone = false; + + /** + * Current state of the state machine + * + * @access private + * @var string + */ + var $state = 'before_version_name'; + + /** + * Input data + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Input data length (to avoid calling strlen() everytime this is needed) + * + * @access private + * @var int + */ + var $data_length = 0; + + /** + * Current position of the pointer + * + * @var int + * @access private + */ + var $position = 0; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_XML_Declaration_Parser($data) + { + $this->data = $data; + $this->data_length = strlen($this->data); + } + + /** + * Parse the input data + * + * @access public + * @return bool true on success, false on failure + */ + function parse() + { + while ($this->state && $this->state !== 'emit' && $this->has_data()) + { + $state = $this->state; + $this->$state(); + } + $this->data = ''; + if ($this->state === 'emit') + { + return true; + } + else + { + $this->version = ''; + $this->encoding = ''; + $this->standalone = ''; + return false; + } + } + + /** + * Check whether there is data beyond the pointer + * + * @access private + * @return bool true if there is further data, false if not + */ + function has_data() + { + return (bool) ($this->position < $this->data_length); + } + + /** + * Advance past any whitespace + * + * @return int Number of whitespace characters passed + */ + function skip_whitespace() + { + $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position); + $this->position += $whitespace; + return $whitespace; + } + + /** + * Read value + */ + function get_value() + { + $quote = substr($this->data, $this->position, 1); + if ($quote === '"' || $quote === "'") + { + $this->position++; + $len = strcspn($this->data, $quote, $this->position); + if ($this->has_data()) + { + $value = substr($this->data, $this->position, $len); + $this->position += $len + 1; + return $value; + } + } + return false; + } + + function before_version_name() + { + if ($this->skip_whitespace()) + { + $this->state = 'version_name'; + } + else + { + $this->state = false; + } + } + + function version_name() + { + if (substr($this->data, $this->position, 7) === 'version') + { + $this->position += 7; + $this->skip_whitespace(); + $this->state = 'version_equals'; + } + else + { + $this->state = false; + } + } + + function version_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'version_value'; + } + else + { + $this->state = false; + } + } + + function version_value() + { + if ($this->version = $this->get_value()) + { + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = 'encoding_name'; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = 'standalone_name'; + } + } + + function encoding_name() + { + if (substr($this->data, $this->position, 8) === 'encoding') + { + $this->position += 8; + $this->skip_whitespace(); + $this->state = 'encoding_equals'; + } + else + { + $this->state = false; + } + } + + function encoding_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'encoding_value'; + } + else + { + $this->state = false; + } + } + + function encoding_value() + { + if ($this->encoding = $this->get_value()) + { + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = 'standalone_name'; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = false; + } + } + + function standalone_name() + { + if (substr($this->data, $this->position, 10) === 'standalone') + { + $this->position += 10; + $this->skip_whitespace(); + $this->state = 'standalone_equals'; + } + else + { + $this->state = false; + } + } + + function standalone_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'standalone_value'; + } + else + { + $this->state = false; + } + } + + function standalone_value() + { + if ($standalone = $this->get_value()) + { + switch ($standalone) + { + case 'yes': + $this->standalone = true; + break; + + case 'no': + $this->standalone = false; + break; + + default: + $this->state = false; + return; + } + + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = false; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = false; + } + } +} + +class SimplePie_Locator +{ + var $useragent; + var $timeout; + var $file; + var $local = array(); + var $elsewhere = array(); + var $file_class = 'SimplePie_File'; + var $cached_entities = array(); + var $http_base; + var $base; + var $base_location = 0; + var $checked_feeds = 0; + var $max_checked_feeds = 10; + var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; + + function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer') + { + $this->file =& $file; + $this->file_class = $file_class; + $this->useragent = $useragent; + $this->timeout = $timeout; + $this->max_checked_feeds = $max_checked_feeds; + $this->content_type_sniffer_class; + } + + function find($type = SIMPLEPIE_LOCATOR_ALL) + { + if ($this->is_feed($this->file)) + { + return $this->file; + } + + if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) + { + $sniffer = new $this->content_type_sniffer_class($this->file); + if ($sniffer->get_type() !== 'text/html') + { + return null; + } + } + + if ($type & ~SIMPLEPIE_LOCATOR_NONE) + { + $this->get_base(); + } + + if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) + { + return $working; + } + + if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) + { + if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) + { + return $working; + } + } + return null; + } + + function is_feed(&$file) + { + if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) + { + $sniffer = new $this->content_type_sniffer_class($file); + $sniffed = $sniffer->get_type(); + if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain'))) + { + return true; + } + else + { + return false; + } + } + elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) + { + return true; + } + else + { + return false; + } + } + + function get_base() + { + $this->http_base = $this->file->url; + $this->base = $this->http_base; + $elements = SimplePie_Misc::get_element('base', $this->file->body); + foreach ($elements as $element) + { + if ($element['attribs']['href']['data'] !== '') + { + $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base); + $this->base_location = $element['offset']; + break; + } + } + } + + function autodiscovery() + { + $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body)); + $done = array(); + foreach ($links as $link) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data'])) + { + $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data']))); + + if ($this->base_location < $link['offset']) + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); + } + else + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); + } + + if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml')))) + { + $this->checked_feeds++; + $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + } + $done[] = $href; + } + } + return null; + } + + function get_links() + { + $links = SimplePie_Misc::get_element('a', $this->file->body); + foreach ($links as $link) + { + if (isset($link['attribs']['href']['data'])) + { + $href = trim($link['attribs']['href']['data']); + $parsed = SimplePie_Misc::parse_url($href); + if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) + { + if ($this->base_location < $link['offset']) + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); + } + else + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); + } + + $current = SimplePie_Misc::parse_url($this->file->url); + + if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority']) + { + $this->local[] = $href; + } + else + { + $this->elsewhere[] = $href; + } + } + } + } + $this->local = array_unique($this->local); + $this->elsewhere = array_unique($this->elsewhere); + if (!empty($this->local) || !empty($this->elsewhere)) + { + return true; + } + return null; + } + + function extension(&$array) + { + foreach ($array as $key => $value) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) + { + $this->checked_feeds++; + $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + else + { + unset($array[$key]); + } + } + } + return null; + } + + function body(&$array) + { + foreach ($array as $key => $value) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (preg_match('/(rss|rdf|atom|xml)/i', $value)) + { + $this->checked_feeds++; + $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + else + { + unset($array[$key]); + } + } + } + return null; + } +} + +class SimplePie_Parser +{ + var $error_code; + var $error_string; + var $current_line; + var $current_column; + var $current_byte; + var $separator = ' '; + var $feed = false; + var $namespace = array(''); + var $element = array(''); + var $xml_base = array(''); + var $xml_base_explicit = array(false); + var $xml_lang = array(''); + var $data = array(); + var $datas = array(array()); + var $current_xhtml_construct = -1; + var $encoding; + + function parse(&$data, $encoding) + { + // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character + if (strtoupper($encoding) == 'US-ASCII') + { + $this->encoding = 'UTF-8'; + } + else + { + $this->encoding = $encoding; + } + + // Strip BOM: + // UTF-32 Big Endian BOM + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") + { + $data = substr($data, 4); + } + // UTF-32 Little Endian BOM + elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") + { + $data = substr($data, 4); + } + // UTF-16 Big Endian BOM + elseif (substr($data, 0, 2) === "\xFE\xFF") + { + $data = substr($data, 2); + } + // UTF-16 Little Endian BOM + elseif (substr($data, 0, 2) === "\xFF\xFE") + { + $data = substr($data, 2); + } + // UTF-8 BOM + elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") + { + $data = substr($data, 3); + } + + if (substr($data, 0, 5) === '')) !== false) + { + $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); + if ($declaration->parse()) + { + $data = substr($data, $pos + 2); + $data = 'version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data; + } + else + { + $this->error_string = 'SimplePie bug! Please report this!'; + return false; + } + } + + $return = true; + + // Create the parser + $xml = xml_parser_create_ns($this->encoding, $this->separator); + xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xml, $this); + xml_set_character_data_handler($xml, 'cdata'); + xml_set_element_handler($xml, 'tag_open', 'tag_close'); + + // Parse! + if (!xml_parse($xml, $data, true)) + { + $this->error_code = xml_get_error_code($xml); + $this->error_string = xml_error_string($this->error_code); + $return = false; + } + $this->current_line = xml_get_current_line_number($xml); + $this->current_column = xml_get_current_column_number($xml); + $this->current_byte = xml_get_current_byte_index($xml); + xml_parser_free($xml); + return $return; + } + + function get_error_code() + { + return $this->error_code; + } + + function get_error_string() + { + return $this->error_string; + } + + function get_current_line() + { + return $this->current_line; + } + + function get_current_column() + { + return $this->current_column; + } + + function get_current_byte() + { + return $this->current_byte; + } + + function get_data() + { + return $this->data; + } + + function tag_open($parser, $tag, $attributes) + { + if ($this->feed === 0) + { + return; + } + elseif ($this->feed == false) + { + if (in_array($tag, array( + SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed', + SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed', + 'rss', + SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF' + ))) + { + $this->feed = 1; + } + } + else + { + $this->feed++; + } + + list($this->namespace[], $this->element[]) = $this->split_ns($tag); + + $attribs = array(); + foreach ($attributes as $name => $value) + { + list($attrib_namespace, $attribute) = $this->split_ns($name); + $attribs[$attrib_namespace][$attribute] = $value; + } + + if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base'])) + { + $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)); + $this->xml_base_explicit[] = true; + } + else + { + $this->xml_base[] = end($this->xml_base); + $this->xml_base_explicit[] = end($this->xml_base_explicit); + } + + if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang'])) + { + $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang']; + } + else + { + $this->xml_lang[] = end($this->xml_lang); + } + + if ($this->current_xhtml_construct >= 0) + { + $this->current_xhtml_construct++; + if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML) + { + $this->data['data'] .= '<' . end($this->element); + if (isset($attribs[''])) + { + foreach ($attribs[''] as $name => $value) + { + $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"'; + } + } + $this->data['data'] .= '>'; + } + } + else + { + $this->datas[] =& $this->data; + $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][]; + $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang)); + if ((end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] == 'xml') + || (end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] == 'xhtml')) + { + $this->current_xhtml_construct = 0; + } + } + } + + function cdata($parser, $cdata) + { + if ($this->current_xhtml_construct >= 0) + { + $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding); + } + elseif ($this->feed > 1) + { + $this->data['data'] .= $cdata; + } + } + + function tag_close($parser, $tag) + { + if (!$this->feed) + { + return; + } + + if ($this->current_xhtml_construct >= 0) + { + $this->current_xhtml_construct--; + if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'))) + { + $this->data['data'] .= 'element) . '>'; + } + } + if ($this->current_xhtml_construct == -1) + { + $this->data =& $this->datas[$this->feed]; + array_pop($this->datas); + } + + array_pop($this->element); + array_pop($this->namespace); + array_pop($this->xml_base); + array_pop($this->xml_base_explicit); + array_pop($this->xml_lang); + $this->feed--; + } + + function split_ns($string) + { + static $cache = array(); + if (!isset($cache[$string])) + { + if ($pos = strpos($string, $this->separator)) + { + static $separator_length; + if (!$separator_length) + { + $separator_length = strlen($this->separator); + } + $namespace = substr($string, 0, $pos); + $local_name = substr($string, $pos + $separator_length); + if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES) + { + $namespace = SIMPLEPIE_NAMESPACE_ITUNES; + } + $cache[$string] = array($namespace, $local_name); + } + else + { + $cache[$string] = array('', $string); + } + } + return $cache[$string]; + } +} + +/** + * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags + */ +class SimplePie_Sanitize +{ + // Private vars + var $base; + + // Options + var $remove_div = true; + var $image_handler = ''; + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + var $encode_instead_of_strip = false; + var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); + var $strip_comments = false; + var $output_encoding = 'UTF-8'; + var $enable_cache = true; + var $cache_location = './cache'; + var $cache_name_function = 'md5'; + var $cache_class = 'SimplePie_Cache'; + var $file_class = 'SimplePie_File'; + var $timeout = 10; + var $useragent = ''; + var $force_fsockopen = false; + + var $replace_url_attributes = array( + 'a' => 'href', + 'area' => 'href', + 'blockquote' => 'cite', + 'del' => 'cite', + 'form' => 'action', + 'img' => array('longdesc', 'src'), + 'input' => 'src', + 'ins' => 'cite', + 'q' => 'cite' + ); + + function remove_div($enable = true) + { + $this->remove_div = (bool) $enable; + } + + function set_image_handler($page = false) + { + if ($page) + { + $this->image_handler = (string) $page; + } + else + { + $this->image_handler = false; + } + } + + function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache') + { + if (isset($enable_cache)) + { + $this->enable_cache = (bool) $enable_cache; + } + + if ($cache_location) + { + $this->cache_location = (string) $cache_location; + } + + if ($cache_name_function) + { + $this->cache_name_function = (string) $cache_name_function; + } + + if ($cache_class) + { + $this->cache_class = (string) $cache_class; + } + } + + function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false) + { + if ($file_class) + { + $this->file_class = (string) $file_class; + } + + if ($timeout) + { + $this->timeout = (string) $timeout; + } + + if ($useragent) + { + $this->useragent = (string) $useragent; + } + + if ($force_fsockopen) + { + $this->force_fsockopen = (string) $force_fsockopen; + } + } + + function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) + { + if ($tags) + { + if (is_array($tags)) + { + $this->strip_htmltags = $tags; + } + else + { + $this->strip_htmltags = explode(',', $tags); + } + } + else + { + $this->strip_htmltags = false; + } + } + + function encode_instead_of_strip($encode = false) + { + $this->encode_instead_of_strip = (bool) $encode; + } + + function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc')) + { + if ($attribs) + { + if (is_array($attribs)) + { + $this->strip_attributes = $attribs; + } + else + { + $this->strip_attributes = explode(',', $attribs); + } + } + else + { + $this->strip_attributes = false; + } + } + + function strip_comments($strip = false) + { + $this->strip_comments = (bool) $strip; + } + + function set_output_encoding($encoding = 'UTF-8') + { + $this->output_encoding = (string) $encoding; + } + + /** + * Set element/attribute key/value pairs of HTML attributes + * containing URLs that need to be resolved relative to the feed + * + * @access public + * @since 1.0 + * @param array $element_attribute Element/attribute key/value pairs + */ + function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) + { + $this->replace_url_attributes = (array) $element_attribute; + } + + function sanitize($data, $type, $base = '') + { + $data = trim($data); + if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI) + { + if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) + { + if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) + { + $type |= SIMPLEPIE_CONSTRUCT_HTML; + } + else + { + $type |= SIMPLEPIE_CONSTRUCT_TEXT; + } + } + + if ($type & SIMPLEPIE_CONSTRUCT_BASE64) + { + $data = base64_decode($data); + } + + if ($type & SIMPLEPIE_CONSTRUCT_XHTML) + { + if ($this->remove_div) + { + $data = preg_replace('/^/', '', $data); + $data = preg_replace('/<\/div>$/', '', $data); + } + else + { + $data = preg_replace('/^/', '
    ', $data); + } + } + + if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) + { + // Strip comments + if ($this->strip_comments) + { + $data = SimplePie_Misc::strip_comments($data); + } + + // Strip out HTML tags and attributes that might cause various security problems. + // Based on recommendations by Mark Pilgrim at: + // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely + if ($this->strip_htmltags) + { + foreach ($this->strip_htmltags as $tag) + { + $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU'; + while (preg_match($pcre, $data)) + { + $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data); + } + } + } + + if ($this->strip_attributes) + { + foreach ($this->strip_attributes as $attrib) + { + $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data); + } + } + + // Replace relative URLs + $this->base = $base; + foreach ($this->replace_url_attributes as $element => $attributes) + { + $data = $this->replace_urls($data, $element, $attributes); + } + + // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags. + if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache) + { + $images = SimplePie_Misc::get_element('img', $data); + foreach ($images as $img) + { + if (isset($img['attribs']['src']['data'])) + { + $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']); + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi'); + + if ($cache->load()) + { + $img['attribs']['src']['data'] = $this->image_handler . $image_url; + $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); + } + else + { + $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); + $headers = $file->headers; + + if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300))) + { + if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) + { + $img['attribs']['src']['data'] = $this->image_handler . $image_url; + $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); + } + else + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + } + } + } + } + } + + // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data + $data = trim($data); + } + + if ($type & SIMPLEPIE_CONSTRUCT_IRI) + { + $data = SimplePie_Misc::absolutize_url($data, $base); + } + + if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) + { + $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8'); + } + + if ($this->output_encoding != 'UTF-8') + { + $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding); + } + } + return $data; + } + + function replace_urls($data, $tag, $attributes) + { + if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags)) + { + $elements = SimplePie_Misc::get_element($tag, $data); + foreach ($elements as $element) + { + if (is_array($attributes)) + { + foreach ($attributes as $attribute) + { + if (isset($element['attribs'][$attribute]['data'])) + { + $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base); + $new_element = SimplePie_Misc::element_implode($element); + $data = str_replace($element['full'], $new_element, $data); + $element['full'] = $new_element; + } + } + } + elseif (isset($element['attribs'][$attributes]['data'])) + { + $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base); + $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data); + } + } + } + return $data; + } + + function do_strip_htmltags($match) + { + if ($this->encode_instead_of_strip) + { + if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) + { + $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8'); + $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8'); + return "<$match[1]$match[2]>$match[3]</$match[1]>"; + } + else + { + return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8'); + } + } + elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) + { + return $match[4]; + } + else + { + return ''; + } + } +} + +?> \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/sweetcron.php.svn-base b/system/application/libraries/.svn/text-base/sweetcron.php.svn-base new file mode 100644 index 0000000..82f2687 --- /dev/null +++ b/system/application/libraries/.svn/text-base/sweetcron.php.svn-base @@ -0,0 +1,392 @@ +CI =& get_instance(); + $this->CI->config->set_item('sweetcron_version', '1.08e'); + } + + function fetch_items() + { + if(!ini_get('safe_mode')){ + //requires php to not be running in "safe mode" + set_time_limit(0); + } + //soz + $option->option_name = 'last_fetch'; + $option->option_value = time(); + $this->CI->option_model->add_option($option); + + $feeds = $this->CI->feed_model->get_active_feeds(); + if ($feeds) { + foreach ($feeds as $feed) { + $this->CI->simplepie->set_feed_url($feed->feed_url); + $this->CI->simplepie->enable_cache(FALSE); + $this->CI->simplepie->init(); + $items = $this->CI->simplepie->get_items(); + $this->add_new_items($items, $feed); + } + } + + } + + function add_new_items($items, $feed) + { + foreach ($items as $item) { + + $new->item_data = array(); + $new->item_data['title'] = $item->get_title(); + $new->item_data['permalink'] = $item->get_permalink(); + $new->item_data['content'] = $item->get_content(); + $new->item_data['enclosures'] = $item->get_enclosures(); + $new->item_data['categories'] = $item->get_categories(); + $new->item_data['tags'] = $this->get_tags($new->item_data); + $new->item_data['image'] = $this->get_image($item->get_content()); + + //build out clean item + $new->item_status = 'publish'; + $new->item_date = strtotime($item->get_date('D M j G:i:s Y')); + $new->item_title = $this->CI->input->xss_clean(trim(strip_tags($item->get_title()))); + $new->item_permalink = $item->get_permalink(); + $new->item_content = $this->CI->input->xss_clean(trim(strip_tags($item->get_content()))); + $new->item_name = url_title($new->item_title); + $new->item_feed_id = $feed->feed_id; + + $new = $this->extend('pre_db', $feed->feed_domain, $new, $item); + + //and add + $this->CI->item_model->add_item($new); + + } + } + + function pseudo_cron() + { + if ($this->CI->config->item('cron_type') == 'pseudo') { + //time in seconds between each pseudo cron + //if you want more frequent cron updates it's better to rely on "true cron" and to turn off pseudo cron + $interval = 1800; //1800 = 30 minutes + if (($this->CI->config->item('last_access') - $this->CI->config->item('last_fetch')) > $interval) { + $this->fetch_items(); + } + } + } + + function extend($method = 'pre_db', $feed_domain = NULL, $item = NULL, $simplepie_object = NULL) + { + //we can extend what sweetcron does at various points in the import / output process by using plugin architecture + //see system/applications/plugins for example plugins + if ($feed_domain && $item) { + $class = str_replace('.', '_', $feed_domain); + $plugin = BASEPATH.'application/plugins/'.$class.'.php'; + //support subdomain with base domain plugin if no subdomain-specific plugin exists + $domain = explode('.', $feed_domain); + if (isset($domain[2])) { + //this is a subdomain of a base domain + $is_subdomain = TRUE; + $base_class = str_replace($domain[0].'_', '', $class); + $base_plugin = BASEPATH.'application/plugins/'.$base_class.'.php'; + } else { + $is_subdomain = FALSE; + } + if (file_exists($plugin) || ($is_subdomain && file_exists($base_plugin))) { + //check if already loaded + if ($is_subdomain && file_exists($base_plugin)) { + if (!method_exists($base_class, $method)) { + include(BASEPATH.'application/plugins/'.$base_class.'.php'); + } + $plugin = new $base_class; + } else { + if (!method_exists($class, $method)) { + include(BASEPATH.'application/plugins/'.$class.'.php'); + } + $plugin = new $class; + } + return $plugin->$method($item, $simplepie_object); + } else { + return $item; + } + } + } + + function get_tags($data) + { + $tags = ''; + $other_tags = ''; + //attempt to pull from enclosures + if (isset($data['enclosures'][0]->categories[0]->term)) { + $tags = html_entity_decode($data['enclosures'][0]->categories[0]->term); + $tags = explode(' ', $tags); + } + + //attempt to pull from categories + if (isset($data['categories'][0]->term)) { + foreach ($data['categories'] as $category) { + //sometimes a tag is an ugly url that I don't think we want... + if (substr($category->term, 0, 7) != 'http://') { + $other_tags[] = html_entity_decode($category->term); + } + } + } + + $tags_count = count($tags); + $other_tags_count = count($other_tags); + + //lets go with whichever has the most... + if ($tags_count > $other_tags_count) { + $tags = $tags; + } else { + $tags = $other_tags; + } + + //clean before returning... + + return $tags; + } + + + function get_image($html) { + //kudos to: + //http://zytzagoo.net/blog/2008/01/23/extracting-images-from-html-using-regular-expressions/ + if (stripos($html, 'CI->uri->segment(2) == strtolower($page_name)) { + return true; + } + } + + function integrity_check() + { + if (!$this->CI->db->table_exists('feeds') || !$this->CI->db->table_exists('items') || !$this->CI->db->table_exists('options') || !$this->CI->db->table_exists('tags') || !$this->CI->db->table_exists('tag_relationships') || !$this->CI->db->table_exists('users')) { + if (file_exists(BASEPATH.'../.htaccess')) { + die('Whoo Hoo! Almost there - now just run the install script.'); + } else { + die('Looks like you are missing an .htaccess file...
    For instructions on creating one, please see the installation documentation'); + } + } + } + + function install_check() + { + if ($this->CI->db->table_exists('feeds') || $this->CI->db->table_exists('items') || $this->CI->db->table_exists('options') || $this->CI->db->table_exists('tags') || $this->CI->db->table_exists('tag_relationships') || $this->CI->db->table_exists('users')) { + die('Sweetcron is already (or partially) installed. If you wish to reinstall, please clear your database first.'); + } + } + + function compatibility_check() + { + //checks php version + if (version_compare(PHP_VERSION, '5.0.0', '<')) { + die('Sorry, Sweetcron is for PHP5 and above. Your version of PHP is lower than that. Time to upgrade?'); + } + if (function_exists('apache_get_modules')) { + $modules = apache_get_modules(); + if (!in_array("mod_rewrite", $modules)) { + die('Sorry, it looks like your server does not have mod_rewrite installed. Please contact your webhost to get it enabled.'); + } + } + } + + function do_search() + { + if ($this->CI->input->post('query')) { + //strip out stuff and send to page + $query = urlencode($this->CI->input->post('query')); + header('Location: '.$this->CI->config->item('base_url').'items/search/'.$query); + } else { + show_error('You must type some keywords to search'); + } + } + + function get_single_item_page($item_id = NULL) + { + if ($item_id) { + //remove query string (some 3rd party commenting services refer back after commenting) + $item_id = explode('?', $item_id); + $item_id = $item_id[0]; + $data->item = $this->CI->item_model->get_public_item_by_id($item_id); + $data->page_name = $data->item->get_title(); + $data->popular_tags = $this->CI->tag_model->get_all_tags('count', 50); + $data->all_tags = $this->CI->tag_model->get_all_tags('count'); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/single', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } + } + + function query_items($type = 'site', $query = NULL, $offset = 0, $limit = 10) + { + return $this->get_items_page($type, NULL, TRUE, $query, NULL, TRUE, $offset, $limit); + } + + function get_items_page($type = 'index', $current_page_num = 1, $public = FALSE, $query = NULL, $rss_filter = NULL, $query_items = NULL, $offset = NULL, $limit = NULL) + { + + //return raw items for query_items() + if ($query_items) { + if ($type == 'site') { + return $this->CI->item_model->get_items_by_feed_domain($offset, $limit, $query, $public); + } elseif ($type == 'tag') { + return $this->CI->item_model->get_items_by_tag($offset, $limit, $query, $public); + } elseif ($type == 'search') { + return $this->CI->item_model->get_items_by_search($offset, $limit, $query, $public); + } + exit(); + } + + $data->blog_posts = $this->CI->item_model->get_items_by_feed_domain(0, 10, 'sweetcron', $public); + $data->active_feeds = $this->CI->feed_model->get_active_feeds(TRUE); + $data->popular_tags = $this->CI->tag_model->get_all_tags('count', 50); + $data->all_tags = $this->CI->tag_model->get_all_tags('count'); + $data->page_type = $type; + + if ($type == 'rss_feed') { + if (!$rss_filter) { + $data->page_name = ''; + $data->items = $this->CI->item_model->get_all_items(0, 20, $public); + } elseif ($rss_filter == 'tag') { + $data->page_name = '- tagged with '.$query; + $data->items = $this->CI->item_model->get_items_by_tag(0, 20, $query, $public); + } elseif ($rss_filter == 'search') { + $data->page_name = '- search for '.$query; + $data->items = $this->CI->item_model->get_items_by_search(0, 20, $query, $public); + } elseif ($rss_filter == 'site') { + $data->page_name = '- imported from '.$query; + $data->items = $this->CI->item_model->get_items_by_feed_domain(0, 20, $query, $public); + } + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/rss_feed', $data); + } elseif ($type == 'static_page') { + + $page = $this->CI->uri->segment(2); + $data->page_name = ucwords($page); + if (file_exists(BASEPATH.'application/views/themes/'.$this->CI->config->item('theme').'/'.$page.'.php')) { + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/'.$page, $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } else { + show_404(); + } + } else { + + $this->CI->page->SetItemsPerPage($this->CI->config->item('per_page')); + $this->CI->page->SetQueryStringVar('page'); + $this->CI->page->SetLinksFormat('‹',' ','›'); + $this->CI->page->SetLinksToDisplay(10); + $this->CI->page->SetCurrentPage($current_page_num); + + if ($public) { + $admin = ''; + } else { + $admin = 'admin/'; + } + + //conditionals depending on page type + if ($type == 'index') { + $data->page_name = 'Home'; + $this->CI->page->SetItemCount($this->CI->item_model->count_all_items($public)); + if ($public) { + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin); + } else { + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/'); + } + $data->items = $this->CI->item_model->get_all_items($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $public); + } elseif ($type == 'search') { + $data->page_name = 'Items Search'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_search($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/search/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_search($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } elseif ($type == 'tag') { + $data->page_name = 'Items Tag'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_tag($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/tag/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_tag($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } elseif ($type == 'site') { + $data->page_name = 'Items Site'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_feed_domain($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/site/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_feed_domain($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } + + $data->page_query = $query; + + if ($query && $type == 'search') { + $data->query = $query; + } + + if ($query && $type == 'tag') { + $data->tag = urldecode($query); + } + + if ($query && $type == 'site') { + $data->site = $query; + } + + //load view + if ($public) { + $data->pages = $this->CI->page->GetPageLinks(); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/items', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } else { + $data->pages = $this->CI->page->GetPageLinks(); + $this->CI->load->view('admin/_header', $data); + $this->CI->load->view('admin/items', $data); + $this->CI->load->view('admin/_footer'); + } + + } + } + +} +?> \ No newline at end of file diff --git a/system/application/libraries/.svn/text-base/sweetcron_item.php.svn-base b/system/application/libraries/.svn/text-base/sweetcron_item.php.svn-base new file mode 100644 index 0000000..729030a --- /dev/null +++ b/system/application/libraries/.svn/text-base/sweetcron_item.php.svn-base @@ -0,0 +1,246 @@ +feed_id; + } + + function get_feed_title() + { + return $this->feed_title; + } + + function get_feed_icon() + { + return $this->feed_icon; + } + + function get_feed_url() + { + return $this->feed_url; + } + + function get_feed_data() + { + return $this->feed_data; + } + + function get_feed_status() + { + return $this->feed_status; + } + + function get_feed_domain() + { + return $this->feed_domain; + } + + function get_feed_class() + { + return $this->feed_class; + } + + //return item components + + function get_id() + { + return $this->ID; + } + + function get_date() + { + return $this->item_date; + } + + function get_nice_date() + { + return $this->nice_date; + } + + function get_human_date() + { + return $this->human_date; + } + + function get_content() + { + return $this->item_content; + } + + function get_title() + { + return $this->item_title; + } + + function get_permalink() + { + return $this->item_permalink; + } + + function get_original_permalink() + { + return $this->item_original_permalink; + } + + function get_status() + { + return $this->item_status; + } + + function get_name() + { + return $this->item_name; + } + + function get_parent() + { + return $this->item_parent; + } + + function get_data() + { + return $this->item_data; + } + + //"has" conditionals for item data + function has_content() + { + if (isset($this->item_content) && $this->item_content != '') { + return true; + } + } + + function has_permalink() + { + if (isset($this->item_permalink)) { + return true; + } + } + + function has_original_permalink() + { + if (isset($this->item_original_permalink)) { + return true; + } + } + + function has_video() + { + if (isset($this->item_data['video'])) { + return true; + } + } + + function has_audio() + { + if (isset($this->item_data['audio'])) { + return true; + } + } + + function has_image() + { + if (isset($this->item_data['image']) && !empty($this->item_data['image'])) { + return true; + } + } + + function has_tags() + { + if (isset($this->item_tags[0])) { + return true; + } + } + + function has_tag($query = NULL) + { + $query = strtolower($query); + if (isset($this->item_tags[0])) { + foreach ($this->item_tags as $tag) { + if ($tag->slug == $query) { + return true; + } + } + } + } + + function has_data($key = NULL) + { + if (isset($this->item_data[$key])) { + return true; + } + } + + //get item data + function get_video() + { + if ($this->has_video()) { + return $this->item_data['video']; + } + } + + function get_audio() + { + if ($this->has_audio()) { + return $this->item_data['audio']; + } + } + + function get_image() + { + if ($this->has_image()) { + return $this->item_data['image']; + } + } + + function get_tags() + { + if ($this->has_tags()) { + return $this->item_tags; + } else { + return array(); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/libraries/MY_Controller.php b/system/application/libraries/MY_Controller.php new file mode 100644 index 0000000..de6f23b --- /dev/null +++ b/system/application/libraries/MY_Controller.php @@ -0,0 +1,87 @@ +load->library('sweetcron'); + $this->load->file(BASEPATH.'/application/libraries/sweetcron_item.php'); + $this->sweetcron->compatibility_check(); + $this->sweetcron->integrity_check(); + + //load other stuff + $this->load->file(BASEPATH.'/application/libraries/markdown.php'); + $this->load->helper('text'); + $this->load->helper('url'); + $this->load->library('simplepie'); + $this->load->library('page'); + $this->load->model('feed_model'); + $this->load->model('item_model'); + $this->load->model('tag_model'); + $this->load->model('option_model'); + $this->load->helper('date'); + $this->load->library('auth'); + + //update last access + $option->option_name = 'last_access'; + $option->option_value = time(); + $this->option_model->add_option($option); + + //Set config items + $this->option_model->load_config_options(); + + //initiate pseudo-cron + $this->sweetcron->pseudo_cron(); + $this->data->user = $this->auth->get_user($this->session->userdata('user_id')); + } +} + +// Controllers accessible only by logged in users +class Auth_Controller extends Public_Controller { + function Auth_Controller() { + parent::Public_Controller(); + //OMG WHO R U + if ($this->data->user === FALSE) { + header('Location: '.$this->config->item('base_url').'admin/login'); + exit(); + } else { + return; + } + } +} \ No newline at end of file diff --git a/system/application/libraries/auth.php b/system/application/libraries/auth.php new file mode 100644 index 0000000..1883e6d --- /dev/null +++ b/system/application/libraries/auth.php @@ -0,0 +1,103 @@ +CI =& get_instance(); + log_message('debug', 'Authorization class initialized.'); + + $this->CI->load->database(); + } + + /*** + Determines whether the passed condition is valid to login a user, if so - sets a session variable containing the user's ID + * @param $condition array The condition to query the database for + * @return boolean + ***/ + function try_login($condition = array()) { + $query = $this->CI->db->getwhere($this->db_table, $condition, 1, 0); + + if ($query->num_rows != 1) { return FALSE; } + + $row = $query->row(); + $this->CI->session->set_userdata(array('user_id' => $row->ID, 'call_user' => $row->user_login)); + + return $row; + } + + + /*** + Returns an object containing user information via the user's ID + * @param $id integer The user's ID + * @return object Upon valid user + * @return FALSE Upon invalid user + ***/ + function get_user($id = FALSE) { + if ($id == FALSE) $id = $this->CI->session->userdata('user_id'); + if ($id == FALSE) return FALSE; + + $condition = array(($this->db_table . '.' . $this->db_userid) => $id); + + $query = $this->CI->db->getwhere($this->db_table, $condition, 1, 0); + + $row = ($query->num_rows() == 1) ? $query->row() : FALSE; + + return $row; + } + + /*** + Logs out a user by deleting their session variables + * @return null + ***/ + function logout() { + $this->CI->session->set_userdata(array('user_id' => FALSE)); + header('Location: '.$this->CI->config->item('base_url')); + } + + function is_logged() + { + if ($this->CI->data->user === FALSE) { + return false; + } else { + return true; + } + } + + + // use $this->auth->permit('super_admin') at the start of non-visual functions to prevent hackery + // parameter can be a string role or an array of roles + // if user is not of correct role they see an error page - they would only see this if they were + // trying something malicious, i.e. trying to access functions that their role doesn't allow + function permit($permitted_role = null) + { + if ($permitted_role) { + if (is_array($permitted_role)) { + if (!in_array($this->CI->data->user->user_role, $permitted_role)) { + return false; + } else { + return true; + } + } else { + if ($this->CI->data->user->user_role != $permitted_role) { + return false; + } else { + return true; + } + } + } + } + +} \ No newline at end of file diff --git a/system/application/libraries/index.html b/system/application/libraries/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/libraries/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/libraries/markdown.php b/system/application/libraries/markdown.php new file mode 100644 index 0000000..ed79197 --- /dev/null +++ b/system/application/libraries/markdown.php @@ -0,0 +1,2894 @@ + +# +# Original Markdown +# Copyright (c) 2004-2006 John Gruber +# +# + + +define( 'MARKDOWN_VERSION', "1.0.1m" ); # Sat 21 Jun 2008 +define( 'MARKDOWNEXTRA_VERSION', "1.2.2" ); # Sat 21 Jun 2008 + + +# +# Global default settings: +# + +# Change to ">" for HTML output +@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />"); + +# Define the width of a tab for code blocks. +@define( 'MARKDOWN_TAB_WIDTH', 4 ); + +# Optional title attribute for footnote links and backlinks. +@define( 'MARKDOWN_FN_LINK_TITLE', "" ); +@define( 'MARKDOWN_FN_BACKLINK_TITLE', "" ); + +# Optional class attribute for footnote links and backlinks. +@define( 'MARKDOWN_FN_LINK_CLASS', "" ); +@define( 'MARKDOWN_FN_BACKLINK_CLASS', "" ); + + +# +# WordPress settings: +# + +# Change to false to remove Markdown from posts and/or comments. +@define( 'MARKDOWN_WP_POSTS', true ); +@define( 'MARKDOWN_WP_COMMENTS', true ); + + + +### Standard Function Interface ### + +@define( 'MARKDOWN_PARSER_CLASS', 'MarkdownExtra_Parser' ); + +function Markdown($text) { +# +# Initialize the parser and return the result of its transform method. +# + # Setup static parser variable. + static $parser; + if (!isset($parser)) { + $parser_class = MARKDOWN_PARSER_CLASS; + $parser = new $parser_class; + } + + # Transform text using parser. + return $parser->transform($text); +} + + +### WordPress Plugin Interface ### + +/* +Plugin Name: Markdown Extra +Plugin URI: http://www.michelf.com/projects/php-markdown/ +Description: Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More... +Version: 1.2.2 +Author: Michel Fortin +Author URI: http://www.michelf.com/ +*/ + +if (isset($wp_version)) { + # More details about how it works here: + # + + # Post content and excerpts + # - Remove WordPress paragraph generator. + # - Run Markdown on excerpt, then remove all tags. + # - Add paragraph tag around the excerpt, but remove it for the excerpt rss. + if (MARKDOWN_WP_POSTS) { + remove_filter('the_content', 'wpautop'); + remove_filter('the_content_rss', 'wpautop'); + remove_filter('the_excerpt', 'wpautop'); + add_filter('the_content', 'Markdown', 6); + add_filter('the_content_rss', 'Markdown', 6); + add_filter('get_the_excerpt', 'Markdown', 6); + add_filter('get_the_excerpt', 'trim', 7); + add_filter('the_excerpt', 'mdwp_add_p'); + add_filter('the_excerpt_rss', 'mdwp_strip_p'); + + remove_filter('content_save_pre', 'balanceTags', 50); + remove_filter('excerpt_save_pre', 'balanceTags', 50); + add_filter('the_content', 'balanceTags', 50); + add_filter('get_the_excerpt', 'balanceTags', 9); + } + + # Comments + # - Remove WordPress paragraph generator. + # - Remove WordPress auto-link generator. + # - Scramble important tags before passing them to the kses filter. + # - Run Markdown on excerpt then remove paragraph tags. + if (MARKDOWN_WP_COMMENTS) { + remove_filter('comment_text', 'wpautop', 30); + remove_filter('comment_text', 'make_clickable'); + add_filter('pre_comment_content', 'Markdown', 6); + add_filter('pre_comment_content', 'mdwp_hide_tags', 8); + add_filter('pre_comment_content', 'mdwp_show_tags', 12); + add_filter('get_comment_text', 'Markdown', 6); + add_filter('get_comment_excerpt', 'Markdown', 6); + add_filter('get_comment_excerpt', 'mdwp_strip_p', 7); + + global $mdwp_hidden_tags, $mdwp_placeholders; + $mdwp_hidden_tags = explode(' ', + '

     
  • '); + $mdwp_placeholders = explode(' ', str_rot13( + 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '. + 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli')); + } + + function mdwp_add_p($text) { + if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) { + $text = '

    '.$text.'

    '; + $text = preg_replace('{\n{2,}}', "

    \n\n

    ", $text); + } + return $text; + } + + function mdwp_strip_p($t) { return preg_replace('{}i', '', $t); } + + function mdwp_hide_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text); + } + function mdwp_show_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text); + } +} + + +### bBlog Plugin Info ### + +function identify_modifier_markdown() { + return array( + 'name' => 'markdown', + 'type' => 'modifier', + 'nicename' => 'PHP Markdown Extra', + 'description' => 'A text-to-HTML conversion tool for web writers', + 'authors' => 'Michel Fortin and John Gruber', + 'licence' => 'GPL', + 'version' => MARKDOWNEXTRA_VERSION, + 'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...', + ); +} + + +### Smarty Modifier Interface ### + +function smarty_modifier_markdown($text) { + return Markdown($text); +} + + +### Textile Compatibility Mode ### + +# Rename this file to "classTextile.php" and it can replace Textile everywhere. + +if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) { + # Try to include PHP SmartyPants. Should be in the same directory. + @include_once 'smartypants.php'; + # Fake Textile class. It calls Markdown instead. + class Textile { + function TextileThis($text, $lite='', $encode='') { + if ($lite == '' && $encode == '') $text = Markdown($text); + if (function_exists('SmartyPants')) $text = SmartyPants($text); + return $text; + } + # Fake restricted version: restrictions are not supported for now. + function TextileRestricted($text, $lite='', $noimage='') { + return $this->TextileThis($text, $lite); + } + # Workaround to ensure compatibility with TextPattern 4.0.3. + function blockLite($text) { return $text; } + } +} + + + +# +# Markdown Parser Class +# + +class Markdown_Parser { + + # Regex to match balanced [brackets]. + # Needed to insert a maximum bracked depth while converting to PHP. + var $nested_brackets_depth = 6; + var $nested_brackets_re; + + var $nested_url_parenthesis_depth = 4; + var $nested_url_parenthesis_re; + + # Table of hash values for escaped characters: + var $escape_chars = '\`*_{}[]()>#+-.!'; + var $escape_chars_re; + + # Change to ">" for HTML output. + var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX; + var $tab_width = MARKDOWN_TAB_WIDTH; + + # Change to `true` to disallow markup or entities. + var $no_markup = false; + var $no_entities = false; + + # Predefined urls and titles for reference links and images. + var $predef_urls = array(); + var $predef_titles = array(); + + + function Markdown_Parser() { + # + # Constructor function. Initialize appropriate member variables. + # + $this->_initDetab(); + $this->prepareItalicsAndBold(); + + $this->nested_brackets_re = + str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). + str_repeat('\])*', $this->nested_brackets_depth); + + $this->nested_url_parenthesis_re = + str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). + str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); + + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; + + # Sort document, block, and span gamut in ascendent priority order. + asort($this->document_gamut); + asort($this->block_gamut); + asort($this->span_gamut); + } + + + # Internal hashes used during transformation. + var $urls = array(); + var $titles = array(); + var $html_hashes = array(); + + # Status flag to avoid invalid nesting. + var $in_anchor = false; + + + function setup() { + # + # Called before the transformation process starts to setup parser + # states. + # + # Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; + $this->html_hashes = array(); + + $in_anchor = false; + } + + function teardown() { + # + # Called after the transformation process to clear any variable + # which may be taking up memory unnecessarly. + # + $this->urls = array(); + $this->titles = array(); + $this->html_hashes = array(); + } + + + function transform($text) { + # + # Main function. Performs some preprocessing on the input text + # and pass it through the document gamut. + # + $this->setup(); + + # Remove UTF-8 BOM and marker character in input, if present. + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # Standardize line endings: + # DOS to Unix and Mac to Unix + $text = preg_replace('{\r\n?}', "\n", $text); + + # Make sure $text ends with a couple of newlines: + $text .= "\n\n"; + + # Convert all tabs to spaces. + $text = $this->detab($text); + + # Turn block-level HTML blocks into hash entries + $text = $this->hashHTMLBlocks($text); + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ ]*\n+/ . + $text = preg_replace('/^[ ]+$/m', '', $text); + + # Run document gamut methods. + foreach ($this->document_gamut as $method => $priority) { + $text = $this->$method($text); + } + + $this->teardown(); + + return $text . "\n"; + } + + var $document_gamut = array( + # Strip link definitions, store in hashes. + "stripLinkDefinitions" => 20, + + "runBasicBlockGamut" => 30, + ); + + + function stripLinkDefinitions($text) { + # + # Strips link definitions from text, stores the URLs and titles in + # hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + ? # url = $2 + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $3 + [")] + [ ]* + )? # title is optional + (?:\n+|\Z) + }xm', + array(&$this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $this->urls[$link_id] = $matches[2]; + $this->titles[$link_id] =& $matches[3]; + return ''; # String that will replace the block + } + + + function hashHTMLBlocks($text) { + if ($this->no_markup) return $text; + + $less_than_tab = $this->tab_width - 1; + + # Hashify HTML blocks: + # We only want to do this for block-level HTML tags, such as headers, + # lists, and tables. That's because we still want to wrap

    s around + # "paragraphs" that are wrapped in non-block-level tags, such as anchors, + # phrase emphasis, and spans. The list of tags we're looking for is + # hard-coded: + # + # * List "a" is made of tags which can be both inline or block-level. + # These will be treated block-level when the start tag is alone on + # its line, otherwise they're not matched here and will be taken as + # inline later. + # * List "b" is made of tags which are always block-level; + # + $block_tags_a_re = 'ins|del'; + $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. + 'script|noscript|form|fieldset|iframe|math'; + + # Regular expression for the content of a block tag. + $nested_tags_level = 4; + $attr = ' + (?> # optional tag attributes + \s # starts with whitespace + (?> + [^>"/]+ # text outside quotes + | + /+(?!>) # slash not followed by ">" + | + "[^"]*" # text inside double quotes (tolerate ">") + | + \'[^\']*\' # text inside single quotes (tolerate ">") + )* + )? + '; + $content = + str_repeat(' + (?> + [^<]+ # content without tag + | + <\2 # nested opening tag + '.$attr.' # attributes + (?> + /> + | + >', $nested_tags_level). # end of opening tag + '.*?'. # last level nested tag content + str_repeat(' + # closing nested tag + ) + | + <(?!/\2\s*> # other tags with a different name + ) + )*', + $nested_tags_level); + $content2 = str_replace('\2', '\3', $content); + + # First, look for nested blocks, e.g.: + #

    + #
    + # tags for inner block must be indented. + #
    + #
    + # + # The outermost tags must start at the left margin for this to match, and + # the inner nested divs must be indented. + # We need to do this before the next, more liberal match, because the next + # match will start at the first `
    ` and stop at the first `
    `. + $text = preg_replace_callback('{(?> + (?> + (?<=\n\n) # Starting after a blank line + | # or + \A\n? # the beginning of the doc + ) + ( # save in $1 + + # Match from `\n` to `\n`, handling nested tags + # in between. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_b_re.')# start tag = $2 + '.$attr.'> # attributes followed by > and \n + '.$content.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special version for tags of group a. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_a_re.')# start tag = $3 + '.$attr.'>[ ]*\n # attributes followed by > + '.$content2.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special case just for
    . It was easier to make a special + # case than to make the other regex more complicated. + + [ ]{0,'.$less_than_tab.'} + <(hr) # start tag = $2 + '.$attr.' # attributes + /?> # the matching end tag + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # Special case for standalone HTML comments: + + [ ]{0,'.$less_than_tab.'} + (?s: + + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # PHP and ASP-style processor instructions ( + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + ) + )}Sxmi', + array(&$this, '_hashHTMLBlocks_callback'), + $text); + + return $text; + } + function _hashHTMLBlocks_callback($matches) { + $text = $matches[1]; + $key = $this->hashBlock($text); + return "\n\n$key\n\n"; + } + + + function hashPart($text, $boundary = 'X') { + # + # Called whenever a tag must be hashed when a function insert an atomic + # element in the text stream. Passing $text to through this function gives + # a unique text-token which will be reverted back when calling unhash. + # + # The $boundary argument specify what character should be used to surround + # the token. By convension, "B" is used for block elements that needs not + # to be wrapped into paragraph tags at the end, ":" is used for elements + # that are word separators and "X" is used in the general case. + # + # Swap back any tag hash found in $text so we do not have to `unhash` + # multiple times at the end. + $text = $this->unhash($text); + + # Then hash the block. + static $i = 0; + $key = "$boundary\x1A" . ++$i . $boundary; + $this->html_hashes[$key] = $text; + return $key; # String that will replace the tag. + } + + + function hashBlock($text) { + # + # Shortcut function for hashPart with block-level boundaries. + # + return $this->hashPart($text, 'B'); + } + + + var $block_gamut = array( + # + # These are all the transformations that form block-level + # tags like paragraphs, headers, and list items. + # + "doHeaders" => 10, + "doHorizontalRules" => 20, + + "doLists" => 40, + "doCodeBlocks" => 50, + "doBlockQuotes" => 60, + ); + + function runBlockGamut($text) { + # + # Run block gamut tranformations. + # + # We need to escape raw HTML in Markdown source before doing anything + # else. This need to be done for each block, and not only at the + # begining in the Markdown function since hashed blocks can be part of + # list items and could have been indented. Indented blocks would have + # been seen as a code block in a previous pass of hashHTMLBlocks. + $text = $this->hashHTMLBlocks($text); + + return $this->runBasicBlockGamut($text); + } + + function runBasicBlockGamut($text) { + # + # Run block gamut tranformations, without hashing HTML blocks. This is + # useful when HTML blocks are known to be already hashed, like in the first + # whole-document pass. + # + foreach ($this->block_gamut as $method => $priority) { + $text = $this->$method($text); + } + + # Finally form paragraph and restore hashed blocks. + $text = $this->formParagraphs($text); + + return $text; + } + + + function doHorizontalRules($text) { + # Do Horizontal Rules: + return preg_replace( + '{ + ^[ ]{0,3} # Leading space + ([-*_]) # $1: First marker + (?> # Repeated marker group + [ ]{0,2} # Zero, one, or two spaces. + \1 # Marker character + ){2,} # Group repeated at least twice + [ ]* # Tailing spaces + $ # End of line. + }mx', + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text); + } + + + var $span_gamut = array( + # + # These are all the transformations that occur *within* block-level + # tags like paragraphs, headers, and list items. + # + # Process character escapes, code spans, and inline HTML + # in one shot. + "parseSpan" => -30, + + # Process anchor and image tags. Images must come first, + # because ![foo][f] looks like an anchor. + "doImages" => 10, + "doAnchors" => 20, + + # Make links out of things like `` + # Must come after doAnchors, because you can use < and > + # delimiters in inline links like [this](). + "doAutoLinks" => 30, + "encodeAmpsAndAngles" => 40, + + "doItalicsAndBold" => 50, + "doHardBreaks" => 60, + ); + + function runSpanGamut($text) { + # + # Run span gamut tranformations. + # + foreach ($this->span_gamut as $method => $priority) { + $text = $this->$method($text); + } + + return $text; + } + + + function doHardBreaks($text) { + # Do hard breaks: + return preg_replace_callback('/ {2,}\n/', + array(&$this, '_doHardBreaks_callback'), $text); + } + function _doHardBreaks_callback($matches) { + return $this->hashPart("empty_element_suffix\n"); + } + + + function doAnchors($text) { + # + # Turn Markdown link shortcuts into XHTML tags. + # + if ($this->in_anchor) return $text; + $this->in_anchor = true; + + # + # First, handle reference-style links: [link text] [id] + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array(&$this, '_doAnchors_reference_callback'), $text); + + # + # Next, inline-style links: [link text](url "optional title") + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + \( # literal paren + [ ]* + (?: + <(\S*)> # href = $3 + | + ('.$this->nested_url_parenthesis_re.') # href = $4 + ) + [ ]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ ]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + ) + }xs', + array(&$this, '_DoAnchors_inline_callback'), $text); + + # + # Last, handle reference-style shortcuts: [link text] + # These must come last in case you've also got [link test][1] + # or [link test](/foo) + # +// $text = preg_replace_callback('{ +// ( # wrap whole match in $1 +// \[ +// ([^\[\]]+) # link text = $2; can\'t contain [ or ] +// \] +// ) +// }xs', +// array(&$this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + # for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + # lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } + else { + $result = $whole_match; + } + return $result; + } + function _doAnchors_inline_callback($matches) { + $whole_match = $matches[1]; + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $url = $this->encodeAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + + function doImages($text) { + # + # Turn Markdown image shortcuts into tags. + # + # + # First, handle reference-style labeled images: ![alt text][id] + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array(&$this, '_doImages_reference_callback'), $text); + + # + # Next, handle inline images: ![alt text](url "optional title") + # Don't forget: encode * and _ + # + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ ]* + (?: + <(\S*)> # src url = $3 + | + ('.$this->nested_url_parenthesis_re.') # src url = $4 + ) + [ ]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ ]* + )? # title is optional + \) + ) + }xs', + array(&$this, '_doImages_inline_callback'), $text); + + return $text; + } + function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); # for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } + else { + # If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; # $title already quoted + } + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + + function doHeaders($text) { + # Setext-style headers: + # Header 1 + # ======== + # + # Header 2 + # -------- + # + $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', + array(&$this, '_doHeaders_callback_setext'), $text); + + # atx-style headers: + # # Header 1 + # ## Header 2 + # ## Header 2 with closing hashes ## + # ... + # ###### Header 6 + # + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + \n+ + }xm', + array(&$this, '_doHeaders_callback_atx'), $text); + + return $text; + } + function _doHeaders_callback_setext($matches) { + # Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) + return $matches[0]; + + $level = $matches[2]{0} == '=' ? 1 : 2; + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + + function doLists($text) { + # + # Form HTML ordered (numbered) and unordered (bulleted) lists. + # + $less_than_tab = $this->tab_width - 1; + + # Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + + $markers_relist = array($marker_ul_re, $marker_ol_re); + + foreach ($markers_relist as $marker_re) { + # Re-usable pattern to match any entirel ul or ol list: + $whole_list_re = ' + ( # $1 = whole list + ( # $2 + [ ]{0,'.$less_than_tab.'} + ('.$marker_re.') # $3 = first list item marker + [ ]+ + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another list item marker + [ ]* + '.$marker_re.'[ ]+ + ) + ) + ) + '; // mx + + # We use a different prefix before nested lists than top-level lists. + # See extended comment in _ProcessListItems(). + + if ($this->list_level) { + $text = preg_replace_callback('{ + ^ + '.$whole_list_re.' + }mx', + array(&$this, '_doLists_callback'), $text); + } + else { + $text = preg_replace_callback('{ + (?:(?<=\n)\n|\A\n?) # Must eat the newline + '.$whole_list_re.' + }mx', + array(&$this, '_doLists_callback'), $text); + } + } + + return $text; + } + function _doLists_callback($matches) { + # Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + + $list = $matches[1]; + $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol"; + + $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); + + $list .= "\n"; + $result = $this->processListItems($list, $marker_any_re); + + $result = $this->hashBlock("<$list_type>\n" . $result . ""); + return "\n". $result ."\n\n"; + } + + var $list_level = 0; + + function processListItems($list_str, $marker_any_re) { + # + # Process the contents of a single ordered or unordered list, splitting it + # into individual list items. + # + # The $this->list_level global keeps track of when we're inside a list. + # Each time we enter a list, we increment it; when we leave a list, + # we decrement. If it's zero, we're not in a list anymore. + # + # We do this because when we're not inside a list, we want to treat + # something like this: + # + # I recommend upgrading to version + # 8. Oops, now this line is treated + # as a sub-list. + # + # As a single paragraph, despite the fact that the second line starts + # with a digit-period-space sequence. + # + # Whereas when we're inside a list (or sub-list), that line will be + # treated as the start of a sub-list. What a kludge, huh? This is + # an aspect of Markdown's syntax that's hard to parse perfectly + # without resorting to mind-reading. Perhaps the solution is to + # change the syntax rules such that sub-lists must start with a + # starting cardinal number; e.g. "1." or "a.". + + $this->list_level++; + + # trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + $list_str = preg_replace_callback('{ + (\n)? # leading line = $1 + (^[ ]*) # leading whitespace = $2 + ('.$marker_any_re.' # list marker and space = $3 + (?:[ ]+|(?=\n)) # space only required if item is not empty + ) + ((?s:.*?)) # list item text = $4 + (?:(\n+(?=\n))|\n) # tailing blank line = $5 + (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) + }xm', + array(&$this, '_processListItems_callback'), $list_str); + + $this->list_level--; + return $list_str; + } + function _processListItems_callback($matches) { + $item = $matches[4]; + $leading_line =& $matches[1]; + $leading_space =& $matches[2]; + $marker_space = $matches[3]; + $tailing_blank_line =& $matches[5]; + + if ($leading_line || $tailing_blank_line || + preg_match('/\n{2,}/', $item)) + { + # Replace marker with the appropriate whitespace indentation + $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; + $item = $this->runBlockGamut($this->outdent($item)."\n"); + } + else { + # Recursion for sub-lists: + $item = $this->doLists($this->outdent($item)); + $item = preg_replace('/\n+$/', '', $item); + $item = $this->runSpanGamut($item); + } + + return "
  • " . $item . "
  • \n"; + } + + + function doCodeBlocks($text) { + # + # Process Markdown `
    ` blocks.
    +	#
    +		$text = preg_replace_callback('{
    +				(?:\n\n|\A\n?)
    +				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    +				  (?>
    +					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    +					.*\n+
    +				  )+
    +				)
    +				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    +			}xm',
    +			array(&$this, '_doCodeBlocks_callback'), $text);
    +
    +		return $text;
    +	}
    +	function _doCodeBlocks_callback($matches) {
    +		$codeblock = $matches[1];
    +
    +		$codeblock = $this->outdent($codeblock);
    +		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    +
    +		# trim leading newlines and trailing newlines
    +		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    +
    +		$codeblock = "
    $codeblock\n
    "; + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + + + function makeCodeSpan($code) { + # + # Create a code span markup for $code. Called from handleSpanToken. + # + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + return $this->hashPart("$code"); + } + + + var $em_relist = array( + '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(?em_relist as $em => $em_re) { + foreach ($this->strong_relist as $strong => $strong_re) { + # Construct list of allowed token expressions. + $token_relist = array(); + if (isset($this->em_strong_relist["$em$strong"])) { + $token_relist[] = $this->em_strong_relist["$em$strong"]; + } + $token_relist[] = $em_re; + $token_relist[] = $strong_re; + + # Construct master expression from list. + $token_re = '{('. implode('|', $token_relist) .')}'; + $this->em_strong_prepared_relist["$em$strong"] = $token_re; + } + } + } + + function doItalicsAndBold($text) { + $token_stack = array(''); + $text_stack = array(''); + $em = ''; + $strong = ''; + $tree_char_em = false; + + while (1) { + # + # Get prepared regular expression for seraching emphasis tokens + # in current context. + # + $token_re = $this->em_strong_prepared_relist["$em$strong"]; + + # + # Each loop iteration seach for the next emphasis token. + # Each token is then passed to handleSpanToken. + # + $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + $text_stack[0] .= $parts[0]; + $token =& $parts[1]; + $text =& $parts[2]; + + if (empty($token)) { + # Reached end of text span: empty stack without emitting. + # any more emphasis. + while ($token_stack[0]) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + break; + } + + $token_len = strlen($token); + if ($tree_char_em) { + # Reached closing marker while inside a three-char emphasis. + if ($token_len == 3) { + # Three-char closing marker, close em and strong. + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + $strong = ''; + } else { + # Other closing marker: close one em or strong and + # change current token state to match the other + $token_stack[0] = str_repeat($token{0}, 3-$token_len); + $tag = $token_len == 2 ? "strong" : "em"; + $span = $text_stack[0]; + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] = $this->hashPart($span); + $$tag = ''; # $$tag stands for $em or $strong + } + $tree_char_em = false; + } else if ($token_len == 3) { + if ($em) { + # Reached closing marker for both em and strong. + # Closing strong marker: + for ($i = 0; $i < 2; ++$i) { + $shifted_token = array_shift($token_stack); + $tag = strlen($shifted_token) == 2 ? "strong" : "em"; + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] .= $this->hashPart($span); + $$tag = ''; # $$tag stands for $em or $strong + } + } else { + # Reached opening three-char emphasis marker. Push on token + # stack; will be handled by the special condition above. + $em = $token{0}; + $strong = "$em$em"; + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $tree_char_em = true; + } + } else if ($token_len == 2) { + if ($strong) { + # Unwind any dangling emphasis marker: + if (strlen($token_stack[0]) == 1) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + # Closing strong marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $strong = ''; + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $strong = $token; + } + } else { + # Here $token_len == 1 + if ($em) { + if (strlen($token_stack[0]) == 1) { + # Closing emphasis marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + } else { + $text_stack[0] .= $token; + } + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $em = $token; + } + } + } + return $text_stack[0]; + } + + + function doBlockQuotes($text) { + $text = preg_replace_callback('/ + ( # Wrap whole match in $1 + (?> + ^[ ]*>[ ]? # ">" at the start of a line + .+\n # rest of the first line + (.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + /xm', + array(&$this, '_doBlockQuotes_callback'), $text); + + return $text; + } + function _doBlockQuotes_callback($matches) { + $bq = $matches[1]; + # trim one level of quoting - trim whitespace-only lines + $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); + $bq = $this->runBlockGamut($bq); # recurse + + $bq = preg_replace('/^/m', " ", $bq); + # These leading spaces cause problem with
     content, 
    +		# so we need to fix that:
    +		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', + array(&$this, '_DoBlockQuotes_callback2'), $bq); + + return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; + } + function _doBlockQuotes_callback2($matches) { + $pre = $matches[1]; + $pre = preg_replace('/^ /m', '', $pre); + return $pre; + } + + + function formParagraphs($text) { + # + # Params: + # $text - string to process with html

    tags + # + # Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + # + # Wrap

    tags and unhashify HTML blocks + # + foreach ($grafs as $key => $value) { + if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { + # Is a paragraph. + $value = $this->runSpanGamut($value); + $value = preg_replace('/^([ ]*)/', "

    ", $value); + $value .= "

    "; + $grafs[$key] = $this->unhash($value); + } + else { + # Is a block. + # Modify elements of @grafs in-place... + $graf = $value; + $block = $this->html_hashes[$graf]; + $graf = $block; +// if (preg_match('{ +// \A +// ( # $1 =
    tag +//
    ]* +// \b +// markdown\s*=\s* ([\'"]) # $2 = attr quote char +// 1 +// \2 +// [^>]* +// > +// ) +// ( # $3 = contents +// .* +// ) +// (
    ) # $4 = closing tag +// \z +// }xs', $block, $matches)) +// { +// list(, $div_open, , $div_content, $div_close) = $matches; +// +// # We can't call Markdown(), because that resets the hash; +// # that initialization code should be pulled into its own sub, though. +// $div_content = $this->hashHTMLBlocks($div_content); +// +// # Run document gamut methods on the content. +// foreach ($this->document_gamut as $method => $priority) { +// $div_content = $this->$method($div_content); +// } +// +// $div_open = preg_replace( +// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); +// +// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; +// } + $grafs[$key] = $graf; + } + } + + return implode("\n\n", $grafs); + } + + + function encodeAttribute($text) { + # + # Encode text for a double-quoted HTML attribute. This function + # is *not* suitable for attributes enclosed in single quotes. + # + $text = $this->encodeAmpsAndAngles($text); + $text = str_replace('"', '"', $text); + return $text; + } + + + function encodeAmpsAndAngles($text) { + # + # Smart processing for ampersands and angle brackets that need to + # be encoded. Valid character entities are left alone unless the + # no-entities mode is set. + # + if ($this->no_entities) { + $text = str_replace('&', '&', $text); + } else { + # Ampersand-encoding based entirely on Nat Irons's Amputator + # MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + '&', $text);; + } + # Encode remaining <'s + $text = str_replace('<', '<', $text); + + return $text; + } + + + function doAutoLinks($text) { + $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', + array(&$this, '_doAutoLinks_url_callback'), $text); + + # Email addresses: + $text = preg_replace_callback('{ + < + (?:mailto:)? + ( + [-.\w\x80-\xFF]+ + \@ + [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ + ) + > + }xi', + array(&$this, '_doAutoLinks_email_callback'), $text); + + return $text; + } + function _doAutoLinks_url_callback($matches) { + $url = $this->encodeAttribute($matches[1]); + $link = "$url"; + return $this->hashPart($link); + } + function _doAutoLinks_email_callback($matches) { + $address = $matches[1]; + $link = $this->encodeEmailAddress($address); + return $this->hashPart($link); + } + + + function encodeEmailAddress($addr) { + # + # Input: an email address, e.g. "foo@example.com" + # + # Output: the email address as a mailto link, with each character + # of the address encoded as either a decimal or hex entity, in + # the hopes of foiling most address harvesting spam bots. E.g.: + # + #

    foo@exampl + # e.com

    + # + # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + # With some optimizations by Milian Wolff. + # + $addr = "mailto:" . $addr; + $chars = preg_split('/(? $char) { + $ord = ord($char); + # Ignore non-ascii chars. + if ($ord < 128) { + $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. + # roughly 10% raw, 45% hex, 45% dec + # '@' *must* be encoded. I insist. + if ($r > 90 && $char != '@') /* do nothing */; + else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; + else $chars[$key] = '&#'.$ord.';'; + } + } + + $addr = implode('', $chars); + $text = implode('', array_slice($chars, 7)); # text without `mailto:` + $addr = "$text"; + + return $addr; + } + + + function parseSpan($str) { + # + # Take the string $str and parse it into tokens, hashing embeded HTML, + # escaped characters and handling code spans. + # + $output = ''; + + $span_re = '{ + ( + \\\\'.$this->escape_chars_re.' + | + (?no_markup ? '' : ' + | + # comment + | + <\?.*?\?> | <%.*?%> # processing instruction + | + <[/!$]?[-a-zA-Z0-9:]+ # regular tags + (?> + \s + (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* + )? + > + ').' + ) + }xs'; + + while (1) { + # + # Each loop iteration seach for either the next tag, the next + # openning code span marker, or the next escaped character. + # Each token is then passed to handleSpanToken. + # + $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); + + # Create token from text preceding tag. + if ($parts[0] != "") { + $output .= $parts[0]; + } + + # Check if we reach the end. + if (isset($parts[1])) { + $output .= $this->handleSpanToken($parts[1], $parts[2]); + $str = $parts[2]; + } + else { + break; + } + } + + return $output; + } + + + function handleSpanToken($token, &$str) { + # + # Handle $token provided by parseSpan by determining its nature and + # returning the corresponding value that should replace it. + # + switch ($token{0}) { + case "\\": + return $this->hashPart("&#". ord($token{1}). ";"); + case "`": + # Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + $str, $matches)) + { + $str = $matches[2]; + $codespan = $this->makeCodeSpan($matches[1]); + return $this->hashPart($codespan); + } + return $token; // return as text since no ending marker found. + default: + return $this->hashPart($token); + } + } + + + function outdent($text) { + # + # Remove one level of line-leading tabs or spaces + # + return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); + } + + + # String length function for detab. `_initDetab` will create a function to + # hanlde UTF-8 if the default function does not exist. + var $utf8_strlen = 'mb_strlen'; + + function detab($text) { + # + # Replace tabs with the appropriate amount of space. + # + # For each line we separate the line in blocks delemited by + # tab characters. Then we reconstruct every line by adding the + # appropriate number of space between each blocks. + + $text = preg_replace_callback('/^.*\t.*$/m', + array(&$this, '_detab_callback'), $text); + + return $text; + } + function _detab_callback($matches) { + $line = $matches[0]; + $strlen = $this->utf8_strlen; # strlen function for UTF-8. + + # Split in blocks. + $blocks = explode("\t", $line); + # Add each blocks to the line. + $line = $blocks[0]; + unset($blocks[0]); # Do not add first block twice. + foreach ($blocks as $block) { + # Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - + $strlen($line, 'UTF-8') % $this->tab_width; + $line .= str_repeat(" ", $amount) . $block; + } + return $line; + } + function _initDetab() { + # + # Check for the availability of the function in the `utf8_strlen` property + # (initially `mb_strlen`). If the function is not available, create a + # function that will loosely count the number of UTF-8 characters with a + # regular expression. + # + if (function_exists($this->utf8_strlen)) return; + $this->utf8_strlen = create_function('$text', 'return preg_match_all( + "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", + $text, $m);'); + } + + + function unhash($text) { + # + # Swap back in all the tags hashed by _HashHTMLBlocks. + # + return preg_replace_callback('/(.)\x1A[0-9]+\1/', + array(&$this, '_unhash_callback'), $text); + } + function _unhash_callback($matches) { + return $this->html_hashes[$matches[0]]; + } + +} + + +# +# Markdown Extra Parser Class +# + +class MarkdownExtra_Parser extends Markdown_Parser { + + # Prefix for footnote ids. + var $fn_id_prefix = ""; + + # Optional title attribute for footnote links and backlinks. + var $fn_link_title = MARKDOWN_FN_LINK_TITLE; + var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE; + + # Optional class attribute for footnote links and backlinks. + var $fn_link_class = MARKDOWN_FN_LINK_CLASS; + var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS; + + # Predefined abbreviations. + var $predef_abbr = array(); + + + function MarkdownExtra_Parser() { + # + # Constructor function. Initialize the parser object. + # + # Add extra escapable characters before parent constructor + # initialize the table. + $this->escape_chars .= ':|'; + + # Insert extra document, block, and span transformations. + # Parent constructor will do the sorting. + $this->document_gamut += array( + "doFencedCodeBlocks" => 5, + "stripFootnotes" => 15, + "stripAbbreviations" => 25, + "appendFootnotes" => 50, + ); + $this->block_gamut += array( + "doFencedCodeBlocks" => 5, + "doTables" => 15, + "doDefLists" => 45, + ); + $this->span_gamut += array( + "doFootnotes" => 5, + "doAbbreviations" => 70, + ); + + parent::Markdown_Parser(); + } + + + # Extra variables used during extra transformations. + var $footnotes = array(); + var $footnotes_ordered = array(); + var $abbr_desciptions = array(); + var $abbr_word_re = ''; + + # Give the current footnote number. + var $footnote_counter = 1; + + + function setup() { + # + # Setting up Extra-specific variables. + # + parent::setup(); + + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + $this->footnote_counter = 1; + + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + } + } + + function teardown() { + # + # Clearing Extra-specific variables. + # + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + + parent::teardown(); + } + + + ### HTML Block Parser ### + + # Tags that are always treated as block tags: + var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; + + # Tags treated as block tags only if the opening tag is alone on it's line: + var $context_block_tags_re = 'script|noscript|math|ins|del'; + + # Tags where markdown="1" default to span mode: + var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; + + # Tags which must not have their contents modified, no matter where + # they appear: + var $clean_tags_re = 'script|math'; + + # Tags that do not need to be closed. + var $auto_close_tags_re = 'hr|img'; + + + function hashHTMLBlocks($text) { + # + # Hashify HTML Blocks and "clean tags". + # + # We only want to do this for block-level HTML tags, such as headers, + # lists, and tables. That's because we still want to wrap

    s around + # "paragraphs" that are wrapped in non-block-level tags, such as anchors, + # phrase emphasis, and spans. The list of tags we're looking for is + # hard-coded. + # + # This works by calling _HashHTMLBlocks_InMarkdown, which then calls + # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back + # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + # These two functions are calling each other. It's recursive! + # + # + # Call the HTML-in-Markdown hasher. + # + list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); + + return $text; + } + function _hashHTMLBlocks_inMarkdown($text, $indent = 0, + $enclosing_tag_re = '', $span = false) + { + # + # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + # + # * $indent is the number of space to be ignored when checking for code + # blocks. This is important because if we don't take the indent into + # account, something like this (which looks right) won't work as expected: + # + #

    + #
    + # Hello World. <-- Is this a Markdown code block or text? + #
    <-- Is this a Markdown code block or a real tag? + #
    + # + # If you don't like this, just don't indent the tag on which + # you apply the markdown="1" attribute. + # + # * If $enclosing_tag_re is not empty, stops at the first unmatched closing + # tag with that name. Nested tags supported. + # + # * If $span is true, text inside must treated as span. So any double + # newline will be replaced by a single newline so that it does not create + # paragraphs. + # + # Returns an array of that form: ( processed text , remaining text ) + # + if ($text === '') return array('', ''); + + # Regex to check for the presense of newlines around a block tag. + $newline_before_re = '/(?:^\n?|\n\n)*$/'; + $newline_after_re = + '{ + ^ # Start of text following the tag. + (?>[ ]*)? # Optional comment. + [ ]*\n # Must be followed by newline. + }xs'; + + # Regex to match any tag. + $block_tag_re = + '{ + ( # $2: Capture hole tag. + # Tag name. + '.$this->block_tags_re.' | + '.$this->context_block_tags_re.' | + '.$this->clean_tags_re.' | + (?!\s)'.$enclosing_tag_re.' + ) + (?: + (?=[\s"\'/]) # Allowed characters after tag name. + (?> + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + | + # Code span marker + `+ + '. ( !$span ? ' # If not in span. + | + # Indented code block + (?> ^[ ]*\n? | \n[ ]*\n ) + [ ]{'.($indent+4).'}[^\n]* \n + (?> + (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n + )* + | + # Fenced code block marker + (?> ^ | \n ) + [ ]{'.($indent).'}~~~+[ ]*\n + ' : '' ). ' # End (if not is span). + ) + }xs'; + + + $depth = 0; # Current depth inside the tag tree. + $parsed = ""; # Parsed text that will be returned. + + # + # Loop through every tag until we find the closing tag of the parent + # or loop until reaching the end of text if no parent tag specified. + # + do { + # + # Split the text using the first $tag_match pattern found. + # Text before pattern will be first in the array, text after + # pattern will be at the end, and between will be any catches made + # by the pattern. + # + $parts = preg_split($block_tag_re, $text, 2, + PREG_SPLIT_DELIM_CAPTURE); + + # If in Markdown span mode, add a empty-string span-level hash + # after each newline to prevent triggering any block element. + if ($span) { + $void = $this->hashPart("", ':'); + $newline = "$void\n"; + $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; + } + + $parsed .= $parts[0]; # Text before current tag. + + # If end of $text has been reached. Stop loop. + if (count($parts) < 3) { + $text = ""; + break; + } + + $tag = $parts[1]; # Tag to handle. + $text = $parts[2]; # Remaining text after current tag. + $tag_re = preg_quote($tag); # For use in a regular expression. + + # + # Check for: Code span marker + # + if ($tag{0} == "`") { + # Find corresponding end marker. + $tag_re = preg_quote($tag); + if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)+?'.$tag_re.' *\n}', $text, + $matches)) + { + # End marker found: pass text unchanged until marker. + $parsed .= $tag . $matches[0]; + $text = substr($text, strlen($matches[0])); + } + else { + # No end marker: just skip it. + $parsed .= $tag; + } + } + } + # + # Check for: Opening Block level tag or + # Opening Context Block tag (like ins and del) + # used as a block tag (tag is alone on it's line). + # + else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) || + ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && + preg_match($newline_before_re, $parsed) && + preg_match($newline_after_re, $text) ) + ) + { + # Need to parse tag and following text using the HTML parser. + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); + + # Make sure it stays outside of any paragraph by adding newlines. + $parsed .= "\n\n$block_text\n\n"; + } + # + # Check for: Clean tag (like script, math) + # HTML Comments, processing instructions. + # + else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + # Need to parse tag and following text using the HTML parser. + # (don't check for markdown attribute) + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); + + $parsed .= $block_text; + } + # + # Check for: Tag with same name as enclosing tag. + # + else if ($enclosing_tag_re !== '' && + # Same name as enclosing tag. + preg_match('{^= 0); + + return array($parsed, $text); + } + function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { + # + # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + # + # * Calls $hash_method to convert any blocks. + # * Stops when the first opening tag closes. + # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + # (it is not inside clean tags) + # + # Returns an array of that form: ( processed text , remaining text ) + # + if ($text === '') return array('', ''); + + # Regex to match `markdown` attribute inside of a tag. + $markdown_attr_re = ' + { + \s* # Eat whitespace before the `markdown` attribute + markdown + \s*=\s* + (?> + (["\']) # $1: quote delimiter + (.*?) # $2: attribute value + \1 # matching delimiter + | + ([^\s>]*) # $3: unquoted attribute value + ) + () # $4: make $3 always defined (avoid warnings) + }xs'; + + # Regex to match any tag. + $tag_re = '{ + ( # $2: Capture hole tag. + + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ) + }xs'; + + $original_text = $text; # Save original text in case of faliure. + + $depth = 0; # Current depth inside the tag tree. + $block_text = ""; # Temporary text holder for current text. + $parsed = ""; # Parsed text that will be returned. + + # + # Get the name of the starting tag. + # (This pattern makes $base_tag_name_re safe without quoting.) + # + if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) + $base_tag_name_re = $matches[1]; + + # + # Loop through every tag until we find the corresponding closing tag. + # + do { + # + # Split the text using the first $tag_match pattern found. + # Text before pattern will be first in the array, text after + # pattern will be at the end, and between will be any catches made + # by the pattern. + # + $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (count($parts) < 3) { + # + # End of $text reached with unbalenced tag(s). + # In that case, we return original text unchanged and pass the + # first character as filtered to prevent an infinite loop in the + # parent function. + # + return array($original_text{0}, substr($original_text, 1)); + } + + $block_text .= $parts[0]; # Text before current tag. + $tag = $parts[1]; # Tag to handle. + $text = $parts[2]; # Remaining text after current tag. + + # + # Check for: Auto-close tag (like
    ) + # Comments and Processing Instructions. + # + if (preg_match('{^auto_close_tags_re.')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + # Just add the tag to the block as if it was text. + $block_text .= $tag; + } + else { + # + # Increase/decrease nested tag count. Only do so if + # the tag's name match base tag's. + # + if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; + $span_mode = $this->mode == 'span' || $this->mode != 'block' && + preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); + + # Calculate indent before tag. + if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { + $strlen = $this->utf8_strlen; + $indent = $strlen($matches[1], 'UTF-8'); + } else { + $indent = 0; + } + + # End preceding block with this tag. + $block_text .= $tag; + $parsed .= $this->$hash_method($block_text); + + # Get enclosing tag name for the ParseMarkdown function. + # (This pattern makes $tag_name_re safe without quoting.) + preg_match('/^<([\w:$]*)\b/', $tag, $matches); + $tag_name_re = $matches[1]; + + # Parse the content using the HTML-in-Markdown parser. + list ($block_text, $text) + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + $tag_name_re, $span_mode); + + # Outdent markdown text. + if ($indent > 0) { + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text); + } + + # Append tag content to parsed text. + if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; + else $parsed .= "$block_text"; + + # Start over a new block. + $block_text = ""; + } + else $block_text .= $tag; + } + + } while ($depth > 0); + + # + # Hash last block text that wasn't processed inside the loop. + # + $parsed .= $this->$hash_method($block_text); + + return array($parsed, $text); + } + + + function hashClean($text) { + # + # Called whenever a tag must be hashed when a function insert a "clean" tag + # in $text, it pass through this function and is automaticaly escaped, + # blocking invalid nested overlap. + # + return $this->hashPart($text, 'C'); + } + + + function doHeaders($text) { + # + # Redefined to add id attribute support. + # + # Setext-style headers: + # Header 1 {#header1} + # ======== + # + # Header 2 {#header2} + # -------- + # + $text = preg_replace_callback( + '{ + (^.+?) # $1: Header text + (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute + [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer + }mx', + array(&$this, '_doHeaders_callback_setext'), $text); + + # atx-style headers: + # # Header 1 {#header1} + # ## Header 2 {#header2} + # ## Header 2 with closing hashes ## {#header3} + # ... + # ###### Header 6 {#header2} + # + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute + [ ]* + \n+ + }xm', + array(&$this, '_doHeaders_callback_atx'), $text); + + return $text; + } + function _doHeaders_attr($attr) { + if (empty($attr)) return ""; + return " id=\"$attr\""; + } + function _doHeaders_callback_setext($matches) { + if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) + return $matches[0]; + $level = $matches[3]{0} == '=' ? 1 : 2; + $attr = $this->_doHeaders_attr($id =& $matches[2]); + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + $attr = $this->_doHeaders_attr($id =& $matches[3]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + + function doTables($text) { + # + # Form HTML tables. + # + $less_than_tab = $this->tab_width - 1; + # + # Find tables with leading pipe. + # + # | Header 1 | Header 2 + # | -------- | -------- + # | Cell 1 | Cell 2 + # | Cell 3 | Cell 4 + # + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+) \n # $1: Header row (at least one pipe) + + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + [ ]* # Allowed whitespace. + [|] .* \n # Row content. + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array(&$this, '_doTable_leadingPipe_callback'), $text); + + # + # Find tables without leading pipe. + # + # Header 1 | Header 2 + # -------- | -------- + # Cell 1 | Cell 2 + # Cell 3 | Cell 4 + # + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + (\S.*[|].*) \n # $1: Header row (at least one pipe) + + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + .* [|] .* \n # Row content + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array(&$this, '_DoTable_callback'), $text); + + return $text; + } + function _doTable_leadingPipe_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + # Remove leading pipe for each row. + $content = preg_replace('/^ *[|]/m', '', $content); + + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + } + function _doTable_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + # Remove any tailing pipes for each line. + $head = preg_replace('/[|] *$/m', '', $head); + $underline = preg_replace('/[|] *$/m', '', $underline); + $content = preg_replace('/[|] *$/m', '', $content); + + # Reading alignement from header underline. + $separators = preg_split('/ *[|] */', $underline); + foreach ($separators as $n => $s) { + if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"'; + else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"'; + else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"'; + else $attr[$n] = ''; + } + + # Parsing span elements, including code spans, character escapes, + # and inline HTML tags, so that pipes inside those gets ignored. + $head = $this->parseSpan($head); + $headers = preg_split('/ *[|] */', $head); + $col_count = count($headers); + + # Write column headers. + $text = "
    \n"; + $text .= "\n"; + $text .= "\n"; + foreach ($headers as $n => $header) + $text .= " ".$this->runSpanGamut(trim($header))."\n"; + $text .= "\n"; + $text .= "\n"; + + # Split content by row. + $rows = explode("\n", trim($content, "\n")); + + $text .= "\n"; + foreach ($rows as $row) { + # Parsing span elements, including code spans, character escapes, + # and inline HTML tags, so that pipes inside those gets ignored. + $row = $this->parseSpan($row); + + # Split row by cell. + $row_cells = preg_split('/ *[|] */', $row, $col_count); + $row_cells = array_pad($row_cells, $col_count, ''); + + $text .= "\n"; + foreach ($row_cells as $n => $cell) + $text .= " ".$this->runSpanGamut(trim($cell))."\n"; + $text .= "\n"; + } + $text .= "\n"; + $text .= "
    "; + + return $this->hashBlock($text) . "\n"; + } + + + function doDefLists($text) { + # + # Form HTML definition lists. + # + $less_than_tab = $this->tab_width - 1; + + # Re-usable pattern to match any entire dl list: + $whole_list_re = '(?> + ( # $1 = whole list + ( # $2 + [ ]{0,'.$less_than_tab.'} + ((?>.*\S.*\n)+) # $3 = defined term + \n? + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another term + [ ]{0,'.$less_than_tab.'} + (?: \S.*\n )+? # defined term + \n? + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + (?! # Negative lookahead for another definition + [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + ) + ) + ) + )'; // mx + + $text = preg_replace_callback('{ + (?>\A\n?|(?<=\n\n)) + '.$whole_list_re.' + }mx', + array(&$this, '_doDefLists_callback'), $text); + + return $text; + } + function _doDefLists_callback($matches) { + # Re-usable patterns to match list item bullets and number markers: + $list = $matches[1]; + + # Turn double returns into triple returns, so that we can make a + # paragraph for the last item in a list, if necessary: + $result = trim($this->processDefListItems($list)); + $result = "
    \n" . $result . "\n
    "; + return $this->hashBlock($result) . "\n\n"; + } + + + function processDefListItems($list_str) { + # + # Process the contents of a single definition list, splitting it + # into individual term and definition list items. + # + $less_than_tab = $this->tab_width - 1; + + # trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + # Process definition terms. + $list_str = preg_replace_callback('{ + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,'.$less_than_tab.'} # leading whitespace + (?![:][ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. + }xm', + array(&$this, '_processDefListItems_callback_dt'), $list_str); + + # Process actual definitions. + $list_str = preg_replace_callback('{ + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,'.$less_than_tab.'} # whitespace before colon + [:][ ]+ # definition mark (colon) + ) + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,'.$less_than_tab.'} [:][ ] | +
    | \z + ) + ) + }xm', + array(&$this, '_processDefListItems_callback_dd'), $list_str); + + return $list_str; + } + function _processDefListItems_callback_dt($matches) { + $terms = explode("\n", trim($matches[1])); + $text = ''; + foreach ($terms as $term) { + $term = $this->runSpanGamut(trim($term)); + $text .= "\n
    " . $term . "
    "; + } + return $text . "\n"; + } + function _processDefListItems_callback_dd($matches) { + $leading_line = $matches[1]; + $marker_space = $matches[2]; + $def = $matches[3]; + + if ($leading_line || preg_match('/\n{2,}/', $def)) { + # Replace marker with the appropriate whitespace indentation + $def = str_repeat(' ', strlen($marker_space)) . $def; + $def = $this->runBlockGamut($this->outdent($def . "\n\n")); + $def = "\n". $def ."\n"; + } + else { + $def = rtrim($def); + $def = $this->runSpanGamut($this->outdent($def)); + } + + return "\n
    " . $def . "
    \n"; + } + + + function doFencedCodeBlocks($text) { + # + # Adding the fenced code block syntax to regular Markdown: + # + # ~~~ + # Code block + # ~~~ + # + $less_than_tab = $this->tab_width; + + $text = preg_replace_callback('{ + (?:\n|\A) + # 1: Opening marker + ( + ~{3,} # Marker: three tilde or more. + ) + [ ]* \n # Whitespace and newline following marker. + + # 2: Content + ( + (?> + (?!\1 [ ]* \n) # Not a closing marker. + .*\n+ + )+ + ) + + # Closing marker. + \1 [ ]* \n + }xm', + array(&$this, '_doFencedCodeBlocks_callback'), $text); + + return $text; + } + function _doFencedCodeBlocks_callback($matches) { + $codeblock = $matches[2]; + $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); + $codeblock = preg_replace_callback('/^\n+/', + array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); + $codeblock = "
    $codeblock
    "; + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + function _doFencedCodeBlocks_newlines($matches) { + return str_repeat("empty_element_suffix", + strlen($matches[0])); + } + + + # + # Redefining emphasis markers so that emphasis by underscore does not + # work in the middle of a word. + # + var $em_relist = array( + '' => '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? '(?:(? '(?<=\S)(? '(?<=\S)(? tags + # + # Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + # + # Wrap

    tags and unhashify HTML blocks + # + foreach ($grafs as $key => $value) { + $value = trim($this->runSpanGamut($value)); + + # Check if this should be enclosed in a paragraph. + # Clean tag hashes & block tag hashes are left alone. + $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + + if ($is_p) { + $value = "

    $value

    "; + } + $grafs[$key] = $value; + } + + # Join grafs in one text, then unhash HTML tags. + $text = implode("\n\n", $grafs); + + # Finish by removing any tag hashes still present in $text. + $text = $this->unhash($text); + + return $text; + } + + + ### Footnotes + + function stripFootnotes($text) { + # + # Strips link definitions from text, stores the URLs and titles in + # hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: [^id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 + [ ]* + \n? # maybe *one* newline + ( # text = $2 (no blank lines allowed) + (?: + .+ # actual text + | + \n # newlines but + (?!\[\^.+?\]:\s)# negative lookahead for footnote marker. + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + # by non-indented content + )* + ) + }xm', + array(&$this, '_stripFootnotes_callback'), + $text); + return $text; + } + function _stripFootnotes_callback($matches) { + $note_id = $this->fn_id_prefix . $matches[1]; + $this->footnotes[$note_id] = $this->outdent($matches[2]); + return ''; # String that will replace the block + } + + + function doFootnotes($text) { + # + # Replace footnote references in $text [^id] with a special text-token + # which will be replaced by the actual footnote marker in appendFootnotes. + # + if (!$this->in_anchor) { + $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); + } + return $text; + } + + + function appendFootnotes($text) { + # + # Append footnote list to text. + # + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array(&$this, '_appendFootnotes_callback'), $text); + + if (!empty($this->footnotes_ordered)) { + $text .= "\n\n"; + $text .= "
    \n"; + $text .= "fn_backlink_class != "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_backlink_title != "") { + $title = $this->fn_backlink_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + $num = 0; + + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + + $footnote .= "\n"; # Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array(&$this, '_appendFootnotes_callback'), $footnote); + + $attr = str_replace("%%", ++$num, $attr); + $note_id = $this->encodeAttribute($note_id); + + # Add backlink to last paragraph; create new paragraph if needed. + $backlink = ""; + if (preg_match('{

    $}', $footnote)) { + $footnote = substr($footnote, 0, -4) . " $backlink

    "; + } else { + $footnote .= "\n\n

    $backlink

    "; + } + + $text .= "
  • \n"; + $text .= $footnote . "\n"; + $text .= "
  • \n\n"; + } + + $text .= "\n"; + $text .= "
    "; + } + return $text; + } + function _appendFootnotes_callback($matches) { + $node_id = $this->fn_id_prefix . $matches[1]; + + # Create footnote marker only if it has a corresponding footnote *and* + # the footnote hasn't been used by another marker. + if (isset($this->footnotes[$node_id])) { + # Transfert footnote content to the ordered list. + $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; + unset($this->footnotes[$node_id]); + + $num = $this->footnote_counter++; + $attr = " rel=\"footnote\""; + if ($this->fn_link_class != "") { + $class = $this->fn_link_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_link_title != "") { + $title = $this->fn_link_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + + $attr = str_replace("%%", $num, $attr); + $node_id = $this->encodeAttribute($node_id); + + return + "". + "$num". + ""; + } + + return "[^".$matches[1]."]"; + } + + + ### Abbreviations ### + + function stripAbbreviations($text) { + # + # Strips abbreviations from text, stores titles in hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: [id]*: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) + }xm', + array(&$this, '_stripAbbreviations_callback'), + $text); + return $text; + } + function _stripAbbreviations_callback($matches) { + $abbr_word = $matches[1]; + $abbr_desc = $matches[2]; + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + return ''; # String that will replace the block + } + + + function doAbbreviations($text) { + # + # Find defined abbreviations in text and wrap them in elements. + # + if ($this->abbr_word_re) { + // cannot use the /x modifier because abbr_word_re may + // contain significant spaces: + $text = preg_replace_callback('{'. + '(?abbr_word_re.')'. + '(?![\w\x1A])'. + '}', + array(&$this, '_doAbbreviations_callback'), $text); + } + return $text; + } + function _doAbbreviations_callback($matches) { + $abbr = $matches[0]; + if (isset($this->abbr_desciptions[$abbr])) { + $desc = $this->abbr_desciptions[$abbr]; + if (empty($desc)) { + return $this->hashPart("$abbr"); + } else { + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); + } + } else { + return $matches[0]; + } + } + +} + + +/* + +PHP Markdown Extra +================== + +Description +----------- + +This is a PHP port of the original Markdown formatter written in Perl +by John Gruber. This special "Extra" version of PHP Markdown features +further enhancements to the syntax for making additional constructs +such as tables and definition list. + +Markdown is a text-to-HTML filter; it translates an easy-to-read / +easy-to-write structured text format into HTML. Markdown's text format +is most similar to that of plain text email, and supports features such +as headers, *emphasis*, code blocks, blockquotes, and links. + +Markdown's syntax is designed not as a generic markup language, but +specifically to serve as a front-end to (X)HTML. You can use span-level +HTML tags anywhere in a Markdown document, and you can use block level +HTML tags (like
    and as well). + +For more information about Markdown's syntax, see: + + + + +Bugs +---- + +To file bug reports please send email to: + + + +Please include with your report: (1) the example input; (2) the output you +expected; (3) the output Markdown actually produced. + + +Version History +--------------- + +See the readme file for detailed release notes for this version. + + +Copyright and License +--------------------- + +PHP Markdown & Extra +Copyright (c) 2004-2008 Michel Fortin + +All rights reserved. + +Based on Markdown +Copyright (c) 2003-2006 John Gruber + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name "Markdown" nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as +is" and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. In no event shall the copyright owner +or contributors be liable for any direct, indirect, incidental, special, +exemplary, or consequential damages (including, but not limited to, +procurement of substitute goods or services; loss of use, data, or +profits; or business interruption) however caused and on any theory of +liability, whether in contract, strict liability, or tort (including +negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + +*/ +?> \ No newline at end of file diff --git a/system/application/libraries/page.php b/system/application/libraries/page.php new file mode 100644 index 0000000..e94d149 --- /dev/null +++ b/system/application/libraries/page.php @@ -0,0 +1,210 @@ +currentPage = (integer) abs($reqCurrentPage); + } + + function SetItemCount($reqItemCount){ + $this->itemCount = (integer) abs($reqItemCount); + } + + function SetItemsPerPage($reqItemsPerPage){ + $this->itemsPerPage = (integer) abs($reqItemsPerPage); + } + + function SetLinksHref($reqLinksHref){ + $this->linksHref = $reqLinksHref; + } + + function SetLinksFormat($reqPageJumpBack, $reqPageSeparator, $reqPageJumpNext){ + $this->pageJumpBack = $reqPageJumpBack; + $this->pageSeparator = $reqPageSeparator; + $this->pageJumpNext = $reqPageJumpNext; + } + + function SetLinksToDisplay($reqLinksToDisplay){ + $this->linksToDisplay = (integer) abs($reqLinksToDisplay); + } + + function SetQueryStringVar($reqQueryStringVar){ + $this->queryStringVar = $reqQueryStringVar; + } + + function SetQueryString($reqQueryString){ + $this->queryString = $reqQueryString; + } + + function GetCurrentCollection($reqCollection){ + if($this->currentPage < 1){ + $start = 0; + } + elseif($this->currentPage > $this->GetPageCount()){ + $start = $this->GetPageCount() * $this->itemsPerPage - $this->itemsPerPage; + } + else { + $start = $this->currentPage * $this->itemsPerPage - $this->itemsPerPage; + } + + return array_slice($reqCollection, $start, $this->itemsPerPage); + } + + function GetPageCount(){ + return (integer)ceil($this->itemCount/$this->itemsPerPage); + } + + function GetPageLinks(){ + $strLinks = ''; + $pageCount = $this->GetPageCount(); + $queryString = $this->GetQueryString(); + $linksPad = floor($this->linksToDisplay/2); + + if($this->linksToDisplay == -1){ + $this->linksToDisplay = $pageCount; + } + + + if($pageCount == 0){ + $strLinks = '1'; + } + elseif($this->currentPage - 1 <= $linksPad || ($pageCount - $this->linksToDisplay + 1 == 0) || $this->linksToDisplay > $pageCount){ + $start = 1; + } + elseif($pageCount - $this->currentPage <= $linksPad){ + $start = $pageCount - $this->linksToDisplay + 1; + } + else { + $start = $this->currentPage - $linksPad; + } + + + if(isset($start)){ + if($start > 1){ + if(!empty($this->pageJumpBack)){ + $pageNum = $start - $this->linksToDisplay + $linksPad; + if($pageNum < 1){ + $pageNum = 1; + } + + $strLinks .= ''; + $strLinks .= $this->pageJumpBack.''.$this->pageSeparator; + } + + $strLinks .= '1...'.$this->pageSeparator; + } + + + if($start + $this->linksToDisplay > $pageCount){ + $end = $pageCount; + } + else { + $end = $start + $this->linksToDisplay - 1; + } + + + for($i = $start; $i <= $end; $i ++){ + if($i != $this->currentPage){ + $strLinks .= ''; + $strLinks .= ($i).''.$this->pageSeparator; + } + else { + $strLinks .= $i.$this->pageSeparator; + } + } + $strLinks = substr($strLinks, 0, -strlen($this->pageSeparator)); + + + if($start + $this->linksToDisplay - 1 < $pageCount){ + $strLinks .= $this->pageSeparator.''; + $strLinks .= '...'.$pageCount.''.$this->pageSeparator; + + if(!empty($this->pageJumpNext)){ + $pageNum = $start + $this->linksToDisplay + $linksPad; + if($pageNum > $pageCount){ + $pageNum = $pageCount; + } + + $strLinks .= ''; + $strLinks .= $this->pageJumpNext.''; + } + } + } + + + return $strLinks; + } + + function GetQueryString(){ + $pattern = array('/'.$this->queryStringVar.'=[^&]*&?/', '/&$/'); + $replace = array('', ''); + $queryString = preg_replace($pattern, $replace, $this->queryString); + $queryString = str_replace('&', '&', $queryString); + + if(!empty($queryString)){ + $queryString.= '&'; + } + + return "page/"; + } + + function GetSqlLimit(){ + return $this->itemsPerPage; + } + + function GetOffset(){ + return $this->currentPage * $this->itemsPerPage - $this->itemsPerPage; + } + + function GetLimit(){ + return $this->itemsPerPage; + } + + function __Construct(){ + $this->SetCurrentPage(1); + $this->SetItemsPerPage(10); + $this->SetItemCount(0); + $this->SetLinksFormat('« Back',' • ','Next »'); + $this->SetLinksHref($_SERVER['PHP_SELF']); + $this->SetLinksToDisplay(10); + $this->SetQueryStringVar('page'); + $this->SetQueryString($_SERVER['QUERY_STRING']); + + if(isset($_GET[$this->queryStringVar]) && is_numeric($_GET[$this->queryStringVar])){ + $this->SetCurrentPage($_GET[$this->queryStringVar]); + } + } +} + +?> \ No newline at end of file diff --git a/system/application/libraries/simplepie.php b/system/application/libraries/simplepie.php new file mode 100644 index 0000000..f5cd9a7 --- /dev/null +++ b/system/application/libraries/simplepie.php @@ -0,0 +1,13284 @@ +' . SIMPLEPIE_NAME . ''); + +/** + * No Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_NONE', 0); + +/** + * Feed Link Element Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1); + +/** + * Local Feed Extension Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2); + +/** + * Local Feed Body Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4); + +/** + * Remote Feed Extension Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8); + +/** + * Remote Feed Body Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16); + +/** + * All Feed Autodiscovery + * @see SimplePie::set_autodiscovery_level() + */ +define('SIMPLEPIE_LOCATOR_ALL', 31); + +/** + * No known feed type + */ +define('SIMPLEPIE_TYPE_NONE', 0); + +/** + * RSS 0.90 + */ +define('SIMPLEPIE_TYPE_RSS_090', 1); + +/** + * RSS 0.91 (Netscape) + */ +define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2); + +/** + * RSS 0.91 (Userland) + */ +define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4); + +/** + * RSS 0.91 (both Netscape and Userland) + */ +define('SIMPLEPIE_TYPE_RSS_091', 6); + +/** + * RSS 0.92 + */ +define('SIMPLEPIE_TYPE_RSS_092', 8); + +/** + * RSS 0.93 + */ +define('SIMPLEPIE_TYPE_RSS_093', 16); + +/** + * RSS 0.94 + */ +define('SIMPLEPIE_TYPE_RSS_094', 32); + +/** + * RSS 1.0 + */ +define('SIMPLEPIE_TYPE_RSS_10', 64); + +/** + * RSS 2.0 + */ +define('SIMPLEPIE_TYPE_RSS_20', 128); + +/** + * RDF-based RSS + */ +define('SIMPLEPIE_TYPE_RSS_RDF', 65); + +/** + * Non-RDF-based RSS (truly intended as syndication format) + */ +define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190); + +/** + * All RSS + */ +define('SIMPLEPIE_TYPE_RSS_ALL', 255); + +/** + * Atom 0.3 + */ +define('SIMPLEPIE_TYPE_ATOM_03', 256); + +/** + * Atom 1.0 + */ +define('SIMPLEPIE_TYPE_ATOM_10', 512); + +/** + * All Atom + */ +define('SIMPLEPIE_TYPE_ATOM_ALL', 768); + +/** + * All feed types + */ +define('SIMPLEPIE_TYPE_ALL', 1023); + +/** + * No construct + */ +define('SIMPLEPIE_CONSTRUCT_NONE', 0); + +/** + * Text construct + */ +define('SIMPLEPIE_CONSTRUCT_TEXT', 1); + +/** + * HTML construct + */ +define('SIMPLEPIE_CONSTRUCT_HTML', 2); + +/** + * XHTML construct + */ +define('SIMPLEPIE_CONSTRUCT_XHTML', 4); + +/** + * base64-encoded construct + */ +define('SIMPLEPIE_CONSTRUCT_BASE64', 8); + +/** + * IRI construct + */ +define('SIMPLEPIE_CONSTRUCT_IRI', 16); + +/** + * A construct that might be HTML + */ +define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32); + +/** + * All constructs + */ +define('SIMPLEPIE_CONSTRUCT_ALL', 63); + +/** + * PCRE for HTML attributes + */ +define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*'); + +/** + * PCRE for XML attributes + */ +define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*'); + +/** + * XML Namespace + */ +define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace'); + +/** + * Atom 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom'); + +/** + * Atom 0.3 Namespace + */ +define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#'); + +/** + * RDF Namespace + */ +define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); + +/** + * RSS 0.90 Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/'); + +/** + * RSS 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/'); + +/** + * RSS 1.0 Content Module Namespace + */ +define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/'); + +/** + * DC 1.0 Namespace + */ +define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/'); + +/** + * DC 1.1 Namespace + */ +define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/'); + +/** + * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace + */ +define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); + +/** + * GeoRSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss'); + +/** + * Media RSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/'); + +/** + * iTunes RSS Namespace + */ +define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); + +/** + * XHTML Namespace + */ +define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml'); + +/** + * IANA Link Relations Registry + */ +define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/'); + +/** + * Whether we're running on PHP5 + */ +define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>=')); + +/** + * No file source + */ +define('SIMPLEPIE_FILE_SOURCE_NONE', 0); + +/** + * Remote file source + */ +define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1); + +/** + * Local file source + */ +define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2); + +/** + * fsockopen() file source + */ +define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4); + +/** + * cURL file source + */ +define('SIMPLEPIE_FILE_SOURCE_CURL', 8); + +/** + * file_get_contents() file source + */ +define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); + +/** + * SimplePie + * + * @package SimplePie + * @version "Razzleberry" + * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon + * @author Ryan Parman + * @author Geoffrey Sneddon + * @todo Option for type of fetching (cache, not modified header, fetch, etc.) + */ +class SimplePie +{ + /** + * @var array Raw data + * @access private + */ + var $data = array(); + + /** + * @var mixed Error string + * @access private + */ + var $error; + + /** + * @var object Instance of SimplePie_Sanitize (or other class) + * @see SimplePie::set_sanitize_class() + * @access private + */ + var $sanitize; + + /** + * @var string SimplePie Useragent + * @see SimplePie::set_useragent() + * @access private + */ + var $useragent = SIMPLEPIE_USERAGENT; + + /** + * @var string Feed URL + * @see SimplePie::set_feed_url() + * @access private + */ + var $feed_url; + + /** + * @var object Instance of SimplePie_File to use as a feed + * @see SimplePie::set_file() + * @access private + */ + var $file; + + /** + * @var string Raw feed data + * @see SimplePie::set_raw_data() + * @access private + */ + var $raw_data; + + /** + * @var int Timeout for fetching remote files + * @see SimplePie::set_timeout() + * @access private + */ + var $timeout = 10; + + /** + * @var bool Forces fsockopen() to be used for remote files instead + * of cURL, even if a new enough version is installed + * @see SimplePie::force_fsockopen() + * @access private + */ + var $force_fsockopen = false; + + /** + * @var bool Force the given data/URL to be treated as a feed no matter what + * it appears like + * @see SimplePie::force_feed() + * @access private + */ + var $force_feed = false; + + /** + * @var bool Enable/Disable XML dump + * @see SimplePie::enable_xml_dump() + * @access private + */ + var $xml_dump = false; + + /** + * @var bool Enable/Disable Caching + * @see SimplePie::enable_cache() + * @access private + */ + var $cache = true; + + /** + * @var int Cache duration (in seconds) + * @see SimplePie::set_cache_duration() + * @access private + */ + var $cache_duration = 3600; + + /** + * @var int Auto-discovery cache duration (in seconds) + * @see SimplePie::set_autodiscovery_cache_duration() + * @access private + */ + var $autodiscovery_cache_duration = 604800; // 7 Days. + + /** + * @var string Cache location (relative to executing script) + * @see SimplePie::set_cache_location() + * @access private + */ + var $cache_location = './cache'; + + /** + * @var string Function that creates the cache filename + * @see SimplePie::set_cache_name_function() + * @access private + */ + var $cache_name_function = 'md5'; + + /** + * @var bool Reorder feed by date descending + * @see SimplePie::enable_order_by_date() + * @access private + */ + var $order_by_date = true; + + /** + * @var mixed Force input encoding to be set to the follow value + * (false, or anything type-cast to false, disables this feature) + * @see SimplePie::set_input_encoding() + * @access private + */ + var $input_encoding = false; + + /** + * @var int Feed Autodiscovery Level + * @see SimplePie::set_autodiscovery_level() + * @access private + */ + var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; + + /** + * @var string Class used for caching feeds + * @see SimplePie::set_cache_class() + * @access private + */ + var $cache_class = 'SimplePie_Cache'; + + /** + * @var string Class used for locating feeds + * @see SimplePie::set_locator_class() + * @access private + */ + var $locator_class = 'SimplePie_Locator'; + + /** + * @var string Class used for parsing feeds + * @see SimplePie::set_parser_class() + * @access private + */ + var $parser_class = 'SimplePie_Parser'; + + /** + * @var string Class used for fetching feeds + * @see SimplePie::set_file_class() + * @access private + */ + var $file_class = 'SimplePie_File'; + + /** + * @var string Class used for items + * @see SimplePie::set_item_class() + * @access private + */ + var $item_class = 'SimplePie_Item'; + + /** + * @var string Class used for authors + * @see SimplePie::set_author_class() + * @access private + */ + var $author_class = 'SimplePie_Author'; + + /** + * @var string Class used for categories + * @see SimplePie::set_category_class() + * @access private + */ + var $category_class = 'SimplePie_Category'; + + /** + * @var string Class used for enclosures + * @see SimplePie::set_enclosures_class() + * @access private + */ + var $enclosure_class = 'SimplePie_Enclosure'; + + /** + * @var string Class used for Media RSS captions + * @see SimplePie::set_caption_class() + * @access private + */ + var $caption_class = 'SimplePie_Caption'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_copyright_class() + * @access private + */ + var $copyright_class = 'SimplePie_Copyright'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_credit_class() + * @access private + */ + var $credit_class = 'SimplePie_Credit'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_rating_class() + * @access private + */ + var $rating_class = 'SimplePie_Rating'; + + /** + * @var string Class used for Media RSS + * @see SimplePie::set_restriction_class() + * @access private + */ + var $restriction_class = 'SimplePie_Restriction'; + + /** + * @var string Class used for content-type sniffing + * @see SimplePie::set_content_type_sniffer_class() + * @access private + */ + var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; + + /** + * @var string Class used for item sources. + * @see SimplePie::set_source_class() + * @access private + */ + var $source_class = 'SimplePie_Source'; + + /** + * @var mixed Set javascript query string parameter (false, or + * anything type-cast to false, disables this feature) + * @see SimplePie::set_javascript() + * @access private + */ + var $javascript = 'js'; + + /** + * @var int Maximum number of feeds to check with autodiscovery + * @see SimplePie::set_max_checked_feeds() + * @access private + */ + var $max_checked_feeds = 10; + + /** + * @var string Web-accessible path to the handler_favicon.php file. + * @see SimplePie::set_favicon_handler() + * @access private + */ + var $favicon_handler = ''; + + /** + * @var string Web-accessible path to the handler_image.php file. + * @see SimplePie::set_image_handler() + * @access private + */ + var $image_handler = ''; + + /** + * @var array Stores the URLs when multiple feeds are being initialized. + * @see SimplePie::set_feed_url() + * @access private + */ + var $multifeed_url = array(); + + /** + * @var array Stores SimplePie objects when multiple feeds initialized. + * @access private + */ + var $multifeed_objects = array(); + + /** + * @var array Stores the get_object_vars() array for use with multifeeds. + * @see SimplePie::set_feed_url() + * @access private + */ + var $config_settings = null; + + /** + * @var integer Stores the number of items to return per-feed with multifeeds. + * @see SimplePie::set_item_limit() + * @access private + */ + var $item_limit = 0; + + /** + * @var array Stores the default attributes to be stripped by strip_attributes(). + * @see SimplePie::strip_attributes() + * @access private + */ + var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); + + /** + * @var array Stores the default tags to be stripped by strip_htmltags(). + * @see SimplePie::strip_htmltags() + * @access private + */ + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + + /** + * The SimplePie class contains feed level data and options + * + * There are two ways that you can create a new SimplePie object. The first + * is by passing a feed URL as a parameter to the SimplePie constructor + * (as well as optionally setting the cache location and cache expiry). This + * will initialise the whole feed with all of the default settings, and you + * can begin accessing methods and properties immediately. + * + * The second way is to create the SimplePie object with no parameters + * at all. This will enable you to set configuration options. After setting + * them, you must initialise the feed using $feed->init(). At that point the + * object's methods and properties will be available to you. This format is + * what is used throughout this documentation. + * + * @access public + * @since 1.0 Preview Release + * @param string $feed_url This is the URL you want to parse. + * @param string $cache_location This is where you want the cache to be stored. + * @param int $cache_duration This is the number of seconds that you want to store the cache file for. + */ + function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) + { + // Other objects, instances created here so we can set options on them + $this->sanitize =& new SimplePie_Sanitize; + + // Set options if they're passed to the constructor + if ($cache_location !== null) + { + $this->set_cache_location($cache_location); + } + + if ($cache_duration !== null) + { + $this->set_cache_duration($cache_duration); + } + + // Only init the script if we're passed a feed URL + if ($feed_url !== null) + { + $this->set_feed_url($feed_url); + $this->init(); + } + } + + /** + * Used for converting object to a string + */ + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + if (!empty($this->data['items'])) + { + foreach ($this->data['items'] as $item) + { + $item->__destruct(); + } + unset($this->data['items']); + } + if (!empty($this->data['ordered_items'])) + { + foreach ($this->data['ordered_items'] as $item) + { + $item->__destruct(); + } + unset($this->data['ordered_items']); + } + } + + /** + * Force the given data/URL to be treated as a feed no matter what it + * appears like + * + * @access public + * @since 1.1 + * @param bool $enable Force the given data/URL to be treated as a feed + */ + function force_feed($enable = false) + { + $this->force_feed = (bool) $enable; + } + + /** + * This is the URL of the feed you want to parse. + * + * This allows you to enter the URL of the feed you want to parse, or the + * website you want to try to use auto-discovery on. This takes priority + * over any set raw data. + * + * You can set multiple feeds to mash together by passing an array instead + * of a string for the $url. Remember that with each additional feed comes + * additional processing and resources. + * + * @access public + * @since 1.0 Preview Release + * @param mixed $url This is the URL (or array of URLs) that you want to parse. + * @see SimplePie::set_raw_data() + */ + function set_feed_url($url) + { + if (is_array($url)) + { + $this->multifeed_url = array(); + foreach ($url as $value) + { + $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1); + } + } + else + { + $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); + } + } + + /** + * Provides an instance of SimplePie_File to use as a feed + * + * @access public + * @param object &$file Instance of SimplePie_File (or subclass) + * @return bool True on success, false on failure + */ + function set_file(&$file) + { + if (is_a($file, 'SimplePie_File')) + { + $this->feed_url = $file->url; + $this->file =& $file; + return true; + } + return false; + } + + /** + * Allows you to use a string of RSS/Atom data instead of a remote feed. + * + * If you have a feed available as a string in PHP, you can tell SimplePie + * to parse that data string instead of a remote feed. Any set feed URL + * takes precedence. + * + * @access public + * @since 1.0 Beta 3 + * @param string $data RSS or Atom data as a string. + * @see SimplePie::set_feed_url() + */ + function set_raw_data($data) + { + $this->raw_data = trim($data); + } + + /** + * Allows you to override the default timeout for fetching remote feeds. + * + * This allows you to change the maximum time the feed's server to respond + * and send the feed back. + * + * @access public + * @since 1.0 Beta 3 + * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. + */ + function set_timeout($timeout = 10) + { + $this->timeout = (int) $timeout; + } + + /** + * Forces SimplePie to use fsockopen() instead of the preferred cURL + * functions. + * + * @access public + * @since 1.0 Beta 3 + * @param bool $enable Force fsockopen() to be used + */ + function force_fsockopen($enable = false) + { + $this->force_fsockopen = (bool) $enable; + } + + /** + * Outputs the raw XML content of the feed, after it has gone through + * SimplePie's filters. + * + * Used only for debugging, this function will output the XML content as + * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up + * before trying to parse it. Many parts of the feed are re-written in + * memory, and in the end, you have a parsable feed. XML dump shows you the + * actual XML that SimplePie tries to parse, which may or may not be very + * different from the original feed. + * + * @access public + * @since 1.0 Preview Release + * @param bool $enable Enable XML dump + */ + function enable_xml_dump($enable = false) + { + $this->xml_dump = (bool) $enable; + } + + /** + * Enables/disables caching in SimplePie. + * + * This option allows you to disable caching all-together in SimplePie. + * However, disabling the cache can lead to longer load times. + * + * @access public + * @since 1.0 Preview Release + * @param bool $enable Enable caching + */ + function enable_cache($enable = true) + { + $this->cache = (bool) $enable; + } + + /** + * Set the length of time (in seconds) that the contents of a feed + * will be cached. + * + * @access public + * @param int $seconds The feed content cache duration. + */ + function set_cache_duration($seconds = 3600) + { + $this->cache_duration = (int) $seconds; + } + + /** + * Set the length of time (in seconds) that the autodiscovered feed + * URL will be cached. + * + * @access public + * @param int $seconds The autodiscovered feed URL cache duration. + */ + function set_autodiscovery_cache_duration($seconds = 604800) + { + $this->autodiscovery_cache_duration = (int) $seconds; + } + + /** + * Set the file system location where the cached files should be stored. + * + * @access public + * @param string $location The file system location. + */ + function set_cache_location($location = './cache') + { + $this->cache_location = (string) $location; + } + + /** + * Determines whether feed items should be sorted into reverse chronological order. + * + * @access public + * @param bool $enable Sort as reverse chronological order. + */ + function enable_order_by_date($enable = true) + { + $this->order_by_date = (bool) $enable; + } + + /** + * Allows you to override the character encoding reported by the feed. + * + * @access public + * @param string $encoding Character encoding. + */ + function set_input_encoding($encoding = false) + { + if ($encoding) + { + $this->input_encoding = (string) $encoding; + } + else + { + $this->input_encoding = false; + } + } + + /** + * Set how much feed autodiscovery to do + * + * @access public + * @see SIMPLEPIE_LOCATOR_NONE + * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY + * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION + * @see SIMPLEPIE_LOCATOR_LOCAL_BODY + * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION + * @see SIMPLEPIE_LOCATOR_REMOTE_BODY + * @see SIMPLEPIE_LOCATOR_ALL + * @param int $level Feed Autodiscovery Level (level can be a + * combination of the above constants, see bitwise OR operator) + */ + function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) + { + $this->autodiscovery = (int) $level; + } + + /** + * Allows you to change which class SimplePie uses for caching. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_cache_class($class = 'SimplePie_Cache') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) + { + $this->cache_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for auto-discovery. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_locator_class($class = 'SimplePie_Locator') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) + { + $this->locator_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for XML parsing. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_parser_class($class = 'SimplePie_Parser') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) + { + $this->parser_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for remote file fetching. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_file_class($class = 'SimplePie_File') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) + { + $this->file_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for data sanitization. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_sanitize_class($class = 'SimplePie_Sanitize') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) + { + $this->sanitize =& new $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling feed items. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_item_class($class = 'SimplePie_Item') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) + { + $this->item_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling author data. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_author_class($class = 'SimplePie_Author') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) + { + $this->author_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for handling category data. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_category_class($class = 'SimplePie_Category') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) + { + $this->category_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for feed enclosures. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_enclosure_class($class = 'SimplePie_Enclosure') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) + { + $this->enclosure_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for captions + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_caption_class($class = 'SimplePie_Caption') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) + { + $this->caption_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_copyright_class($class = 'SimplePie_Copyright') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) + { + $this->copyright_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_credit_class($class = 'SimplePie_Credit') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) + { + $this->credit_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_rating_class($class = 'SimplePie_Rating') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) + { + $this->rating_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_restriction_class($class = 'SimplePie_Restriction') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) + { + $this->restriction_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses for content-type sniffing. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) + { + $this->content_type_sniffer_class = $class; + return true; + } + return false; + } + + /** + * Allows you to change which class SimplePie uses item sources. + * Useful when you are overloading or extending SimplePie's default classes. + * + * @access public + * @param string $class Name of custom class. + * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation + * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation + */ + function set_source_class($class = 'SimplePie_Source') + { + if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) + { + $this->source_class = $class; + return true; + } + return false; + } + + /** + * Allows you to override the default user agent string. + * + * @access public + * @param string $ua New user agent string. + */ + function set_useragent($ua = SIMPLEPIE_USERAGENT) + { + $this->useragent = (string) $ua; + } + + /** + * Set callback function to create cache filename with + * + * @access public + * @param mixed $function Callback function + */ + function set_cache_name_function($function = 'md5') + { + if (is_callable($function)) + { + $this->cache_name_function = $function; + } + } + + /** + * Set javascript query string parameter + * + * @access public + * @param mixed $get Javascript query string parameter + */ + function set_javascript($get = 'js') + { + if ($get) + { + $this->javascript = (string) $get; + } + else + { + $this->javascript = false; + } + } + + /** + * Set options to make SP as fast as possible. Forgoes a + * substantial amount of data sanitization in favor of speed. + * + * @access public + * @param bool $set Whether to set them or not + */ + function set_stupidly_fast($set = false) + { + if ($set) + { + $this->enable_order_by_date(false); + $this->remove_div(false); + $this->strip_comments(false); + $this->strip_htmltags(false); + $this->strip_attributes(false); + $this->set_image_handler(false); + } + } + + /** + * Set maximum number of feeds to check with autodiscovery + * + * @access public + * @param int $max Maximum number of feeds to check + */ + function set_max_checked_feeds($max = 10) + { + $this->max_checked_feeds = (int) $max; + } + + function remove_div($enable = true) + { + $this->sanitize->remove_div($enable); + } + + function strip_htmltags($tags = '', $encode = null) + { + if ($tags === '') + { + $tags = $this->strip_htmltags; + } + $this->sanitize->strip_htmltags($tags); + if ($encode !== null) + { + $this->sanitize->encode_instead_of_strip($tags); + } + } + + function encode_instead_of_strip($enable = true) + { + $this->sanitize->encode_instead_of_strip($enable); + } + + function strip_attributes($attribs = '') + { + if ($attribs === '') + { + $attribs = $this->strip_attributes; + } + $this->sanitize->strip_attributes($attribs); + } + + function set_output_encoding($encoding = 'UTF-8') + { + $this->sanitize->set_output_encoding($encoding); + } + + function strip_comments($strip = false) + { + $this->sanitize->strip_comments($strip); + } + + /** + * Set element/attribute key/value pairs of HTML attributes + * containing URLs that need to be resolved relative to the feed + * + * @access public + * @since 1.0 + * @param array $element_attribute Element/attribute key/value pairs + */ + function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) + { + $this->sanitize->set_url_replacements($element_attribute); + } + + /** + * Set the handler to enable the display of cached favicons. + * + * @access public + * @param str $page Web-accessible path to the handler_favicon.php file. + * @param str $qs The query string that the value should be passed to. + */ + function set_favicon_handler($page = false, $qs = 'i') + { + if ($page != false) + { + $this->favicon_handler = $page . '?' . $qs . '='; + } + else + { + $this->favicon_handler = ''; + } + } + + /** + * Set the handler to enable the display of cached images. + * + * @access public + * @param str $page Web-accessible path to the handler_image.php file. + * @param str $qs The query string that the value should be passed to. + */ + function set_image_handler($page = false, $qs = 'i') + { + if ($page != false) + { + $this->sanitize->set_image_handler($page . '?' . $qs . '='); + } + else + { + $this->image_handler = ''; + } + } + + /** + * Set the limit for items returned per-feed with multifeeds. + * + * @access public + * @param integer $limit The maximum number of items to return. + */ + function set_item_limit($limit = 0) + { + $this->item_limit = (int) $limit; + } + + function init() + { + if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre')) + { + return false; + } + if (isset($_GET[$this->javascript])) + { + if (function_exists('ob_gzhandler')) + { + ob_start('ob_gzhandler'); + } + header('Content-type: text/javascript; charset: UTF-8'); + header('Cache-Control: must-revalidate'); + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days + ?> +function embed_odeo(link) { + document.writeln(''); +} + +function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) { + if (placeholder != '') { + document.writeln(''); + } + else { + document.writeln(''); + } +} + +function embed_flash(bgcolor, width, height, link, loop, type) { + document.writeln(''); +} + +function embed_flv(width, height, link, placeholder, loop, player) { + document.writeln(''); +} + +function embed_wmedia(width, height, link) { + document.writeln(''); +} + sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); + $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); + + if ($this->feed_url !== null || $this->raw_data !== null) + { + $this->data = array(); + $this->multifeed_objects = array(); + $cache = false; + + if ($this->feed_url !== null) + { + $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); + // Decide whether to enable caching + if ($this->cache && $parsed_feed_url['scheme'] !== '') + { + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); + } + // If it's enabled and we don't want an XML dump, use the cache + if ($cache && !$this->xml_dump) + { + // Load the Cache + $this->data = $cache->load(); + if (!empty($this->data)) + { + // If the cache is for an outdated build of SimplePie + if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD) + { + $cache->unlink(); + $this->data = array(); + } + // If we've hit a collision just rerun it with caching disabled + elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url) + { + $cache = false; + $this->data = array(); + } + // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. + elseif (isset($this->data['feed_url'])) + { + // If the autodiscovery cache is still valid use it. + if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) + { + // Do not need to do feed autodiscovery yet. + if ($this->data['feed_url'] == $this->data['url']) + { + $cache->unlink(); + $this->data = array(); + } + else + { + $this->set_feed_url($this->data['feed_url']); + return $this->init(); + } + } + } + // Check if the cache has been updated + elseif ($cache->mtime() + $this->cache_duration < time()) + { + // If we have last-modified and/or etag set + if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) + { + $headers = array(); + if (isset($this->data['headers']['last-modified'])) + { + $headers['if-modified-since'] = $this->data['headers']['last-modified']; + } + if (isset($this->data['headers']['etag'])) + { + $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; + } + $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); + if ($file->success) + { + if ($file->status_code == 304) + { + $cache->touch(); + return true; + } + else + { + $headers = $file->headers; + } + } + else + { + unset($file); + } + } + } + // If the cache is still valid, just return true + else + { + return true; + } + } + // If the cache is empty, delete it + else + { + $cache->unlink(); + $this->data = array(); + } + } + // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. + if (!isset($file)) + { + if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url) + { + $file =& $this->file; + } + else + { + $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); + } + } + // If the file connection has an error, set SimplePie::error to that and quit + if (!$file->success) + { + $this->error = $file->error; + if (!empty($this->data)) + { + return true; + } + else + { + return false; + } + } + + if (!$this->force_feed) + { + // Check if the supplied URL is a feed, if it isn't, look for it. + $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); + if (!$locate->is_feed($file)) + { + // We need to unset this so that if SimplePie::set_file() has been called that object is untouched + unset($file); + if ($file = $locate->find($this->autodiscovery)) + { + if ($cache) + { + $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); + if (!$cache->save($this)) + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); + } + $this->feed_url = $file->url; + } + else + { + $this->error = "A feed could not be found at $this->feed_url"; + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + } + $locate = null; + } + + $headers = $file->headers; + $data = $file->body; + $sniffer = new $this->content_type_sniffer_class($file); + $sniffed = $sniffer->get_type(); + } + else + { + $data = $this->raw_data; + } + + // Set up array of possible encodings + $encodings = array(); + + // First check to see if input has been overridden. + if ($this->input_encoding !== false) + { + $encodings[] = $this->input_encoding; + } + + $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); + $text_types = array('text/xml', 'text/xml-external-parsed-entity'); + + // RFC 3023 (only applies to sniffed content) + if (isset($sniffed)) + { + if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') + { + if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) + { + $encodings[] = strtoupper($charset[1]); + } + $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); + $encodings[] = 'UTF-8'; + } + elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') + { + if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) + { + $encodings[] = $charset[1]; + } + $encodings[] = 'US-ASCII'; + } + // Text MIME-type default + elseif (substr($sniffed, 0, 5) === 'text/') + { + $encodings[] = 'US-ASCII'; + } + } + + // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 + $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); + $encodings[] = 'UTF-8'; + $encodings[] = 'ISO-8859-1'; + + // There's no point in trying an encoding twice + $encodings = array_unique($encodings); + + // If we want the XML, just output that with the most likely encoding and quit + if ($this->xml_dump) + { + header('Content-type: text/xml; charset=' . $encodings[0]); + echo $data; + exit; + } + + // Loop through each possible encoding, till we return something, or run out of possibilities + foreach ($encodings as $encoding) + { + // Change the encoding to UTF-8 (as we always use UTF-8 internally) + $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'); + + // Create new parser + $parser =& new $this->parser_class(); + + // If it's parsed fine + if ($parser->parse($utf8_data, 'UTF-8')) + { + $this->data = $parser->get_data(); + if (isset($this->data['child'])) + { + if (isset($headers)) + { + $this->data['headers'] = $headers; + } + $this->data['build'] = SIMPLEPIE_BUILD; + + // Cache the file if caching is enabled + if ($cache && !$cache->save($this)) + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + return true; + } + else + { + $this->error = "A feed could not be found at $this->feed_url"; + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + } + } + // We have an error, just set SimplePie::error to it and quit + $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); + SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); + return false; + } + elseif (!empty($this->multifeed_url)) + { + $i = 0; + $success = 0; + $this->multifeed_objects = array(); + foreach ($this->multifeed_url as $url) + { + if (SIMPLEPIE_PHP5) + { + // This keyword needs to defy coding standards for PHP4 compatibility + $this->multifeed_objects[$i] = clone($this); + } + else + { + $this->multifeed_objects[$i] = $this; + } + $this->multifeed_objects[$i]->set_feed_url($url); + $success |= $this->multifeed_objects[$i]->init(); + $i++; + } + return (bool) $success; + } + else + { + return false; + } + } + + /** + * Return the error message for the occured error + * + * @access public + * @return string Error message + */ + function error() + { + return $this->error; + } + + function get_encoding() + { + return $this->sanitize->output_encoding; + } + + function handle_content_type($mime = 'text/html') + { + if (!headers_sent()) + { + $header = "Content-type: $mime;"; + if ($this->get_encoding()) + { + $header .= ' charset=' . $this->get_encoding(); + } + else + { + $header .= ' charset=UTF-8'; + } + header($header); + } + } + + function get_type() + { + if (!isset($this->data['type'])) + { + $this->data['type'] = SIMPLEPIE_TYPE_ALL; + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; + } + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) + || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; + } + } + elseif (isset($this->data['child']['']['rss'])) + { + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; + if (isset($this->data['child']['']['rss'][0]['attribs']['']['version'])) + { + switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version'])) + { + case '0.91': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; + if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data'])) + { + switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data'])) + { + case '0': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; + break; + + case '24': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; + break; + } + } + break; + + case '0.92': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; + break; + + case '0.93': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; + break; + + case '0.94': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; + break; + + case '2.0': + $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; + break; + } + } + } + else + { + $this->data['type'] = SIMPLEPIE_TYPE_NONE; + } + } + return $this->data['type']; + } + + /** + * Returns the URL for the favicon of the feed's website. + * + * @todo Cache atom:icon + * @access public + * @since 1.0 + */ + function get_favicon() + { + //chopped out a bit here because I always want to use the domain default favicon, not the one set in the feed + if (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) + { + $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); + + if ($this->cache && $this->favicon_handler) + { + $favicon_filename = call_user_func($this->cache_name_function, $favicon); + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); + + if ($cache->load()) + { + return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); + + if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0) + { + $sniffer = new $this->content_type_sniffer_class($file); + if (substr($sniffer->get_type(), 0, 6) === 'image/') + { + if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) + { + return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + } + } + else + { + return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); + } + } + return false; + } + + /** + * @todo If we have a perm redirect we should return the new URL + * @todo When we make the above change, let's support as well + * @todo Also, |atom:link|@rel=self + */ + function subscribe_url() + { + if ($this->feed_url !== null) + { + return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_feed() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_outlook() + { + if ($this->feed_url !== null) + { + return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_podcast() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + function subscribe_itunes() + { + if ($this->feed_url !== null) + { + return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + return null; + } + } + + /** + * Creates the subscribe_* methods' return data + * + * @access private + * @param string $feed_url String to prefix to the feed URL + * @param string $site_url String to prefix to the site URL (and + * suffix to the feed URL) + * @return mixed URL if feed exists, false otherwise + */ + function subscribe_service($feed_url, $site_url = null) + { + if ($this->subscribe_url()) + { + $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url); + if ($site_url !== null && $this->get_link() !== null) + { + $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link()); + } + return $return; + } + else + { + return null; + } + } + + function subscribe_aol() + { + return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); + } + + function subscribe_bloglines() + { + return urldecode($this->subscribe_service('http://www.bloglines.com/sub/')); + } + + function subscribe_eskobo() + { + return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); + } + + function subscribe_feedfeeds() + { + return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); + } + + function subscribe_feedster() + { + return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); + } + + function subscribe_google() + { + return $this->subscribe_service('http://fusion.google.com/add?feedurl='); + } + + function subscribe_gritwire() + { + return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); + } + + function subscribe_msn() + { + return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); + } + + function subscribe_netvibes() + { + return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); + } + + function subscribe_newsburst() + { + return $this->subscribe_service('http://www.newsburst.com/Source/?add='); + } + + function subscribe_newsgator() + { + return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); + } + + function subscribe_odeo() + { + return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); + } + + function subscribe_podnova() + { + return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); + } + + function subscribe_rojo() + { + return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); + } + + function subscribe_yahoo() + { + return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); + } + + function get_feed_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_ATOM_10) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_ATOM_03) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_RDF) + { + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) + { + return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag])) + { + return $this->data['child']['']['rss'][0]['child'][$namespace][$tag]; + } + } + return null; + } + + function get_channel_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_ATOM_ALL) + { + if ($return = $this->get_feed_tags($namespace, $tag)) + { + return $return; + } + } + if ($type & SIMPLEPIE_TYPE_RSS_10) + { + if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_090) + { + if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if ($channel = $this->get_feed_tags('', 'channel')) + { + if (isset($channel[0]['child'][$namespace][$tag])) + { + return $channel[0]['child'][$namespace][$tag]; + } + } + } + return null; + } + + function get_image_tags($namespace, $tag) + { + $type = $this->get_type(); + if ($type & SIMPLEPIE_TYPE_RSS_10) + { + if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_090) + { + if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) + { + if ($image = $this->get_channel_tags('', 'image')) + { + if (isset($image[0]['child'][$namespace][$tag])) + { + return $image[0]['child'][$namespace][$tag]; + } + } + } + return null; + } + + function get_base($element = array()) + { + if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) + { + return $element['xml_base']; + } + elseif ($this->get_link() !== null) + { + return $this->get_link(); + } + else + { + return $this->subscribe_url(); + } + } + + function sanitize($data, $type, $base = '') + { + return $this->sanitize->sanitize($data, $type, $base); + } + + function get_title() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_channel_tags('', 'category') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->author_class($name, $uri, $email); + } + } + if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->author_class($name, $url, $email); + } + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if (isset($links[$key])) + { + return $links[$key]; + } + else + { + return null; + } + } + + /** + * Added for parity between the parent-level and the item/entry-level. + */ + function get_permalink() + { + return $this->get_link(0); + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_channel_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + function get_description() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags('', 'copyright')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_language() + { + if ($return = $this->get_channel_tags('', 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) + { + return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['headers']['content-language'])) + { + return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_image_title() + { + if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_image_url() + { + if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) + { + return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags('', 'url')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_image_link() + { + if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_image_tags('', 'link')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_image_width() + { + if ($return = $this->get_image_tags('', 'width')) + { + return round($return[0]['data']); + } + elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url')) + { + return 88.0; + } + else + { + return null; + } + } + + function get_image_height() + { + if ($return = $this->get_image_tags('', 'height')) + { + return round($return[0]['data']); + } + elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url')) + { + return 31.0; + } + else + { + return null; + } + } + + function get_item_quantity($max = 0) + { + $qty = count($this->get_items()); + if ($max == 0) + { + return $qty; + } + else + { + return ($qty > $max) ? $max : $qty; + } + } + + function get_item($key = 0) + { + $items = $this->get_items(); + if (isset($items[$key])) + { + return $items[$key]; + } + else + { + return null; + } + } + + function get_items($start = 0, $end = 0) + { + if (!empty($this->multifeed_objects)) + { + return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); + } + elseif (!isset($this->data['items'])) + { + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + if ($items = $this->get_channel_tags('', 'item')) + { + $keys = array_keys($items); + foreach ($keys as $key) + { + $this->data['items'][] =& new $this->item_class($this, $items[$key]); + } + } + } + + if (!empty($this->data['items'])) + { + // If we want to order it by date, check if all items have a date, and then sort it + if ($this->order_by_date) + { + if (!isset($this->data['ordered_items'])) + { + $do_sort = true; + foreach ($this->data['items'] as $item) + { + if (!$item->get_date('U')) + { + $do_sort = false; + break; + } + } + $item = null; + $this->data['ordered_items'] = $this->data['items']; + if ($do_sort) + { + usort($this->data['ordered_items'], array(&$this, 'sort_items')); + } + } + $items = $this->data['ordered_items']; + } + else + { + $items = $this->data['items']; + } + + // Slice the data as desired + if ($end == 0) + { + return array_slice($items, $start); + } + else + { + return array_slice($items, $start, $end); + } + } + else + { + return array(); + } + } + + function sort_items($a, $b) + { + return $a->get_date('U') <= $b->get_date('U'); + } + + function merge_items($urls, $start = 0, $end = 0, $limit = 0) + { + if (is_array($urls) && sizeof($urls) > 0) + { + $items = array(); + foreach ($urls as $arg) + { + if (is_a($arg, 'SimplePie')) + { + $items = array_merge($items, $arg->get_items(0, $limit)); + } + else + { + trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); + } + } + + $do_sort = true; + foreach ($items as $item) + { + if (!$item->get_date('U')) + { + $do_sort = false; + break; + } + } + $item = null; + if ($do_sort) + { + usort($items, array('SimplePie', 'sort_items')); + } + + if ($end == 0) + { + return array_slice($items, $start); + } + else + { + return array_slice($items, $start, $end); + } + } + else + { + trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); + return array(); + } + } +} + +class SimplePie_Item +{ + var $feed; + var $data = array(); + + function SimplePie_Item($feed, $data) + { + $this->feed = $feed; + $this->data = $data; + } + + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + unset($this->feed); + } + + function get_item_tags($namespace, $tag) + { + if (isset($this->data['child'][$namespace][$tag])) + { + return $this->data['child'][$namespace][$tag]; + } + else + { + return null; + } + } + + function get_base($element = array()) + { + return $this->feed->get_base($element); + } + + function sanitize($data, $type, $base = '') + { + return $this->feed->sanitize($data, $type, $base); + } + + function get_feed() + { + return $this->feed; + } + + function get_id($hash = false) + { + if (!$hash) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags('', 'guid')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (($return = $this->get_permalink()) !== null) + { + return $return; + } + elseif (($return = $this->get_title()) !== null) + { + return $return; + } + } + if ($this->get_permalink() !== null || $this->get_title() !== null) + { + return md5($this->get_permalink() . $this->get_title()); + } + else + { + return md5(serialize($this->data)); + } + } + + function get_title() + { + if (!isset($this->data['title'])) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags('', 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $this->data['title'] = null; + } + } + return $this->data['title']; + } + + function get_description($description_only = false) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (!$description_only) + { + return $this->get_content(true); + } + else + { + return null; + } + } + + function get_content($content_only = false) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif (!$content_only) + { + return $this->get_description(true); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_item_tags('', 'category') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->feed->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->feed->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + /** + * @todo Atom inheritance (item author, source author, feed author) + */ + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->feed->author_class($name, $uri, $email); + } + } + if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->feed->author_class($name, $url, $email); + } + } + if ($author = $this->get_item_tags('', 'author')) + { + $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) + { + return $authors; + } + elseif ($authors = $this->feed->get_authors()) + { + return $authors; + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_date($date_format = 'j F Y, g:i a') + { + if (!isset($this->data['date'])) + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags('', 'pubDate')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date')) + { + $this->data['date']['raw'] = $return[0]['data']; + } + + if (!empty($this->data['date']['raw'])) + { + $parser = SimplePie_Parse_Date::get(); + $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']); + } + else + { + $this->data['date'] = null; + } + } + if ($this->data['date']) + { + $date_format = (string) $date_format; + switch ($date_format) + { + case '': + return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT); + + case 'U': + return $this->data['date']['parsed']; + + default: + return date($date_format, $this->data['date']['parsed']); + } + } + else + { + return null; + } + } + + function get_local_date($date_format = '%c') + { + if (!$date_format) + { + return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (($date = $this->get_date('U')) !== null) + { + return strftime($date_format, $date); + } + else + { + return null; + } + } + + function get_permalink() + { + $link = $this->get_link(); + $enclosure = $this->get_enclosure(0); + if ($link !== null) + { + return $link; + } + elseif ($enclosure !== null) + { + return $enclosure->get_link(); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if ($links[$key] !== null) + { + return $links[$key]; + } + else + { + return null; + } + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_item_tags('', 'guid')) + { + if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true') + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + /** + * @todo Add ability to prefer one type of content over another (in a media group). + */ + function get_enclosure($key = 0, $prefer = null) + { + $enclosures = $this->get_enclosures(); + if (isset($enclosures[$key])) + { + return $enclosures[$key]; + } + else + { + return null; + } + } + + /** + * Grabs all available enclosures (podcasts, etc.) + * + * Supports the RSS tag, as well as Media RSS and iTunes RSS. + * + * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support. + * + * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). + * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists). + */ + function get_enclosures() + { + if (!isset($this->data['enclosures'])) + { + $this->data['enclosures'] = array(); + + // Elements + $captions_parent = null; + $categories_parent = null; + $copyrights_parent = null; + $credits_parent = null; + $description_parent = null; + $duration_parent = null; + $hashes_parent = null; + $keywords_parent = null; + $player_parent = null; + $ratings_parent = null; + $restrictions_parent = null; + $thumbnails_parent = null; + $title_parent = null; + + // Let's do the channel and item-level ones first, and just re-use them if we need to. + $parent = $this->get_feed(); + + // CAPTIONS + if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) + { + foreach ($captions as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + } + elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) + { + foreach ($captions as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + } + if (is_array($captions_parent)) + { + $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent)); + } + + // CATEGORIES + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category) + { + $term = null; + $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd'; + $label = null; + if (isset($category['attribs']['']['text'])) + { + $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + + if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'])) + { + foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory) + { + if (isset($subcategory['attribs']['']['text'])) + { + $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + } + if (is_array($categories_parent)) + { + $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + + // COPYRIGHT + if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) + { + $copyright_url = null; + $copyright_label = null; + if (isset($copyright[0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($copyright[0]['data'])) + { + $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) + { + $copyright_url = null; + $copyright_label = null; + if (isset($copyright[0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($copyright[0]['data'])) + { + $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + + // CREDITS + if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) + { + foreach ($credits as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + } + elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) + { + foreach ($credits as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + } + if (is_array($credits_parent)) + { + $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent)); + } + + // DESCRIPTION + if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) + { + if (isset($description_parent[0]['data'])) + { + $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) + { + if (isset($description_parent[0]['data'])) + { + $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + + // DURATION + if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration')) + { + $seconds = null; + $minutes = null; + $hours = null; + if (isset($duration_parent[0]['data'])) + { + $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + if (sizeof($temp) > 0) + { + (int) $seconds = array_pop($temp); + } + if (sizeof($temp) > 0) + { + (int) $minutes = array_pop($temp); + $seconds += $minutes * 60; + } + if (sizeof($temp) > 0) + { + (int) $hours = array_pop($temp); + $seconds += $hours * 3600; + } + unset($temp); + $duration_parent = $seconds; + } + } + + // HASHES + if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) + { + foreach ($hashes_iterator as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes_parent[] = $algo.':'.$value; + } + } + elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) + { + foreach ($hashes_iterator as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes_parent[] = $algo.':'.$value; + } + } + if (is_array($hashes_parent)) + { + $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent)); + } + + // KEYWORDS + if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) + { + if (isset($keywords[0]['data'])) + { + $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords_parent[] = trim($word); + } + } + unset($temp); + } + if (is_array($keywords_parent)) + { + $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent)); + } + + // PLAYER + if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) + { + if (isset($player_parent[0]['attribs']['']['url'])) + { + $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) + { + if (isset($player_parent[0]['attribs']['']['url'])) + { + $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + + // RATINGS + if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) + { + foreach ($ratings as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) + { + foreach ($ratings as $rating) + { + $rating_scheme = 'urn:itunes'; + $rating_value = null; + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) + { + foreach ($ratings as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) + { + foreach ($ratings as $rating) + { + $rating_scheme = 'urn:itunes'; + $rating_value = null; + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + } + if (is_array($ratings_parent)) + { + $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent)); + } + + // RESTRICTIONS + if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = 'allow'; + $restriction_type = null; + $restriction_value = 'itunes'; + if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes') + { + $restriction_relationship = 'deny'; + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) + { + foreach ($restrictions as $restriction) + { + $restriction_relationship = 'allow'; + $restriction_type = null; + $restriction_value = 'itunes'; + if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes') + { + $restriction_relationship = 'deny'; + } + $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + } + if (is_array($restrictions_parent)) + { + $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent)); + } + + // THUMBNAILS + if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) + { + foreach ($thumbnails as $thumbnail) + { + if (isset($thumbnail['attribs']['']['url'])) + { + $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) + { + foreach ($thumbnails as $thumbnail) + { + if (isset($thumbnail['attribs']['']['url'])) + { + $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + } + } + + // TITLES + if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) + { + if (isset($title_parent[0]['data'])) + { + $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) + { + if (isset($title_parent[0]['data'])) + { + $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + } + + // Clear the memory + unset($parent); + + // If we have media:group tags, loop through them. + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group) + { + // If we have media:content tags, loop through them. + foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) + { + if (isset($content['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + // Elements + $captions = null; + $categories = null; + $copyrights = null; + $credits = null; + $description = null; + $hashes = null; + $keywords = null; + $player = null; + $ratings = null; + $restrictions = null; + $thumbnails = null; + $title = null; + + // Start checking the attributes of media:content + if (isset($content['attribs']['']['bitrate'])) + { + $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['channels'])) + { + $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['duration'])) + { + $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $duration = $duration_parent; + } + if (isset($content['attribs']['']['expression'])) + { + $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['framerate'])) + { + $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['height'])) + { + $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['lang'])) + { + $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['fileSize'])) + { + $length = ceil($content['attribs']['']['fileSize']); + } + if (isset($content['attribs']['']['medium'])) + { + $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['samplingrate'])) + { + $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['type'])) + { + $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['width'])) + { + $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + + // Checking the other optional media: elements. Priority: media:content, media:group, item, channel + + // CAPTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + else + { + $captions = $captions_parent; + } + + // CATEGORIES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (is_array($categories) && is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); + } + elseif (is_array($categories)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories)); + } + elseif (is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + + // COPYRIGHTS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + else + { + $copyrights = $copyrights_parent; + } + + // CREDITS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + else + { + $credits = $credits_parent; + } + + // DESCRIPTION + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $description = $description_parent; + } + + // HASHES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + else + { + $hashes = $hashes_parent; + } + + // KEYWORDS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + else + { + $keywords = $keywords_parent; + } + + // PLAYER + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $player = $player_parent; + } + + // RATINGS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + else + { + $ratings = $ratings_parent; + } + + // RESTRICTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + else + { + $restrictions = $restrictions_parent; + } + + // THUMBNAILS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + else + { + $thumbnails = $thumbnails_parent; + } + + // TITLES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $title = $title_parent; + } + + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); + } + } + } + + // If we have standalone media:content tags, loop through them. + if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'])) + { + foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) + { + if (isset($content['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + // Elements + $captions = null; + $categories = null; + $copyrights = null; + $credits = null; + $description = null; + $hashes = null; + $keywords = null; + $player = null; + $ratings = null; + $restrictions = null; + $thumbnails = null; + $title = null; + + // Start checking the attributes of media:content + if (isset($content['attribs']['']['bitrate'])) + { + $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['channels'])) + { + $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['duration'])) + { + $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $duration = $duration_parent; + } + if (isset($content['attribs']['']['expression'])) + { + $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['framerate'])) + { + $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['height'])) + { + $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['lang'])) + { + $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['fileSize'])) + { + $length = ceil($content['attribs']['']['fileSize']); + } + if (isset($content['attribs']['']['medium'])) + { + $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['samplingrate'])) + { + $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['type'])) + { + $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['attribs']['']['width'])) + { + $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + + // Checking the other optional media: elements. Priority: media:content, media:group, item, channel + + // CAPTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) + { + $caption_type = null; + $caption_lang = null; + $caption_startTime = null; + $caption_endTime = null; + $caption_text = null; + if (isset($caption['attribs']['']['type'])) + { + $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['lang'])) + { + $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['start'])) + { + $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['attribs']['']['end'])) + { + $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($caption['data'])) + { + $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); + } + if (is_array($captions)) + { + $captions = array_values(SimplePie_Misc::array_unique($captions)); + } + } + else + { + $captions = $captions_parent; + } + + // CATEGORIES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) + { + foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['data'])) + { + $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $scheme = 'http://search.yahoo.com/mrss/category_schema'; + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->feed->category_class($term, $scheme, $label); + } + } + if (is_array($categories) && is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); + } + elseif (is_array($categories)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories)); + } + elseif (is_array($categories_parent)) + { + $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); + } + else + { + $categories = null; + } + + // COPYRIGHTS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) + { + $copyright_url = null; + $copyright_label = null; + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) + { + $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) + { + $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); + } + else + { + $copyrights = $copyrights_parent; + } + + // CREDITS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) + { + $credit_role = null; + $credit_scheme = null; + $credit_name = null; + if (isset($credit['attribs']['']['role'])) + { + $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($credit['attribs']['']['scheme'])) + { + $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $credit_scheme = 'urn:ebu'; + } + if (isset($credit['data'])) + { + $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); + } + if (is_array($credits)) + { + $credits = array_values(SimplePie_Misc::array_unique($credits)); + } + } + else + { + $credits = $credits_parent; + } + + // DESCRIPTION + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) + { + $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $description = $description_parent; + } + + // HASHES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) + { + $value = null; + $algo = null; + if (isset($hash['data'])) + { + $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($hash['attribs']['']['algo'])) + { + $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $algo = 'md5'; + } + $hashes[] = $algo.':'.$value; + } + if (is_array($hashes)) + { + $hashes = array_values(SimplePie_Misc::array_unique($hashes)); + } + } + else + { + $hashes = $hashes_parent; + } + + // KEYWORDS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) + { + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) + { + $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); + foreach ($temp as $word) + { + $keywords[] = trim($word); + } + unset($temp); + } + if (is_array($keywords)) + { + $keywords = array_values(SimplePie_Misc::array_unique($keywords)); + } + } + else + { + $keywords = $keywords_parent; + } + + // PLAYER + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) + { + $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + else + { + $player = $player_parent; + } + + // RATINGS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) + { + $rating_scheme = null; + $rating_value = null; + if (isset($rating['attribs']['']['scheme'])) + { + $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $rating_scheme = 'urn:simple'; + } + if (isset($rating['data'])) + { + $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); + } + if (is_array($ratings)) + { + $ratings = array_values(SimplePie_Misc::array_unique($ratings)); + } + } + else + { + $ratings = $ratings_parent; + } + + // RESTRICTIONS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) + { + $restriction_relationship = null; + $restriction_type = null; + $restriction_value = null; + if (isset($restriction['attribs']['']['relationship'])) + { + $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['attribs']['']['type'])) + { + $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($restriction['data'])) + { + $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); + } + if (is_array($restrictions)) + { + $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); + } + } + else + { + $restrictions = $restrictions_parent; + } + + // THUMBNAILS + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) + { + foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) + { + $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); + } + if (is_array($thumbnails)) + { + $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); + } + } + else + { + $thumbnails = $thumbnails_parent; + } + + // TITLES + if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) + { + $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + $title = $title_parent; + } + + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); + } + } + } + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) + { + if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure') + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + if (isset($link['attribs']['']['type'])) + { + $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($link['attribs']['']['length'])) + { + $length = ceil($link['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) + { + if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure') + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + if (isset($link['attribs']['']['type'])) + { + $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($link['attribs']['']['length'])) + { + $length = ceil($link['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + if ($enclosure = $this->get_item_tags('', 'enclosure')) + { + if (isset($enclosure[0]['attribs']['']['url'])) + { + // Attributes + $bitrate = null; + $channels = null; + $duration = null; + $expression = null; + $framerate = null; + $height = null; + $javascript = null; + $lang = null; + $length = null; + $medium = null; + $samplingrate = null; + $type = null; + $url = null; + $width = null; + + $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); + if (isset($enclosure[0]['attribs']['']['type'])) + { + $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($enclosure[0]['attribs']['']['length'])) + { + $length = ceil($enclosure[0]['attribs']['']['length']); + } + + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + } + + if (sizeof($this->data['enclosures']) == 0) + { + // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor + $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); + } + + $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures'])); + } + if (!empty($this->data['enclosures'])) + { + return $this->data['enclosures']; + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_source() + { + if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source')) + { + return new $this->feed->source_class($this, $return[0]); + } + else + { + return null; + } + } + + /** + * Creates the add_to_* methods' return data + * + * @access private + * @param string $item_url String to prefix to the item permalink + * @param string $title_url String to prefix to the item title + * (and suffix to the item permalink) + * @return mixed URL if feed exists, false otherwise + */ + function add_to_service($item_url, $title_url = null) + { + if ($this->get_permalink() !== null) + { + $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink()); + if ($title_url !== null && $this->get_title() !== null) + { + $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title()); + } + return $return; + } + else + { + return null; + } + } + + function add_to_blinklist() + { + return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title='); + } + + function add_to_blogmarks() + { + return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title='); + } + + function add_to_delicious() + { + return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title='); + } + + function add_to_digg() + { + return $this->add_to_service('http://digg.com/submit?phase=2&URL='); + } + + function add_to_furl() + { + return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t='); + } + + function add_to_magnolia() + { + return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title='); + } + + function add_to_myweb20() + { + return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t='); + } + + function add_to_newsvine() + { + return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h='); + } + + function add_to_reddit() + { + return $this->add_to_service('http://reddit.com/submit?url=', '&title='); + } + + function add_to_segnalo() + { + return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title='); + } + + function add_to_simpy() + { + return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title='); + } + + function add_to_spurl() + { + return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title='); + } + + function add_to_wists() + { + return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title='); + } + + function search_technorati() + { + return $this->add_to_service('http://www.technorati.com/search/'); + } +} + +class SimplePie_Source +{ + var $item; + var $data = array(); + + function SimplePie_Source($item, $data) + { + $this->item = $item; + $this->data = $data; + } + + function __toString() + { + return md5(serialize($this->data)); + } + + /** + * Remove items that link back to this before destroying this object + */ + function __destruct() + { + unset($this->item); + } + + function get_source_tags($namespace, $tag) + { + if (isset($this->data['child'][$namespace][$tag])) + { + return $this->data['child'][$namespace][$tag]; + } + else + { + return null; + } + } + + function get_base($element = array()) + { + return $this->item->get_base($element); + } + + function sanitize($data, $type, $base = '') + { + return $this->item->sanitize($data, $type, $base); + } + + function get_item() + { + return $this->item; + } + + function get_title() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + $categories = array(); + + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) + { + $term = null; + $scheme = null; + $label = null; + if (isset($category['attribs']['']['term'])) + { + $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['scheme'])) + { + $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($category['attribs']['']['label'])) + { + $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); + } + $categories[] =& new $this->item->feed->category_class($term, $scheme, $label); + } + foreach ((array) $this->get_source_tags('', 'category') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) + { + $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($categories)) + { + return SimplePie_Misc::array_unique($categories); + } + else + { + return null; + } + } + + function get_author($key = 0) + { + $authors = $this->get_authors(); + if (isset($authors[$key])) + { + return $authors[$key]; + } + else + { + return null; + } + } + + function get_authors() + { + $authors = array(); + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) + { + $name = null; + $uri = null; + $email = null; + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $authors[] =& new $this->item->feed->author_class($name, $uri, $email); + } + } + if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) + { + $name = null; + $url = null; + $email = null; + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $authors[] =& new $this->item->feed->author_class($name, $url, $email); + } + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) + { + $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); + } + + if (!empty($authors)) + { + return SimplePie_Misc::array_unique($authors); + } + else + { + return null; + } + } + + function get_contributor($key = 0) + { + $contributors = $this->get_contributors(); + if (isset($contributors[$key])) + { + return $contributors[$key]; + } + else + { + return null; + } + } + + function get_contributors() + { + $contributors = array(); + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) + { + $name = null; + $uri = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) + { + $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $uri !== null) + { + $contributors[] =& new $this->item->feed->author_class($name, $uri, $email); + } + } + foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) + { + $name = null; + $url = null; + $email = null; + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) + { + $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) + { + $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); + } + if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) + { + $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + if ($name !== null || $email !== null || $url !== null) + { + $contributors[] =& new $this->item->feed->author_class($name, $url, $email); + } + } + + if (!empty($contributors)) + { + return SimplePie_Misc::array_unique($contributors); + } + else + { + return null; + } + } + + function get_link($key = 0, $rel = 'alternate') + { + $links = $this->get_links($rel); + if (isset($links[$key])) + { + return $links[$key]; + } + else + { + return null; + } + } + + /** + * Added for parity between the parent-level and the item/entry-level. + */ + function get_permalink() + { + return $this->get_link(0); + } + + function get_links($rel = 'alternate') + { + if (!isset($this->data['links'])) + { + $this->data['links'] = array(); + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + } + } + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) + { + foreach ($links as $link) + { + if (isset($link['attribs']['']['href'])) + { + $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; + $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); + + } + } + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + if ($links = $this->get_source_tags('', 'link')) + { + $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); + } + + $keys = array_keys($this->data['links']); + foreach ($keys as $key) + { + if (SimplePie_Misc::is_isegment_nz_nc($key)) + { + if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); + $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; + } + else + { + $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; + } + } + elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) + { + $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; + } + $this->data['links'][$key] = array_unique($this->data['links'][$key]); + } + } + + if (isset($this->data['links'][$rel])) + { + return $this->data['links'][$rel]; + } + else + { + return null; + } + } + + function get_description() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); + } + else + { + return null; + } + } + + function get_copyright() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) + { + return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags('', 'copyright')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_language() + { + if ($return = $this->get_source_tags('', 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); + } + elseif (isset($this->data['xml_lang'])) + { + return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); + } + else + { + return null; + } + } + + function get_latitude() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[1]; + } + else + { + return null; + } + } + + function get_longitude() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) + { + return (float) $return[0]['data']; + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) + { + return (float) $return[0]['data']; + } + elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) + { + return (float) $match[2]; + } + else + { + return null; + } + } + + function get_image_url() + { + if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) + { + return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) + { + return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); + } + else + { + return null; + } + } +} + +class SimplePie_Author +{ + var $name; + var $link; + var $email; + + // Constructor, used to input the data + function SimplePie_Author($name = null, $link = null, $email = null) + { + $this->name = $name; + $this->link = $link; + $this->email = $email; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_name() + { + if ($this->name !== null) + { + return $this->name; + } + else + { + return null; + } + } + + function get_link() + { + if ($this->link !== null) + { + return $this->link; + } + else + { + return null; + } + } + + function get_email() + { + if ($this->email !== null) + { + return $this->email; + } + else + { + return null; + } + } +} + +class SimplePie_Category +{ + var $term; + var $scheme; + var $label; + + // Constructor, used to input the data + function SimplePie_Category($term = null, $scheme = null, $label = null) + { + $this->term = $term; + $this->scheme = $scheme; + $this->label = $label; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_term() + { + if ($this->term !== null) + { + return $this->term; + } + else + { + return null; + } + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_label() + { + if ($this->label !== null) + { + return $this->label; + } + else + { + return $this->get_term(); + } + } +} + +class SimplePie_Enclosure +{ + var $bitrate; + var $captions; + var $categories; + var $channels; + var $copyright; + var $credits; + var $description; + var $duration; + var $expression; + var $framerate; + var $handler; + var $hashes; + var $height; + var $javascript; + var $keywords; + var $lang; + var $length; + var $link; + var $medium; + var $player; + var $ratings; + var $restrictions; + var $samplingrate; + var $thumbnails; + var $title; + var $type; + var $width; + + // Constructor, used to input the data + function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null) + { + $this->bitrate = $bitrate; + $this->captions = $captions; + $this->categories = $categories; + $this->channels = $channels; + $this->copyright = $copyright; + $this->credits = $credits; + $this->description = $description; + $this->duration = $duration; + $this->expression = $expression; + $this->framerate = $framerate; + $this->hashes = $hashes; + $this->height = $height; + $this->javascript = $javascript; + $this->keywords = $keywords; + $this->lang = $lang; + $this->length = $length; + $this->link = $link; + $this->medium = $medium; + $this->player = $player; + $this->ratings = $ratings; + $this->restrictions = $restrictions; + $this->samplingrate = $samplingrate; + $this->thumbnails = $thumbnails; + $this->title = $title; + $this->type = $type; + $this->width = $width; + if (class_exists('idna_convert')) + { + $idn =& new idna_convert; + $parsed = SimplePie_Misc::parse_url($link); + $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); + } + $this->handler = $this->get_handler(); // Needs to load last + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_bitrate() + { + if ($this->bitrate !== null) + { + return $this->bitrate; + } + else + { + return null; + } + } + + function get_caption($key = 0) + { + $captions = $this->get_captions(); + if (isset($captions[$key])) + { + return $captions[$key]; + } + else + { + return null; + } + } + + function get_captions() + { + if ($this->captions !== null) + { + return $this->captions; + } + else + { + return null; + } + } + + function get_category($key = 0) + { + $categories = $this->get_categories(); + if (isset($categories[$key])) + { + return $categories[$key]; + } + else + { + return null; + } + } + + function get_categories() + { + if ($this->categories !== null) + { + return $this->categories; + } + else + { + return null; + } + } + + function get_channels() + { + if ($this->channels !== null) + { + return $this->channels; + } + else + { + return null; + } + } + + function get_copyright() + { + if ($this->copyright !== null) + { + return $this->copyright; + } + else + { + return null; + } + } + + function get_credit($key = 0) + { + $credits = $this->get_credits(); + if (isset($credits[$key])) + { + return $credits[$key]; + } + else + { + return null; + } + } + + function get_credits() + { + if ($this->credits !== null) + { + return $this->credits; + } + else + { + return null; + } + } + + function get_description() + { + if ($this->description !== null) + { + return $this->description; + } + else + { + return null; + } + } + + function get_duration($convert = false) + { + if ($this->duration !== null) + { + if ($convert) + { + $time = SimplePie_Misc::time_hms($this->duration); + return $time; + } + else + { + return $this->duration; + } + } + else + { + return null; + } + } + + function get_expression() + { + if ($this->expression !== null) + { + return $this->expression; + } + else + { + return 'full'; + } + } + + function get_extension() + { + if ($this->link !== null) + { + $url = SimplePie_Misc::parse_url($this->link); + if ($url['path'] !== '') + { + return pathinfo($url['path'], PATHINFO_EXTENSION); + } + } + return null; + } + + function get_framerate() + { + if ($this->framerate !== null) + { + return $this->framerate; + } + else + { + return null; + } + } + + function get_handler() + { + return $this->get_real_type(true); + } + + function get_hash($key = 0) + { + $hashes = $this->get_hashes(); + if (isset($hashes[$key])) + { + return $hashes[$key]; + } + else + { + return null; + } + } + + function get_hashes() + { + if ($this->hashes !== null) + { + return $this->hashes; + } + else + { + return null; + } + } + + function get_height() + { + if ($this->height !== null) + { + return $this->height; + } + else + { + return null; + } + } + + function get_language() + { + if ($this->lang !== null) + { + return $this->lang; + } + else + { + return null; + } + } + + function get_keyword($key = 0) + { + $keywords = $this->get_keywords(); + if (isset($keywords[$key])) + { + return $keywords[$key]; + } + else + { + return null; + } + } + + function get_keywords() + { + if ($this->keywords !== null) + { + return $this->keywords; + } + else + { + return null; + } + } + + function get_length() + { + if ($this->length !== null) + { + return $this->length; + } + else + { + return null; + } + } + + function get_link() + { + if ($this->link !== null) + { + return urldecode($this->link); + } + else + { + return null; + } + } + + function get_medium() + { + if ($this->medium !== null) + { + return $this->medium; + } + else + { + return null; + } + } + + function get_player() + { + if ($this->player !== null) + { + return $this->player; + } + else + { + return null; + } + } + + function get_rating($key = 0) + { + $ratings = $this->get_ratings(); + if (isset($ratings[$key])) + { + return $ratings[$key]; + } + else + { + return null; + } + } + + function get_ratings() + { + if ($this->ratings !== null) + { + return $this->ratings; + } + else + { + return null; + } + } + + function get_restriction($key = 0) + { + $restrictions = $this->get_restrictions(); + if (isset($restrictions[$key])) + { + return $restrictions[$key]; + } + else + { + return null; + } + } + + function get_restrictions() + { + if ($this->restrictions !== null) + { + return $this->restrictions; + } + else + { + return null; + } + } + + function get_sampling_rate() + { + if ($this->samplingrate !== null) + { + return $this->samplingrate; + } + else + { + return null; + } + } + + function get_size() + { + $length = $this->get_length(); + if ($length !== null) + { + return round($length/1048576, 2); + } + else + { + return null; + } + } + + function get_thumbnail($key = 0) + { + $thumbnails = $this->get_thumbnails(); + if (isset($thumbnails[$key])) + { + return $thumbnails[$key]; + } + else + { + return null; + } + } + + function get_thumbnails() + { + if ($this->thumbnails !== null) + { + return $this->thumbnails; + } + else + { + return null; + } + } + + function get_title() + { + if ($this->title !== null) + { + return $this->title; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } + + function get_width() + { + if ($this->width !== null) + { + return $this->width; + } + else + { + return null; + } + } + + function native_embed($options='') + { + return $this->embed($options, true); + } + + /** + * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'. + */ + function embed($options = '', $native = false) + { + // Set up defaults + $audio = ''; + $video = ''; + $alt = ''; + $altclass = ''; + $loop = 'false'; + $width = 'auto'; + $height = 'auto'; + $bgcolor = '#ffffff'; + $mediaplayer = ''; + $widescreen = false; + $handler = $this->get_handler(); + $type = $this->get_real_type(); + + // Process options and reassign values as necessary + if (is_array($options)) + { + extract($options); + } + else + { + $options = explode(',', $options); + foreach($options as $option) + { + $opt = explode(':', $option, 2); + if (isset($opt[0], $opt[1])) + { + $opt[0] = trim($opt[0]); + $opt[1] = trim($opt[1]); + switch ($opt[0]) + { + case 'audio': + $audio = $opt[1]; + break; + + case 'video': + $video = $opt[1]; + break; + + case 'alt': + $alt = $opt[1]; + break; + + case 'altclass': + $altclass = $opt[1]; + break; + + case 'loop': + $loop = $opt[1]; + break; + + case 'width': + $width = $opt[1]; + break; + + case 'height': + $height = $opt[1]; + break; + + case 'bgcolor': + $bgcolor = $opt[1]; + break; + + case 'mediaplayer': + $mediaplayer = $opt[1]; + break; + + case 'widescreen': + $widescreen = $opt[1]; + break; + } + } + } + } + + $mime = explode('/', $type, 2); + $mime = $mime[0]; + + // Process values for 'auto' + if ($width == 'auto') + { + if ($mime == 'video') + { + if ($height == 'auto') + { + $width = 480; + } + elseif ($widescreen) + { + $width = round((intval($height)/9)*16); + } + else + { + $width = round((intval($height)/3)*4); + } + } + else + { + $width = '100%'; + } + } + + if ($height == 'auto') + { + if ($mime == 'audio') + { + $height = 0; + } + elseif ($mime == 'video') + { + if ($width == 'auto') + { + if ($widescreen) + { + $height = 270; + } + else + { + $height = 360; + } + } + elseif ($widescreen) + { + $height = round((intval($width)/16)*9); + } + else + { + $height = round((intval($width)/4)*3); + } + } + else + { + $height = 376; + } + } + elseif ($mime == 'audio') + { + $height = 0; + } + + // Set proper placeholder value + if ($mime == 'audio') + { + $placeholder = $audio; + } + elseif ($mime == 'video') + { + $placeholder = $video; + } + + $embed = ''; + + // Make sure the JS library is included + if (!$native) + { + static $javascript_outputted = null; + if (!$javascript_outputted && $this->javascript) + { + $embed .= ''; + $javascript_outputted = true; + } + } + + // Odeo Feed MP3's + if ($handler == 'odeo') + { + if ($native) + { + $embed .= ''; + } + else + { + $embed .= ''; + } + } + + // Flash + elseif ($handler == 'flash') + { + if ($native) + { + $embed .= "get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\">"; + } + else + { + $embed .= ""; + } + } + + // Flash Media Player file types. + // Preferred handler for MP3 file types. + elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != '')) + { + $height += 20; + if ($native) + { + $embed .= "get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\">"; + } + else + { + $embed .= ""; + } + } + + // QuickTime 7 file types. Need to test with QuickTime 6. + // Only handle MP3's if the Flash Media Player is not present. + elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == '')) + { + $height += 16; + if ($native) + { + if ($placeholder != ""){ + $embed .= "get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\">"; + } + else { + $embed .= "get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\">"; + } + } + else + { + $embed .= ""; + } + } + + // Windows Media + elseif ($handler == 'wmedia') + { + $height += 45; + if ($native) + { + $embed .= "get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\">"; + } + else + { + $embed .= ""; + } + } + + // Everything else + else $embed .= '' . $alt . ''; + + return $embed; + } + + function get_real_type($find_handler = false) + { + // If it's Odeo, let's get it out of the way. + if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com') + { + return 'odeo'; + } + + // Mime-types by handler. + $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash + $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player + $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime + $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media + $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3 + + if ($this->get_type() !== null) + { + $type = strtolower($this->type); + } + else + { + $type = null; + } + + // If we encounter an unsupported mime-type, check the file extension and guess intelligently. + if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) + { + switch (strtolower($this->get_extension())) + { + // Audio mime-types + case 'aac': + case 'adts': + $type = 'audio/acc'; + break; + + case 'aif': + case 'aifc': + case 'aiff': + case 'cdda': + $type = 'audio/aiff'; + break; + + case 'bwf': + $type = 'audio/wav'; + break; + + case 'kar': + case 'mid': + case 'midi': + case 'smf': + $type = 'audio/midi'; + break; + + case 'm4a': + $type = 'audio/x-m4a'; + break; + + case 'mp3': + case 'swa': + $type = 'audio/mp3'; + break; + + case 'wav': + $type = 'audio/wav'; + break; + + case 'wax': + $type = 'audio/x-ms-wax'; + break; + + case 'wma': + $type = 'audio/x-ms-wma'; + break; + + // Video mime-types + case '3gp': + case '3gpp': + $type = 'video/3gpp'; + break; + + case '3g2': + case '3gp2': + $type = 'video/3gpp2'; + break; + + case 'asf': + $type = 'video/x-ms-asf'; + break; + + case 'flv': + $type = 'video/x-flv'; + break; + + case 'm1a': + case 'm1s': + case 'm1v': + case 'm15': + case 'm75': + case 'mp2': + case 'mpa': + case 'mpeg': + case 'mpg': + case 'mpm': + case 'mpv': + $type = 'video/mpeg'; + break; + + case 'm4v': + $type = 'video/x-m4v'; + break; + + case 'mov': + case 'qt': + $type = 'video/quicktime'; + break; + + case 'mp4': + case 'mpg4': + $type = 'video/mp4'; + break; + + case 'sdv': + $type = 'video/sd-video'; + break; + + case 'wm': + $type = 'video/x-ms-wm'; + break; + + case 'wmv': + $type = 'video/x-ms-wmv'; + break; + + case 'wvx': + $type = 'video/x-ms-wvx'; + break; + + // Flash mime-types + case 'spl': + $type = 'application/futuresplash'; + break; + + case 'swf': + $type = 'application/x-shockwave-flash'; + break; + } + } + + if ($find_handler) + { + if (in_array($type, $types_flash)) + { + return 'flash'; + } + elseif (in_array($type, $types_fmedia)) + { + return 'fmedia'; + } + elseif (in_array($type, $types_quicktime)) + { + return 'quicktime'; + } + elseif (in_array($type, $types_wmedia)) + { + return 'wmedia'; + } + elseif (in_array($type, $types_mp3)) + { + return 'mp3'; + } + else + { + return null; + } + } + else + { + return $type; + } + } +} + +class SimplePie_Caption +{ + var $type; + var $lang; + var $startTime; + var $endTime; + var $text; + + // Constructor, used to input the data + function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null) + { + $this->type = $type; + $this->lang = $lang; + $this->startTime = $startTime; + $this->endTime = $endTime; + $this->text = $text; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_endtime() + { + if ($this->endTime !== null) + { + return $this->endTime; + } + else + { + return null; + } + } + + function get_language() + { + if ($this->lang !== null) + { + return $this->lang; + } + else + { + return null; + } + } + + function get_starttime() + { + if ($this->startTime !== null) + { + return $this->startTime; + } + else + { + return null; + } + } + + function get_text() + { + if ($this->text !== null) + { + return $this->text; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } +} + +class SimplePie_Credit +{ + var $role; + var $scheme; + var $name; + + // Constructor, used to input the data + function SimplePie_Credit($role = null, $scheme = null, $name = null) + { + $this->role = $role; + $this->scheme = $scheme; + $this->name = $name; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_role() + { + if ($this->role !== null) + { + return $this->role; + } + else + { + return null; + } + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_name() + { + if ($this->name !== null) + { + return $this->name; + } + else + { + return null; + } + } +} + +class SimplePie_Copyright +{ + var $url; + var $label; + + // Constructor, used to input the data + function SimplePie_Copyright($url = null, $label = null) + { + $this->url = $url; + $this->label = $label; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_url() + { + if ($this->url !== null) + { + return $this->url; + } + else + { + return null; + } + } + + function get_attribution() + { + if ($this->label !== null) + { + return $this->label; + } + else + { + return null; + } + } +} + +class SimplePie_Rating +{ + var $scheme; + var $value; + + // Constructor, used to input the data + function SimplePie_Rating($scheme = null, $value = null) + { + $this->scheme = $scheme; + $this->value = $value; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_scheme() + { + if ($this->scheme !== null) + { + return $this->scheme; + } + else + { + return null; + } + } + + function get_value() + { + if ($this->value !== null) + { + return $this->value; + } + else + { + return null; + } + } +} + +class SimplePie_Restriction +{ + var $relationship; + var $type; + var $value; + + // Constructor, used to input the data + function SimplePie_Restriction($relationship = null, $type = null, $value = null) + { + $this->relationship = $relationship; + $this->type = $type; + $this->value = $value; + } + + function __toString() + { + // There is no $this->data here + return md5(serialize($this)); + } + + function get_relationship() + { + if ($this->relationship !== null) + { + return $this->relationship; + } + else + { + return null; + } + } + + function get_type() + { + if ($this->type !== null) + { + return $this->type; + } + else + { + return null; + } + } + + function get_value() + { + if ($this->value !== null) + { + return $this->value; + } + else + { + return null; + } + } +} + +/** + * @todo Move to properly supporting RFC2616 (HTTP/1.1) + */ +class SimplePie_File +{ + var $url; + var $useragent; + var $success = true; + var $headers = array(); + var $body; + var $status_code; + var $redirects = 0; + var $error; + var $method = SIMPLEPIE_FILE_SOURCE_NONE; + + function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) + { + if (class_exists('idna_convert')) + { + $idn =& new idna_convert; + $parsed = SimplePie_Misc::parse_url($url); + $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); + } + $this->url = $url; + $this->useragent = $useragent; + if (preg_match('/^http(s)?:\/\//i', $url)) + { + if ($useragent === null) + { + $useragent = ini_get('user_agent'); + $this->useragent = $useragent; + } + if (!is_array($headers)) + { + $headers = array(); + } + if (!$force_fsockopen && function_exists('curl_exec')) + { + $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; + $fp = curl_init(); + $headers2 = array(); + foreach ($headers as $key => $value) + { + $headers2[] = "$key: $value"; + } + if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) + { + curl_setopt($fp, CURLOPT_ENCODING, ''); + } + curl_setopt($fp, CURLOPT_URL, $url); + curl_setopt($fp, CURLOPT_HEADER, 1); + curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); + curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); + curl_setopt($fp, CURLOPT_REFERER, $url); + curl_setopt($fp, CURLOPT_USERAGENT, $useragent); + curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); + if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) + { + curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); + } + + $this->headers = curl_exec($fp); + if (curl_errno($fp) == 23 || curl_errno($fp) == 61) + { + curl_setopt($fp, CURLOPT_ENCODING, 'none'); + $this->headers = curl_exec($fp); + } + if (curl_errno($fp)) + { + $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); + $this->success = false; + } + else + { + $info = curl_getinfo($fp); + curl_close($fp); + $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); + $this->headers = array_pop($this->headers); + $parser =& new SimplePie_HTTP_Parser($this->headers); + if ($parser->parse()) + { + $this->headers = $parser->headers; + $this->body = $parser->body; + $this->status_code = $parser->status_code; + if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) + { + $this->redirects++; + $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); + return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + } + } + } + } + else + { + $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN; + $url_parts = parse_url($url); + if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https') + { + $url_parts['host'] = "ssl://$url_parts[host]"; + $url_parts['port'] = 443; + } + if (!isset($url_parts['port'])) + { + $url_parts['port'] = 80; + } + $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout); + if (!$fp) + { + $this->error = 'fsockopen error: ' . $errstr; + $this->success = false; + } + else + { + stream_set_timeout($fp, $timeout); + if (isset($url_parts['path'])) + { + if (isset($url_parts['query'])) + { + $get = "$url_parts[path]?$url_parts[query]"; + } + else + { + $get = $url_parts['path']; + } + } + else + { + $get = '/'; + } + $out = "GET $get HTTP/1.0\r\n"; + $out .= "Host: $url_parts[host]\r\n"; + $out .= "User-Agent: $useragent\r\n"; + if (function_exists('gzinflate')) + { + $out .= "Accept-Encoding: gzip,deflate\r\n"; + } + + if (isset($url_parts['user']) && isset($url_parts['pass'])) + { + $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n"; + } + foreach ($headers as $key => $value) + { + $out .= "$key: $value\r\n"; + } + $out .= "Connection: Close\r\n\r\n"; + fwrite($fp, $out); + + $info = stream_get_meta_data($fp); + + $this->headers = ''; + while (!$info['eof'] && !$info['timed_out']) + { + $this->headers .= fread($fp, 1160); + $info = stream_get_meta_data($fp); + } + if (!$info['timed_out']) + { + $parser =& new SimplePie_HTTP_Parser($this->headers); + if ($parser->parse()) + { + $this->headers = $parser->headers; + $this->body = $parser->body; + $this->status_code = $parser->status_code; + if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) + { + $this->redirects++; + $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); + return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + } + if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate')) + { + if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00") + { + $this->body = substr($this->body, 10); + } + $this->body = gzinflate($this->body); + } + } + } + else + { + $this->error = 'fsocket timed out'; + $this->success = false; + } + fclose($fp); + } + } + } + else + { + $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; + if (!$this->body = file_get_contents($url)) + { + $this->error = 'file_get_contents could not read the file'; + $this->success = false; + } + } + } +} + +/** + * HTTP Response Parser + * + * @package SimplePie + */ +class SimplePie_HTTP_Parser +{ + /** + * HTTP Version + * + * @access public + * @var float + */ + var $http_version = 0.0; + + /** + * Status code + * + * @access public + * @var int + */ + var $status_code = 0; + + /** + * Reason phrase + * + * @access public + * @var string + */ + var $reason = ''; + + /** + * Key/value pairs of the headers + * + * @access public + * @var array + */ + var $headers = array(); + + /** + * Body of the response + * + * @access public + * @var string + */ + var $body = ''; + + /** + * Current state of the state machine + * + * @access private + * @var string + */ + var $state = 'http_version'; + + /** + * Input data + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Input data length (to avoid calling strlen() everytime this is needed) + * + * @access private + * @var int + */ + var $data_length = 0; + + /** + * Current position of the pointer + * + * @var int + * @access private + */ + var $position = 0; + + /** + * Name of the hedaer currently being parsed + * + * @access private + * @var string + */ + var $name = ''; + + /** + * Value of the hedaer currently being parsed + * + * @access private + * @var string + */ + var $value = ''; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_HTTP_Parser($data) + { + $this->data = $data; + $this->data_length = strlen($this->data); + } + + /** + * Parse the input data + * + * @access public + * @return bool true on success, false on failure + */ + function parse() + { + while ($this->state && $this->state !== 'emit' && $this->has_data()) + { + $state = $this->state; + $this->$state(); + } + $this->data = ''; + if ($this->state === 'emit') + { + return true; + } + else + { + $this->http_version = ''; + $this->status_code = ''; + $this->reason = ''; + $this->headers = array(); + $this->body = ''; + return false; + } + } + + /** + * Check whether there is data beyond the pointer + * + * @access private + * @return bool true if there is further data, false if not + */ + function has_data() + { + return (bool) ($this->position < $this->data_length); + } + + /** + * See if the next character is LWS + * + * @access private + * @return bool true if the next character is LWS, false if not + */ + function is_linear_whitespace() + { + return (bool) ($this->data[$this->position] === "\x09" + || $this->data[$this->position] === "\x20" + || ($this->data[$this->position] === "\x0A" + && isset($this->data[$this->position + 1]) + && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20"))); + } + + /** + * Parse the HTTP version + * + * @access private + */ + function http_version() + { + if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/') + { + $len = strspn($this->data, '0123456789.', 5); + $this->http_version = substr($this->data, 5, $len); + $this->position += 5 + $len; + if (substr_count($this->http_version, '.') <= 1) + { + $this->http_version = (float) $this->http_version; + $this->position += strspn($this->data, "\x09\x20", $this->position); + $this->state = 'status'; + } + else + { + $this->state = false; + } + } + else + { + $this->state = false; + } + } + + /** + * Parse the status code + * + * @access private + */ + function status() + { + if ($len = strspn($this->data, '0123456789', $this->position)) + { + $this->status_code = (int) substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'reason'; + } + else + { + $this->state = false; + } + } + + /** + * Parse the reason phrase + * + * @access private + */ + function reason() + { + $len = strcspn($this->data, "\x0A", $this->position); + $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20"); + $this->position += $len + 1; + $this->state = 'new_line'; + } + + /** + * Deal with a new line, shifting data around as needed + * + * @access private + */ + function new_line() + { + $this->value = trim($this->value, "\x0D\x20"); + if ($this->name !== '' && $this->value !== '') + { + $this->name = strtolower($this->name); + if (isset($this->headers[$this->name])) + { + $this->headers[$this->name] .= ', ' . $this->value; + } + else + { + $this->headers[$this->name] = $this->value; + } + } + $this->name = ''; + $this->value = ''; + if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A") + { + $this->position += 2; + $this->state = 'body'; + } + elseif ($this->data[$this->position] === "\x0A") + { + $this->position++; + $this->state = 'body'; + } + else + { + $this->state = 'name'; + } + } + + /** + * Parse a header name + * + * @access private + */ + function name() + { + $len = strcspn($this->data, "\x0A:", $this->position); + if (isset($this->data[$this->position + $len])) + { + if ($this->data[$this->position + $len] === "\x0A") + { + $this->position += $len; + $this->state = 'new_line'; + } + else + { + $this->name = substr($this->data, $this->position, $len); + $this->position += $len + 1; + $this->state = 'value'; + } + } + else + { + $this->state = false; + } + } + + /** + * Parse LWS, replacing consecutive LWS characters with a single space + * + * @access private + */ + function linear_whitespace() + { + do + { + if (substr($this->data, $this->position, 2) === "\x0D\x0A") + { + $this->position += 2; + } + elseif ($this->data[$this->position] === "\x0A") + { + $this->position++; + } + $this->position += strspn($this->data, "\x09\x20", $this->position); + } while ($this->has_data() && $this->is_linear_whitespace()); + $this->value .= "\x20"; + } + + /** + * See what state to move to while within non-quoted header values + * + * @access private + */ + function value() + { + if ($this->is_linear_whitespace()) + { + $this->linear_whitespace(); + } + else + { + switch ($this->data[$this->position]) + { + case '"': + $this->position++; + $this->state = 'quote'; + break; + + case "\x0A": + $this->position++; + $this->state = 'new_line'; + break; + + default: + $this->state = 'value_char'; + break; + } + } + } + + /** + * Parse a header value while outside quotes + * + * @access private + */ + function value_char() + { + $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position); + $this->value .= substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'value'; + } + + /** + * See what state to move to while within quoted header values + * + * @access private + */ + function quote() + { + if ($this->is_linear_whitespace()) + { + $this->linear_whitespace(); + } + else + { + switch ($this->data[$this->position]) + { + case '"': + $this->position++; + $this->state = 'value'; + break; + + case "\x0A": + $this->position++; + $this->state = 'new_line'; + break; + + case '\\': + $this->position++; + $this->state = 'quote_escaped'; + break; + + default: + $this->state = 'quote_char'; + break; + } + } + } + + /** + * Parse a header value while within quotes + * + * @access private + */ + function quote_char() + { + $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position); + $this->value .= substr($this->data, $this->position, $len); + $this->position += $len; + $this->state = 'value'; + } + + /** + * Parse an escaped character within quotes + * + * @access private + */ + function quote_escaped() + { + $this->value .= $this->data[$this->position]; + $this->position++; + $this->state = 'quote'; + } + + /** + * Parse the body + * + * @access private + */ + function body() + { + $this->body = substr($this->data, $this->position); + $this->state = 'emit'; + } +} + +class SimplePie_Cache +{ + /** + * Don't call the constructor. Please. + * + * @access private + */ + function SimplePie_Cache() + { + trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR); + } + + /** + * Create a new SimplePie_Cache object + * + * @static + * @access public + */ + function create($location, $filename, $extension) + { + return new SimplePie_Cache_File($location, $filename, $extension); + } +} + +class SimplePie_Cache_File +{ + var $location; + var $filename; + var $extension; + var $name; + + function SimplePie_Cache_File($location, $filename, $extension) + { + $this->location = $location; + $this->filename = rawurlencode($filename); + $this->extension = rawurlencode($extension); + $this->name = "$location/$this->filename.$this->extension"; + } + + function save($data) + { + if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location)) + { + if (is_a($data, 'SimplePie')) + { + $data = $data->data; + } + + $data = serialize($data); + + if (function_exists('file_put_contents')) + { + return (bool) file_put_contents($this->name, $data); + } + else + { + $fp = fopen($this->name, 'wb'); + if ($fp) + { + fwrite($fp, $data); + fclose($fp); + return true; + } + } + } + return false; + } + + function load() + { + if (file_exists($this->name) && is_readable($this->name)) + { + return unserialize(file_get_contents($this->name)); + } + return false; + } + + function mtime() + { + if (file_exists($this->name)) + { + return filemtime($this->name); + } + return false; + } + + function touch() + { + if (file_exists($this->name)) + { + return touch($this->name); + } + return false; + } + + function unlink() + { + if (file_exists($this->name)) + { + return unlink($this->name); + } + return false; + } +} + +class SimplePie_Misc +{ + function time_hms($seconds) + { + $time = ''; + + $hours = floor($seconds / 3600); + $remainder = $seconds % 3600; + if ($hours > 0) + { + $time .= $hours.':'; + } + + $minutes = floor($remainder / 60); + $seconds = $remainder % 60; + if ($minutes < 10 && $hours > 0) + { + $minutes = '0' . $minutes; + } + if ($seconds < 10) + { + $seconds = '0' . $seconds; + } + + $time .= $minutes.':'; + $time .= $seconds; + + return $time; + } + + function absolutize_url($relative, $base) + { + if ($relative !== '') + { + $relative = SimplePie_Misc::parse_url($relative); + if ($relative['scheme'] !== '') + { + $target = $relative; + } + elseif ($base !== '') + { + $base = SimplePie_Misc::parse_url($base); + $target = SimplePie_Misc::parse_url(''); + if ($relative['authority'] !== '') + { + $target = $relative; + $target['scheme'] = $base['scheme']; + } + else + { + $target['scheme'] = $base['scheme']; + $target['authority'] = $base['authority']; + if ($relative['path'] !== '') + { + if (strpos($relative['path'], '/') === 0) + { + $target['path'] = $relative['path']; + } + elseif ($base['authority'] !== '' && $base['path'] === '') + { + $target['path'] = '/' . $relative['path']; + } + elseif (($last_segment = strrpos($base['path'], '/')) !== false) + { + $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path']; + } + else + { + $target['path'] = $relative['path']; + } + $target['query'] = $relative['query']; + } + else + { + $target['path'] = $base['path']; + if ($relative['query'] !== '') + { + $target['query'] = $relative['query']; + } + elseif ($base['query'] !== '') + { + $target['query'] = $base['query']; + } + } + } + $target['fragment'] = $relative['fragment']; + } + else + { + // No base URL, just return the relative URL + $target = $relative; + } + $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']); + } + else + { + $return = $base; + } + $return = SimplePie_Misc::normalize_url($return); + return $return; + } + + function remove_dot_segments($input) + { + $output = ''; + while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..') + { + // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, + if (strpos($input, '../') === 0) + { + $input = substr($input, 3); + } + elseif (strpos($input, './') === 0) + { + $input = substr($input, 2); + } + // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise, + elseif (strpos($input, '/./') === 0) + { + $input = substr_replace($input, '/', 0, 3); + } + elseif ($input == '/.') + { + $input = '/'; + } + // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise, + elseif (strpos($input, '/../') === 0) + { + $input = substr_replace($input, '/', 0, 4); + $output = substr_replace($output, '', strrpos($output, '/')); + } + elseif ($input == '/..') + { + $input = '/'; + $output = substr_replace($output, '', strrpos($output, '/')); + } + // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, + elseif ($input == '.' || $input == '..') + { + $input = ''; + } + // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer + elseif (($pos = strpos($input, '/', 1)) !== false) + { + $output .= substr($input, 0, $pos); + $input = substr_replace($input, '', 0, $pos); + } + else + { + $output .= $input; + $input = ''; + } + } + return $output . $input; + } + + function get_element($realname, $string) + { + $return = array(); + $name = preg_quote($realname, '/'); + if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) + { + for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++) + { + $return[$i]['tag'] = $realname; + $return[$i]['full'] = $matches[$i][0][0]; + $return[$i]['offset'] = $matches[$i][0][1]; + if (strlen($matches[$i][3][0]) <= 2) + { + $return[$i]['self_closing'] = true; + } + else + { + $return[$i]['self_closing'] = false; + $return[$i]['content'] = $matches[$i][4][0]; + } + $return[$i]['attribs'] = array(); + if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER)) + { + for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++) + { + if (count($attribs[$j]) == 2) + { + $attribs[$j][2] = $attribs[$j][1]; + } + $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8'); + } + } + } + } + return $return; + } + + function element_implode($element) + { + $full = "<$element[tag]"; + foreach ($element['attribs'] as $key => $value) + { + $key = strtolower($key); + $full .= " $key=\"" . htmlspecialchars($value['data']) . '"'; + } + if ($element['self_closing']) + { + $full .= ' />'; + } + else + { + $full .= ">$element[content]"; + } + return $full; + } + + function error($message, $level, $file, $line) + { + switch ($level) + { + case E_USER_ERROR: + $note = 'PHP Error'; + break; + case E_USER_WARNING: + $note = 'PHP Warning'; + break; + case E_USER_NOTICE: + $note = 'PHP Notice'; + break; + default: + $note = 'Unknown Error'; + break; + } + error_log("$note: $message in $file on line $line", 0); + return $message; + } + + /** + * If a file has been cached, retrieve and display it. + * + * This is most useful for caching images (get_favicon(), etc.), + * however it works for all cached files. This WILL NOT display ANY + * file/image/page/whatever, but rather only display what has already + * been cached by SimplePie. + * + * @access public + * @see SimplePie::get_favicon() + * @param str $identifier_url URL that is used to identify the content. + * This may or may not be the actual URL of the live content. + * @param str $cache_location Location of SimplePie's cache. Defaults + * to './cache'. + * @param str $cache_extension The file extension that the file was + * cached with. Defaults to 'spc'. + * @param str $cache_class Name of the cache-handling class being used + * in SimplePie. Defaults to 'SimplePie_Cache', and should be left + * as-is unless you've overloaded the class. + * @param str $cache_name_function Obsolete. Exists for backwards + * compatibility reasons only. + */ + function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5') + { + $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension); + + if ($file = $cache->load()) + { + if (isset($file['headers']['content-type'])) + { + header('Content-type:' . $file['headers']['content-type']); + } + else + { + header('Content-type: application/octet-stream'); + } + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days + echo $file['body']; + exit; + } + + die('Cached file for ' . $identifier_url . ' cannot be found.'); + } + + function fix_protocol($url, $http = 1) + { + $url = SimplePie_Misc::normalize_url($url); + $parsed = SimplePie_Misc::parse_url($url); + if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https') + { + return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http); + } + + if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url)) + { + return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http); + } + + if ($http == 2 && $parsed['scheme'] !== '') + { + return "feed:$url"; + } + elseif ($http == 3 && strtolower($parsed['scheme']) == 'http') + { + return substr_replace($url, 'podcast', 0, 4); + } + elseif ($http == 4 && strtolower($parsed['scheme']) == 'http') + { + return substr_replace($url, 'itpc', 0, 4); + } + else + { + return $url; + } + } + + function parse_url($url) + { + static $cache = array(); + if (isset($cache[$url])) + { + return $cache[$url]; + } + elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match)) + { + for ($i = count($match); $i <= 9; $i++) + { + $match[$i] = ''; + } + return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]); + } + else + { + return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => ''); + } + } + + function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '') + { + $return = ''; + if ($scheme !== '') + { + $return .= "$scheme:"; + } + if ($authority !== '') + { + $return .= "//$authority"; + } + if ($path !== '') + { + $return .= $path; + } + if ($query !== '') + { + $return .= "?$query"; + } + if ($fragment !== '') + { + $return .= "#$fragment"; + } + return $return; + } + + function normalize_url($url) + { + $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url); + $url = SimplePie_Misc::parse_url($url); + $url['scheme'] = strtolower($url['scheme']); + if ($url['authority'] !== '') + { + $url['authority'] = strtolower($url['authority']); + $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']); + } + return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']); + } + + function percent_encoding_normalization($match) + { + $integer = hexdec($match[1]); + if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E) + { + return chr($integer); + } + else + { + return strtoupper($match[0]); + } + } + + /** + * Remove bad UTF-8 bytes + * + * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C + * FAQ: Multilingual Forms (modified to include full ASCII range) + * + * @author Geoffrey Sneddon + * @see http://www.w3.org/International/questions/qa-forms-utf-8 + * @param string $str String to remove bad UTF-8 bytes from + * @return string UTF-8 string + */ + function utf8_bad_replace($str) + { + if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str))) + { + return $return; + } + elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8'))) + { + return $return; + } + elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches)) + { + return implode("\xEF\xBF\xBD", $matches[0]); + } + elseif ($str !== '') + { + return "\xEF\xBF\xBD"; + } + else + { + return ''; + } + } + + /** + * Converts a Windows-1252 encoded string to a UTF-8 encoded string + * + * @static + * @access public + * @param string $string Windows-1252 encoded string + * @return string UTF-8 encoded string + */ + function windows_1252_to_utf8($string) + { + static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF"); + + return strtr($string, $convert_table); + } + + function change_encoding($data, $input, $output) + { + $input = SimplePie_Misc::encoding($input); + $output = SimplePie_Misc::encoding($output); + + // We fail to fail on non US-ASCII bytes + if ($input === 'US-ASCII') + { + static $non_ascii_octects = ''; + if (!$non_ascii_octects) + { + for ($i = 0x80; $i <= 0xFF; $i++) + { + $non_ascii_octects .= chr($i); + } + } + $data = substr($data, 0, strcspn($data, $non_ascii_octects)); + } + + if (function_exists('iconv') && ($return = @iconv($input, $output, $data))) + { + return $return; + } + elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input))) + { + return $return; + } + elseif ($input == 'windows-1252' && $output == 'UTF-8') + { + return SimplePie_Misc::windows_1252_to_utf8($data); + } + elseif ($input == 'UTF-8' && $output == 'windows-1252') + { + return utf8_decode($data); + } + return $data; + } + + function encoding($encoding) + { + // Character sets are case-insensitive (though we'll return them in the form given in their registration) + switch (strtoupper($encoding)) + { + case 'ANSI_X3.110-1983': + case 'CSA_T500-1983': + case 'CSISO99NAPLPS': + case 'ISO-IR-99': + case 'NAPLPS': + return 'ANSI_X3.110-1983'; + + case 'ARABIC7': + case 'ASMO_449': + case 'CSISO89ASMO449': + case 'ISO-IR-89': + case 'ISO_9036': + return 'ASMO_449'; + + case 'ADOBE-STANDARD-ENCODING': + case 'CSADOBESTANDARDENCODING': + return 'Adobe-Standard-Encoding'; + + case 'ADOBE-SYMBOL-ENCODING': + case 'CSHPPSMATH': + return 'Adobe-Symbol-Encoding'; + + case 'AMI-1251': + case 'AMI1251': + case 'AMIGA-1251': + case 'AMIGA1251': + return 'Amiga-1251'; + + case 'BOCU-1': + case 'CSBOCU-1': + return 'BOCU-1'; + + case 'BRF': + case 'CSBRF': + return 'BRF'; + + case 'BS_4730': + case 'CSISO4UNITEDKINGDOM': + case 'GB': + case 'ISO-IR-4': + case 'ISO646-GB': + case 'UK': + return 'BS_4730'; + + case 'BS_VIEWDATA': + case 'CSISO47BSVIEWDATA': + case 'ISO-IR-47': + return 'BS_viewdata'; + + case 'BIG5': + case 'CSBIG5': + return 'Big5'; + + case 'BIG5-HKSCS': + return 'Big5-HKSCS'; + + case 'CESU-8': + case 'CSCESU-8': + return 'CESU-8'; + + case 'CA': + case 'CSA7-1': + case 'CSA_Z243.4-1985-1': + case 'CSISO121CANADIAN1': + case 'ISO-IR-121': + case 'ISO646-CA': + return 'CSA_Z243.4-1985-1'; + + case 'CSA7-2': + case 'CSA_Z243.4-1985-2': + case 'CSISO122CANADIAN2': + case 'ISO-IR-122': + case 'ISO646-CA2': + return 'CSA_Z243.4-1985-2'; + + case 'CSA_Z243.4-1985-GR': + case 'CSISO123CSAZ24341985GR': + case 'ISO-IR-123': + return 'CSA_Z243.4-1985-gr'; + + case 'CSISO139CSN369103': + case 'CSN_369103': + case 'ISO-IR-139': + return 'CSN_369103'; + + case 'CSDECMCS': + case 'DEC': + case 'DEC-MCS': + return 'DEC-MCS'; + + case 'CSISO21GERMAN': + case 'DE': + case 'DIN_66003': + case 'ISO-IR-21': + case 'ISO646-DE': + return 'DIN_66003'; + + case 'CSISO646DANISH': + case 'DK': + case 'DS2089': + case 'DS_2089': + case 'ISO646-DK': + return 'DS_2089'; + + case 'CSIBMEBCDICATDE': + case 'EBCDIC-AT-DE': + return 'EBCDIC-AT-DE'; + + case 'CSEBCDICATDEA': + case 'EBCDIC-AT-DE-A': + return 'EBCDIC-AT-DE-A'; + + case 'CSEBCDICCAFR': + case 'EBCDIC-CA-FR': + return 'EBCDIC-CA-FR'; + + case 'CSEBCDICDKNO': + case 'EBCDIC-DK-NO': + return 'EBCDIC-DK-NO'; + + case 'CSEBCDICDKNOA': + case 'EBCDIC-DK-NO-A': + return 'EBCDIC-DK-NO-A'; + + case 'CSEBCDICES': + case 'EBCDIC-ES': + return 'EBCDIC-ES'; + + case 'CSEBCDICESA': + case 'EBCDIC-ES-A': + return 'EBCDIC-ES-A'; + + case 'CSEBCDICESS': + case 'EBCDIC-ES-S': + return 'EBCDIC-ES-S'; + + case 'CSEBCDICFISE': + case 'EBCDIC-FI-SE': + return 'EBCDIC-FI-SE'; + + case 'CSEBCDICFISEA': + case 'EBCDIC-FI-SE-A': + return 'EBCDIC-FI-SE-A'; + + case 'CSEBCDICFR': + case 'EBCDIC-FR': + return 'EBCDIC-FR'; + + case 'CSEBCDICIT': + case 'EBCDIC-IT': + return 'EBCDIC-IT'; + + case 'CSEBCDICPT': + case 'EBCDIC-PT': + return 'EBCDIC-PT'; + + case 'CSEBCDICUK': + case 'EBCDIC-UK': + return 'EBCDIC-UK'; + + case 'CSEBCDICUS': + case 'EBCDIC-US': + return 'EBCDIC-US'; + + case 'CSISO111ECMACYRILLIC': + case 'ECMA-CYRILLIC': + case 'ISO-IR-111': + case 'KOI8-E': + return 'ECMA-cyrillic'; + + case 'CSISO17SPANISH': + case 'ES': + case 'ISO-IR-17': + case 'ISO646-ES': + return 'ES'; + + case 'CSISO85SPANISH2': + case 'ES2': + case 'ISO-IR-85': + case 'ISO646-ES2': + return 'ES2'; + + case 'CSEUCPKDFMTJAPANESE': + case 'EUC-JP': + case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE': + return 'EUC-JP'; + + case 'CSEUCKR': + case 'EUC-KR': + return 'EUC-KR'; + + case 'CSEUCFIXWIDJAPANESE': + case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE': + return 'Extended_UNIX_Code_Fixed_Width_for_Japanese'; + + case 'GB18030': + return 'GB18030'; + + case 'CSGB2312': + case 'GB2312': + return 'GB2312'; + + case 'CP936': + case 'GBK': + case 'MS936': + case 'WINDOWS-936': + return 'GBK'; + + case 'CN': + case 'CSISO57GB1988': + case 'GB_1988-80': + case 'ISO-IR-57': + case 'ISO646-CN': + return 'GB_1988-80'; + + case 'CHINESE': + case 'CSISO58GB231280': + case 'GB_2312-80': + case 'ISO-IR-58': + return 'GB_2312-80'; + + case 'CSISO153GOST1976874': + case 'GOST_19768-74': + case 'ISO-IR-153': + case 'ST_SEV_358-88': + return 'GOST_19768-74'; + + case 'CSHPDESKTOP': + case 'HP-DESKTOP': + return 'HP-DeskTop'; + + case 'CSHPLEGAL': + case 'HP-LEGAL': + return 'HP-Legal'; + + case 'CSHPMATH8': + case 'HP-MATH8': + return 'HP-Math8'; + + case 'CSHPPIFONT': + case 'HP-PI-FONT': + return 'HP-Pi-font'; + + case 'HZ-GB-2312': + return 'HZ-GB-2312'; + + case 'CSIBMSYMBOLS': + case 'IBM-SYMBOLS': + return 'IBM-Symbols'; + + case 'CSIBMTHAI': + case 'IBM-THAI': + return 'IBM-Thai'; + + case 'CCSID00858': + case 'CP00858': + case 'IBM00858': + case 'PC-MULTILINGUAL-850+EURO': + return 'IBM00858'; + + case 'CCSID00924': + case 'CP00924': + case 'EBCDIC-LATIN9--EURO': + case 'IBM00924': + return 'IBM00924'; + + case 'CCSID01140': + case 'CP01140': + case 'EBCDIC-US-37+EURO': + case 'IBM01140': + return 'IBM01140'; + + case 'CCSID01141': + case 'CP01141': + case 'EBCDIC-DE-273+EURO': + case 'IBM01141': + return 'IBM01141'; + + case 'CCSID01142': + case 'CP01142': + case 'EBCDIC-DK-277+EURO': + case 'EBCDIC-NO-277+EURO': + case 'IBM01142': + return 'IBM01142'; + + case 'CCSID01143': + case 'CP01143': + case 'EBCDIC-FI-278+EURO': + case 'EBCDIC-SE-278+EURO': + case 'IBM01143': + return 'IBM01143'; + + case 'CCSID01144': + case 'CP01144': + case 'EBCDIC-IT-280+EURO': + case 'IBM01144': + return 'IBM01144'; + + case 'CCSID01145': + case 'CP01145': + case 'EBCDIC-ES-284+EURO': + case 'IBM01145': + return 'IBM01145'; + + case 'CCSID01146': + case 'CP01146': + case 'EBCDIC-GB-285+EURO': + case 'IBM01146': + return 'IBM01146'; + + case 'CCSID01147': + case 'CP01147': + case 'EBCDIC-FR-297+EURO': + case 'IBM01147': + return 'IBM01147'; + + case 'CCSID01148': + case 'CP01148': + case 'EBCDIC-INTERNATIONAL-500+EURO': + case 'IBM01148': + return 'IBM01148'; + + case 'CCSID01149': + case 'CP01149': + case 'EBCDIC-IS-871+EURO': + case 'IBM01149': + return 'IBM01149'; + + case 'CP037': + case 'CSIBM037': + case 'EBCDIC-CP-CA': + case 'EBCDIC-CP-NL': + case 'EBCDIC-CP-US': + case 'EBCDIC-CP-WT': + case 'IBM037': + return 'IBM037'; + + case 'CP038': + case 'CSIBM038': + case 'EBCDIC-INT': + case 'IBM038': + return 'IBM038'; + + case 'CP1026': + case 'CSIBM1026': + case 'IBM1026': + return 'IBM1026'; + + case 'IBM-1047': + case 'IBM1047': + return 'IBM1047'; + + case 'CP273': + case 'CSIBM273': + case 'IBM273': + return 'IBM273'; + + case 'CP274': + case 'CSIBM274': + case 'EBCDIC-BE': + case 'IBM274': + return 'IBM274'; + + case 'CP275': + case 'CSIBM275': + case 'EBCDIC-BR': + case 'IBM275': + return 'IBM275'; + + case 'CSIBM277': + case 'EBCDIC-CP-DK': + case 'EBCDIC-CP-NO': + case 'IBM277': + return 'IBM277'; + + case 'CP278': + case 'CSIBM278': + case 'EBCDIC-CP-FI': + case 'EBCDIC-CP-SE': + case 'IBM278': + return 'IBM278'; + + case 'CP280': + case 'CSIBM280': + case 'EBCDIC-CP-IT': + case 'IBM280': + return 'IBM280'; + + case 'CP281': + case 'CSIBM281': + case 'EBCDIC-JP-E': + case 'IBM281': + return 'IBM281'; + + case 'CP284': + case 'CSIBM284': + case 'EBCDIC-CP-ES': + case 'IBM284': + return 'IBM284'; + + case 'CP285': + case 'CSIBM285': + case 'EBCDIC-CP-GB': + case 'IBM285': + return 'IBM285'; + + case 'CP290': + case 'CSIBM290': + case 'EBCDIC-JP-KANA': + case 'IBM290': + return 'IBM290'; + + case 'CP297': + case 'CSIBM297': + case 'EBCDIC-CP-FR': + case 'IBM297': + return 'IBM297'; + + case 'CP420': + case 'CSIBM420': + case 'EBCDIC-CP-AR1': + case 'IBM420': + return 'IBM420'; + + case 'CP423': + case 'CSIBM423': + case 'EBCDIC-CP-GR': + case 'IBM423': + return 'IBM423'; + + case 'CP424': + case 'CSIBM424': + case 'EBCDIC-CP-HE': + case 'IBM424': + return 'IBM424'; + + case '437': + case 'CP437': + case 'CSPC8CODEPAGE437': + case 'IBM437': + return 'IBM437'; + + case 'CP500': + case 'CSIBM500': + case 'EBCDIC-CP-BE': + case 'EBCDIC-CP-CH': + case 'IBM500': + return 'IBM500'; + + case 'CP775': + case 'CSPC775BALTIC': + case 'IBM775': + return 'IBM775'; + + case '850': + case 'CP850': + case 'CSPC850MULTILINGUAL': + case 'IBM850': + return 'IBM850'; + + case '851': + case 'CP851': + case 'CSIBM851': + case 'IBM851': + return 'IBM851'; + + case '852': + case 'CP852': + case 'CSPCP852': + case 'IBM852': + return 'IBM852'; + + case '855': + case 'CP855': + case 'CSIBM855': + case 'IBM855': + return 'IBM855'; + + case '857': + case 'CP857': + case 'CSIBM857': + case 'IBM857': + return 'IBM857'; + + case '860': + case 'CP860': + case 'CSIBM860': + case 'IBM860': + return 'IBM860'; + + case '861': + case 'CP-IS': + case 'CP861': + case 'CSIBM861': + case 'IBM861': + return 'IBM861'; + + case '862': + case 'CP862': + case 'CSPC862LATINHEBREW': + case 'IBM862': + return 'IBM862'; + + case '863': + case 'CP863': + case 'CSIBM863': + case 'IBM863': + return 'IBM863'; + + case 'CP864': + case 'CSIBM864': + case 'IBM864': + return 'IBM864'; + + case '865': + case 'CP865': + case 'CSIBM865': + case 'IBM865': + return 'IBM865'; + + case '866': + case 'CP866': + case 'CSIBM866': + case 'IBM866': + return 'IBM866'; + + case 'CP-AR': + case 'CP868': + case 'CSIBM868': + case 'IBM868': + return 'IBM868'; + + case '869': + case 'CP-GR': + case 'CP869': + case 'CSIBM869': + case 'IBM869': + return 'IBM869'; + + case 'CP870': + case 'CSIBM870': + case 'EBCDIC-CP-ROECE': + case 'EBCDIC-CP-YU': + case 'IBM870': + return 'IBM870'; + + case 'CP871': + case 'CSIBM871': + case 'EBCDIC-CP-IS': + case 'IBM871': + return 'IBM871'; + + case 'CP880': + case 'CSIBM880': + case 'EBCDIC-CYRILLIC': + case 'IBM880': + return 'IBM880'; + + case 'CP891': + case 'CSIBM891': + case 'IBM891': + return 'IBM891'; + + case 'CP903': + case 'CSIBM903': + case 'IBM903': + return 'IBM903'; + + case '904': + case 'CP904': + case 'CSIBBM904': + case 'IBM904': + return 'IBM904'; + + case 'CP905': + case 'CSIBM905': + case 'EBCDIC-CP-TR': + case 'IBM905': + return 'IBM905'; + + case 'CP918': + case 'CSIBM918': + case 'EBCDIC-CP-AR2': + case 'IBM918': + return 'IBM918'; + + case 'CSISO143IECP271': + case 'IEC_P27-1': + case 'ISO-IR-143': + return 'IEC_P27-1'; + + case 'CSISO49INIS': + case 'INIS': + case 'ISO-IR-49': + return 'INIS'; + + case 'CSISO50INIS8': + case 'INIS-8': + case 'ISO-IR-50': + return 'INIS-8'; + + case 'CSISO51INISCYRILLIC': + case 'INIS-CYRILLIC': + case 'ISO-IR-51': + return 'INIS-cyrillic'; + + case 'CSINVARIANT': + case 'INVARIANT': + return 'INVARIANT'; + + case 'ISO-10646-J-1': + return 'ISO-10646-J-1'; + + case 'CSUNICODE': + case 'ISO-10646-UCS-2': + return 'ISO-10646-UCS-2'; + + case 'CSUCS4': + case 'ISO-10646-UCS-4': + return 'ISO-10646-UCS-4'; + + case 'CSUNICODEASCII': + case 'ISO-10646-UCS-BASIC': + return 'ISO-10646-UCS-Basic'; + + case 'CSISO10646UTF1': + case 'ISO-10646-UTF-1': + return 'ISO-10646-UTF-1'; + + case 'CSUNICODELATIN1': + case 'ISO-10646': + case 'ISO-10646-UNICODE-LATIN1': + return 'ISO-10646-Unicode-Latin1'; + + case 'CSISO115481': + case 'ISO-11548-1': + case 'ISO_11548-1': + case 'ISO_TR_11548-1': + return 'ISO-11548-1'; + + case 'ISO-2022-CN': + return 'ISO-2022-CN'; + + case 'ISO-2022-CN-EXT': + return 'ISO-2022-CN-EXT'; + + case 'CSISO2022JP': + case 'ISO-2022-JP': + return 'ISO-2022-JP'; + + case 'CSISO2022JP2': + case 'ISO-2022-JP-2': + return 'ISO-2022-JP-2'; + + case 'CSISO2022KR': + case 'ISO-2022-KR': + return 'ISO-2022-KR'; + + case 'CSWINDOWS30LATIN1': + case 'ISO-8859-1-WINDOWS-3.0-LATIN-1': + return 'ISO-8859-1-Windows-3.0-Latin-1'; + + case 'CSWINDOWS31LATIN1': + case 'ISO-8859-1-WINDOWS-3.1-LATIN-1': + return 'ISO-8859-1-Windows-3.1-Latin-1'; + + case 'CSISOLATIN6': + case 'ISO-8859-10': + case 'ISO-IR-157': + case 'ISO_8859-10:1992': + case 'L6': + case 'LATIN6': + return 'ISO-8859-10'; + + case 'ISO-8859-13': + return 'ISO-8859-13'; + + case 'ISO-8859-14': + case 'ISO-CELTIC': + case 'ISO-IR-199': + case 'ISO_8859-14': + case 'ISO_8859-14:1998': + case 'L8': + case 'LATIN8': + return 'ISO-8859-14'; + + case 'ISO-8859-15': + case 'ISO_8859-15': + case 'LATIN-9': + return 'ISO-8859-15'; + + case 'ISO-8859-16': + case 'ISO-IR-226': + case 'ISO_8859-16': + case 'ISO_8859-16:2001': + case 'L10': + case 'LATIN10': + return 'ISO-8859-16'; + + case 'CSISOLATIN2': + case 'ISO-8859-2': + case 'ISO-IR-101': + case 'ISO_8859-2': + case 'ISO_8859-2:1987': + case 'L2': + case 'LATIN2': + return 'ISO-8859-2'; + + case 'CSWINDOWS31LATIN2': + case 'ISO-8859-2-WINDOWS-LATIN-2': + return 'ISO-8859-2-Windows-Latin-2'; + + case 'CSISOLATIN3': + case 'ISO-8859-3': + case 'ISO-IR-109': + case 'ISO_8859-3': + case 'ISO_8859-3:1988': + case 'L3': + case 'LATIN3': + return 'ISO-8859-3'; + + case 'CSISOLATIN4': + case 'ISO-8859-4': + case 'ISO-IR-110': + case 'ISO_8859-4': + case 'ISO_8859-4:1988': + case 'L4': + case 'LATIN4': + return 'ISO-8859-4'; + + case 'CSISOLATINCYRILLIC': + case 'CYRILLIC': + case 'ISO-8859-5': + case 'ISO-IR-144': + case 'ISO_8859-5': + case 'ISO_8859-5:1988': + return 'ISO-8859-5'; + + case 'ARABIC': + case 'ASMO-708': + case 'CSISOLATINARABIC': + case 'ECMA-114': + case 'ISO-8859-6': + case 'ISO-IR-127': + case 'ISO_8859-6': + case 'ISO_8859-6:1987': + return 'ISO-8859-6'; + + case 'CSISO88596E': + case 'ISO-8859-6-E': + case 'ISO_8859-6-E': + return 'ISO-8859-6-E'; + + case 'CSISO88596I': + case 'ISO-8859-6-I': + case 'ISO_8859-6-I': + return 'ISO-8859-6-I'; + + case 'CSISOLATINGREEK': + case 'ECMA-118': + case 'ELOT_928': + case 'GREEK': + case 'GREEK8': + case 'ISO-8859-7': + case 'ISO-IR-126': + case 'ISO_8859-7': + case 'ISO_8859-7:1987': + return 'ISO-8859-7'; + + case 'CSISOLATINHEBREW': + case 'HEBREW': + case 'ISO-8859-8': + case 'ISO-IR-138': + case 'ISO_8859-8': + case 'ISO_8859-8:1988': + return 'ISO-8859-8'; + + case 'CSISO88598E': + case 'ISO-8859-8-E': + case 'ISO_8859-8-E': + return 'ISO-8859-8-E'; + + case 'CSISO88598I': + case 'ISO-8859-8-I': + case 'ISO_8859-8-I': + return 'ISO-8859-8-I'; + + case 'CSISOLATIN5': + case 'ISO-8859-9': + case 'ISO-IR-148': + case 'ISO_8859-9': + case 'ISO_8859-9:1989': + case 'L5': + case 'LATIN5': + return 'ISO-8859-9'; + + case 'CSWINDOWS31LATIN5': + case 'ISO-8859-9-WINDOWS-LATIN-5': + return 'ISO-8859-9-Windows-Latin-5'; + + case 'CSUNICODEIBM1261': + case 'ISO-UNICODE-IBM-1261': + return 'ISO-Unicode-IBM-1261'; + + case 'CSUNICODEIBM1264': + case 'ISO-UNICODE-IBM-1264': + return 'ISO-Unicode-IBM-1264'; + + case 'CSUNICODEIBM1265': + case 'ISO-UNICODE-IBM-1265': + return 'ISO-Unicode-IBM-1265'; + + case 'CSUNICODEIBM1268': + case 'ISO-UNICODE-IBM-1268': + return 'ISO-Unicode-IBM-1268'; + + case 'CSUNICODEIBM1276': + case 'ISO-UNICODE-IBM-1276': + return 'ISO-Unicode-IBM-1276'; + + case 'CSISO10367BOX': + case 'ISO-IR-155': + case 'ISO_10367-BOX': + return 'ISO_10367-box'; + + case 'CSISO2033': + case 'E13B': + case 'ISO-IR-98': + case 'ISO_2033-1983': + return 'ISO_2033-1983'; + + case 'CSISO5427CYRILLIC': + case 'ISO-IR-37': + case 'ISO_5427': + return 'ISO_5427'; + + case 'ISO-IR-54': + case 'ISO5427CYRILLIC1981': + case 'ISO_5427:1981': + return 'ISO_5427:1981'; + + case 'CSISO5428GREEK': + case 'ISO-IR-55': + case 'ISO_5428:1980': + return 'ISO_5428:1980'; + + case 'CSISO646BASIC1983': + case 'ISO_646.BASIC:1983': + case 'REF': + return 'ISO_646.basic:1983'; + + case 'CSISO2INTLREFVERSION': + case 'IRV': + case 'ISO-IR-2': + case 'ISO_646.IRV:1983': + return 'ISO_646.irv:1983'; + + case 'CSISO6937ADD': + case 'ISO-IR-152': + case 'ISO_6937-2-25': + return 'ISO_6937-2-25'; + + case 'CSISOTEXTCOMM': + case 'ISO-IR-142': + case 'ISO_6937-2-ADD': + return 'ISO_6937-2-add'; + + case 'CSISO8859SUPP': + case 'ISO-IR-154': + case 'ISO_8859-SUPP': + case 'LATIN1-2-5': + return 'ISO_8859-supp'; + + case 'CSISO15ITALIAN': + case 'ISO-IR-15': + case 'ISO646-IT': + case 'IT': + return 'IT'; + + case 'CSISO13JISC6220JP': + case 'ISO-IR-13': + case 'JIS_C6220-1969': + case 'JIS_C6220-1969-JP': + case 'KATAKANA': + case 'X0201-7': + return 'JIS_C6220-1969-jp'; + + case 'CSISO14JISC6220RO': + case 'ISO-IR-14': + case 'ISO646-JP': + case 'JIS_C6220-1969-RO': + case 'JP': + return 'JIS_C6220-1969-ro'; + + case 'CSISO42JISC62261978': + case 'ISO-IR-42': + case 'JIS_C6226-1978': + return 'JIS_C6226-1978'; + + case 'CSISO87JISX0208': + case 'ISO-IR-87': + case 'JIS_C6226-1983': + case 'JIS_X0208-1983': + case 'X0208': + return 'JIS_C6226-1983'; + + case 'CSISO91JISC62291984A': + case 'ISO-IR-91': + case 'JIS_C6229-1984-A': + case 'JP-OCR-A': + return 'JIS_C6229-1984-a'; + + case 'CSISO92JISC62991984B': + case 'ISO-IR-92': + case 'ISO646-JP-OCR-B': + case 'JIS_C6229-1984-B': + case 'JP-OCR-B': + return 'JIS_C6229-1984-b'; + + case 'CSISO93JIS62291984BADD': + case 'ISO-IR-93': + case 'JIS_C6229-1984-B-ADD': + case 'JP-OCR-B-ADD': + return 'JIS_C6229-1984-b-add'; + + case 'CSISO94JIS62291984HAND': + case 'ISO-IR-94': + case 'JIS_C6229-1984-HAND': + case 'JP-OCR-HAND': + return 'JIS_C6229-1984-hand'; + + case 'CSISO95JIS62291984HANDADD': + case 'ISO-IR-95': + case 'JIS_C6229-1984-HAND-ADD': + case 'JP-OCR-HAND-ADD': + return 'JIS_C6229-1984-hand-add'; + + case 'CSISO96JISC62291984KANA': + case 'ISO-IR-96': + case 'JIS_C6229-1984-KANA': + return 'JIS_C6229-1984-kana'; + + case 'CSJISENCODING': + case 'JIS_ENCODING': + return 'JIS_Encoding'; + + case 'CSHALFWIDTHKATAKANA': + case 'JIS_X0201': + case 'X0201': + return 'JIS_X0201'; + + case 'CSISO159JISX02121990': + case 'ISO-IR-159': + case 'JIS_X0212-1990': + case 'X0212': + return 'JIS_X0212-1990'; + + case 'CSISO141JUSIB1002': + case 'ISO-IR-141': + case 'ISO646-YU': + case 'JS': + case 'JUS_I.B1.002': + case 'YU': + return 'JUS_I.B1.002'; + + case 'CSISO147MACEDONIAN': + case 'ISO-IR-147': + case 'JUS_I.B1.003-MAC': + case 'MACEDONIAN': + return 'JUS_I.B1.003-mac'; + + case 'CSISO146SERBIAN': + case 'ISO-IR-146': + case 'JUS_I.B1.003-SERB': + case 'SERBIAN': + return 'JUS_I.B1.003-serb'; + + case 'KOI7-SWITCHED': + return 'KOI7-switched'; + + case 'CSKOI8R': + case 'KOI8-R': + return 'KOI8-R'; + + case 'KOI8-U': + return 'KOI8-U'; + + case 'CSKSC5636': + case 'ISO646-KR': + case 'KSC5636': + return 'KSC5636'; + + case 'CSKSC56011987': + case 'ISO-IR-149': + case 'KOREAN': + case 'KSC_5601': + case 'KS_C_5601-1987': + case 'KS_C_5601-1989': + return 'KS_C_5601-1987'; + + case 'CSKZ1048': + case 'KZ-1048': + case 'RK1048': + case 'STRK1048-2002': + return 'KZ-1048'; + + case 'CSISO27LATINGREEK1': + case 'ISO-IR-27': + case 'LATIN-GREEK-1': + return 'Latin-greek-1'; + + case 'CSMNEM': + case 'MNEM': + return 'MNEM'; + + case 'CSMNEMONIC': + case 'MNEMONIC': + return 'MNEMONIC'; + + case 'CSISO86HUNGARIAN': + case 'HU': + case 'ISO-IR-86': + case 'ISO646-HU': + case 'MSZ_7795.3': + return 'MSZ_7795.3'; + + case 'CSMICROSOFTPUBLISHING': + case 'MICROSOFT-PUBLISHING': + return 'Microsoft-Publishing'; + + case 'CSNATSDANO': + case 'ISO-IR-9-1': + case 'NATS-DANO': + return 'NATS-DANO'; + + case 'CSNATSDANOADD': + case 'ISO-IR-9-2': + case 'NATS-DANO-ADD': + return 'NATS-DANO-ADD'; + + case 'CSNATSSEFI': + case 'ISO-IR-8-1': + case 'NATS-SEFI': + return 'NATS-SEFI'; + + case 'CSNATSSEFIADD': + case 'ISO-IR-8-2': + case 'NATS-SEFI-ADD': + return 'NATS-SEFI-ADD'; + + case 'CSISO151CUBA': + case 'CUBA': + case 'ISO-IR-151': + case 'ISO646-CU': + case 'NC_NC00-10:81': + return 'NC_NC00-10:81'; + + case 'CSISO69FRENCH': + case 'FR': + case 'ISO-IR-69': + case 'ISO646-FR': + case 'NF_Z_62-010': + return 'NF_Z_62-010'; + + case 'CSISO25FRENCH': + case 'ISO-IR-25': + case 'ISO646-FR1': + case 'NF_Z_62-010_(1973)': + return 'NF_Z_62-010_(1973)'; + + case 'CSISO60DANISHNORWEGIAN': + case 'CSISO60NORWEGIAN1': + case 'ISO-IR-60': + case 'ISO646-NO': + case 'NO': + case 'NS_4551-1': + return 'NS_4551-1'; + + case 'CSISO61NORWEGIAN2': + case 'ISO-IR-61': + case 'ISO646-NO2': + case 'NO2': + case 'NS_4551-2': + return 'NS_4551-2'; + + case 'OSD_EBCDIC_DF03_IRV': + return 'OSD_EBCDIC_DF03_IRV'; + + case 'OSD_EBCDIC_DF04_1': + return 'OSD_EBCDIC_DF04_1'; + + case 'OSD_EBCDIC_DF04_15': + return 'OSD_EBCDIC_DF04_15'; + + case 'CSPC8DANISHNORWEGIAN': + case 'PC8-DANISH-NORWEGIAN': + return 'PC8-Danish-Norwegian'; + + case 'CSPC8TURKISH': + case 'PC8-TURKISH': + return 'PC8-Turkish'; + + case 'CSISO16PORTUGUESE': + case 'ISO-IR-16': + case 'ISO646-PT': + case 'PT': + return 'PT'; + + case 'CSISO84PORTUGUESE2': + case 'ISO-IR-84': + case 'ISO646-PT2': + case 'PT2': + return 'PT2'; + + case 'CP154': + case 'CSPTCP154': + case 'CYRILLIC-ASIAN': + case 'PT154': + case 'PTCP154': + return 'PTCP154'; + + case 'SCSU': + return 'SCSU'; + + case 'CSISO10SWEDISH': + case 'FI': + case 'ISO-IR-10': + case 'ISO646-FI': + case 'ISO646-SE': + case 'SE': + case 'SEN_850200_B': + return 'SEN_850200_B'; + + case 'CSISO11SWEDISHFORNAMES': + case 'ISO-IR-11': + case 'ISO646-SE2': + case 'SE2': + case 'SEN_850200_C': + return 'SEN_850200_C'; + + case 'CSSHIFTJIS': + case 'MS_KANJI': + case 'SHIFT_JIS': + return 'Shift_JIS'; + + case 'CSISO128T101G2': + case 'ISO-IR-128': + case 'T.101-G2': + return 'T.101-G2'; + + case 'CSISO102T617BIT': + case 'ISO-IR-102': + case 'T.61-7BIT': + return 'T.61-7bit'; + + case 'CSISO103T618BIT': + case 'ISO-IR-103': + case 'T.61': + case 'T.61-8BIT': + return 'T.61-8bit'; + + case 'CSTSCII': + case 'TSCII': + return 'TSCII'; + + case 'CSUNICODE11': + case 'UNICODE-1-1': + return 'UNICODE-1-1'; + + case 'CSUNICODE11UTF7': + case 'UNICODE-1-1-UTF-7': + return 'UNICODE-1-1-UTF-7'; + + case 'CSUNKNOWN8BIT': + case 'UNKNOWN-8BIT': + return 'UNKNOWN-8BIT'; + + case 'ANSI': + case 'ANSI_X3.4-1968': + case 'ANSI_X3.4-1986': + case 'ASCII': + case 'CP367': + case 'CSASCII': + case 'IBM367': + case 'ISO-IR-6': + case 'ISO646-US': + case 'ISO_646.IRV:1991': + case 'US': + case 'US-ASCII': + return 'US-ASCII'; + + case 'UTF-16': + return 'UTF-16'; + + case 'UTF-16BE': + return 'UTF-16BE'; + + case 'UTF-16LE': + return 'UTF-16LE'; + + case 'UTF-32': + return 'UTF-32'; + + case 'UTF-32BE': + return 'UTF-32BE'; + + case 'UTF-32LE': + return 'UTF-32LE'; + + case 'UTF-7': + return 'UTF-7'; + + case 'UTF-8': + return 'UTF-8'; + + case 'CSVIQR': + case 'VIQR': + return 'VIQR'; + + case 'CSVISCII': + case 'VISCII': + return 'VISCII'; + + case 'CSVENTURAINTERNATIONAL': + case 'VENTURA-INTERNATIONAL': + return 'Ventura-International'; + + case 'CSVENTURAMATH': + case 'VENTURA-MATH': + return 'Ventura-Math'; + + case 'CSVENTURAUS': + case 'VENTURA-US': + return 'Ventura-US'; + + case 'CSWINDOWS31J': + case 'WINDOWS-31J': + return 'Windows-31J'; + + case 'CSDKUS': + case 'DK-US': + return 'dk-us'; + + case 'CSISO150': + case 'CSISO150GREEKCCITT': + case 'GREEK-CCITT': + case 'ISO-IR-150': + return 'greek-ccitt'; + + case 'CSISO88GREEK7': + case 'GREEK7': + case 'ISO-IR-88': + return 'greek7'; + + case 'CSISO18GREEK7OLD': + case 'GREEK7-OLD': + case 'ISO-IR-18': + return 'greek7-old'; + + case 'CSHPROMAN8': + case 'HP-ROMAN8': + case 'R8': + case 'ROMAN8': + return 'hp-roman8'; + + case 'CSISO90': + case 'ISO-IR-90': + return 'iso-ir-90'; + + case 'CSISO19LATINGREEK': + case 'ISO-IR-19': + case 'LATIN-GREEK': + return 'latin-greek'; + + case 'CSISO158LAP': + case 'ISO-IR-158': + case 'LAP': + case 'LATIN-LAP': + return 'latin-lap'; + + case 'CSMACINTOSH': + case 'MAC': + case 'MACINTOSH': + return 'macintosh'; + + case 'CSUSDK': + case 'US-DK': + return 'us-dk'; + + case 'CSISO70VIDEOTEXSUPP1': + case 'ISO-IR-70': + case 'VIDEOTEX-SUPPL': + return 'videotex-suppl'; + + case 'WINDOWS-1250': + return 'windows-1250'; + + case 'WINDOWS-1251': + return 'windows-1251'; + + case 'CP819': + case 'CSISOLATIN1': + case 'IBM819': + case 'ISO-8859-1': + case 'ISO-IR-100': + case 'ISO_8859-1': + case 'ISO_8859-1:1987': + case 'L1': + case 'LATIN1': + case 'WINDOWS-1252': + return 'windows-1252'; + + case 'WINDOWS-1253': + return 'windows-1253'; + + case 'WINDOWS-1254': + return 'windows-1254'; + + case 'WINDOWS-1255': + return 'windows-1255'; + + case 'WINDOWS-1256': + return 'windows-1256'; + + case 'WINDOWS-1257': + return 'windows-1257'; + + case 'WINDOWS-1258': + return 'windows-1258'; + + default: + return $encoding; + } + } + + function get_curl_version() + { + if (is_array($curl = curl_version())) + { + $curl = $curl['version']; + } + elseif (substr($curl, 0, 5) == 'curl/') + { + $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5)); + } + elseif (substr($curl, 0, 8) == 'libcurl/') + { + $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8)); + } + else + { + $curl = 0; + } + return $curl; + } + + function is_subclass_of($class1, $class2) + { + if (func_num_args() != 2) + { + trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING); + } + elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1)) + { + return is_subclass_of($class1, $class2); + } + elseif (is_string($class1) && is_string($class2)) + { + if (class_exists($class1)) + { + if (class_exists($class2)) + { + $class2 = strtolower($class2); + while ($class1 = strtolower(get_parent_class($class1))) + { + if ($class1 == $class2) + { + return true; + } + } + } + } + else + { + trigger_error('Unknown class passed as parameter', E_USER_WARNNG); + } + } + return false; + } + + /** + * Strip HTML comments + * + * @access public + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function strip_comments($data) + { + $output = ''; + while (($start = strpos($data, '', $start)) !== false) + { + $data = substr_replace($data, '', 0, $end + 3); + } + else + { + $data = ''; + } + } + return $output . $data; + } + + function parse_date($dt) + { + $parser = SimplePie_Parse_Date::get(); + return $parser->parse($dt); + } + + /** + * Decode HTML entities + * + * @static + * @access public + * @param string $data Input data + * @return string Output data + */ + function entities_decode($data) + { + $decoder = new SimplePie_Decode_HTML_Entities($data); + return $decoder->parse(); + } + + /** + * Remove RFC822 comments + * + * @access public + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function uncomment_rfc822($string) + { + $string = (string) $string; + $position = 0; + $length = strlen($string); + $depth = 0; + + $output = ''; + + while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) + { + $output .= substr($string, $position, $pos - $position); + $position = $pos + 1; + if ($string[$pos - 1] !== '\\') + { + $depth++; + while ($depth && $position < $length) + { + $position += strcspn($string, '()', $position); + if ($string[$position - 1] === '\\') + { + $position++; + continue; + } + elseif (isset($string[$position])) + { + switch ($string[$position]) + { + case '(': + $depth++; + break; + + case ')': + $depth--; + break; + } + $position++; + } + else + { + break; + } + } + } + else + { + $output .= '('; + } + } + $output .= substr($string, $position); + + return $output; + } + + function parse_mime($mime) + { + if (($pos = strpos($mime, ';')) === false) + { + return trim($mime); + } + else + { + return trim(substr($mime, 0, $pos)); + } + } + + function htmlspecialchars_decode($string, $quote_style) + { + if (function_exists('htmlspecialchars_decode')) + { + return htmlspecialchars_decode($string, $quote_style); + } + else + { + return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style))); + } + } + + function atom_03_construct_type($attribs) + { + if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64')) + { + $mode = SIMPLEPIE_CONSTRUCT_BASE64; + } + else + { + $mode = SIMPLEPIE_CONSTRUCT_NONE; + } + if (isset($attribs['']['type'])) + { + switch (strtolower(trim($attribs['']['type']))) + { + case 'text': + case 'text/plain': + return SIMPLEPIE_CONSTRUCT_TEXT | $mode; + + case 'html': + case 'text/html': + return SIMPLEPIE_CONSTRUCT_HTML | $mode; + + case 'xhtml': + case 'application/xhtml+xml': + return SIMPLEPIE_CONSTRUCT_XHTML | $mode; + + default: + return SIMPLEPIE_CONSTRUCT_NONE | $mode; + } + } + else + { + return SIMPLEPIE_CONSTRUCT_TEXT | $mode; + } + } + + function atom_10_construct_type($attribs) + { + if (isset($attribs['']['type'])) + { + switch (strtolower(trim($attribs['']['type']))) + { + case 'text': + return SIMPLEPIE_CONSTRUCT_TEXT; + + case 'html': + return SIMPLEPIE_CONSTRUCT_HTML; + + case 'xhtml': + return SIMPLEPIE_CONSTRUCT_XHTML; + + default: + return SIMPLEPIE_CONSTRUCT_NONE; + } + } + return SIMPLEPIE_CONSTRUCT_TEXT; + } + + function atom_10_content_construct_type($attribs) + { + if (isset($attribs['']['type'])) + { + $type = strtolower(trim($attribs['']['type'])); + switch ($type) + { + case 'text': + return SIMPLEPIE_CONSTRUCT_TEXT; + + case 'html': + return SIMPLEPIE_CONSTRUCT_HTML; + + case 'xhtml': + return SIMPLEPIE_CONSTRUCT_XHTML; + } + if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/') + { + return SIMPLEPIE_CONSTRUCT_NONE; + } + else + { + return SIMPLEPIE_CONSTRUCT_BASE64; + } + } + else + { + return SIMPLEPIE_CONSTRUCT_TEXT; + } + } + + function is_isegment_nz_nc($string) + { + return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string); + } + + function space_seperated_tokens($string) + { + $space_characters = "\x20\x09\x0A\x0B\x0C\x0D"; + $string_length = strlen($string); + + $position = strspn($string, $space_characters); + $tokens = array(); + + while ($position < $string_length) + { + $len = strcspn($string, $space_characters, $position); + $tokens[] = substr($string, $position, $len); + $position += $len; + $position += strspn($string, $space_characters, $position); + } + + return $tokens; + } + + function array_unique($array) + { + if (version_compare(PHP_VERSION, '5.2', '>=')) + { + return array_unique($array); + } + else + { + $array = (array) $array; + $new_array = array(); + $new_array_strings = array(); + foreach ($array as $key => $value) + { + if (is_object($value)) + { + if (method_exists($value, '__toString')) + { + $cmp = $value->__toString(); + } + else + { + trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR); + } + } + elseif (is_array($value)) + { + $cmp = (string) reset($value); + } + else + { + $cmp = (string) $value; + } + if (!in_array($cmp, $new_array_strings)) + { + $new_array[$key] = $value; + $new_array_strings[] = $cmp; + } + } + return $new_array; + } + } + + /** + * Converts a unicode codepoint to a UTF-8 character + * + * @static + * @access public + * @param int $codepoint Unicode codepoint + * @return string UTF-8 character + */ + function codepoint_to_utf8($codepoint) + { + static $cache = array(); + $codepoint = (int) $codepoint; + if (isset($cache[$codepoint])) + { + return $cache[$codepoint]; + } + elseif ($codepoint < 0) + { + return $cache[$codepoint] = false; + } + else if ($codepoint <= 0x7f) + { + return $cache[$codepoint] = chr($codepoint); + } + else if ($codepoint <= 0x7ff) + { + return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f)); + } + else if ($codepoint <= 0xffff) + { + return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); + } + else if ($codepoint <= 0x10ffff) + { + return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); + } + else + { + // U+FFFD REPLACEMENT CHARACTER + return $cache[$codepoint] = "\xEF\xBF\xBD"; + } + } + + /** + * Re-implementation of PHP 5's stripos() + * + * Returns the numeric position of the first occurrence of needle in the + * haystack string. + * + * @static + * @access string + * @param object $haystack + * @param string $needle Note that the needle may be a string of one or more + * characters. If needle is not a string, it is converted to an integer + * and applied as the ordinal value of a character. + * @param int $offset The optional offset parameter allows you to specify which + * character in haystack to start searching. The position returned is still + * relative to the beginning of haystack. + * @return bool If needle is not found, stripos() will return boolean false. + */ + function stripos($haystack, $needle, $offset = 0) + { + if (function_exists('stripos')) + { + return stripos($haystack, $needle, $offset); + } + else + { + if (is_string($needle)) + { + $needle = strtolower($needle); + } + elseif (is_int($needle) || is_bool($needle) || is_double($needle)) + { + $needle = strtolower(chr($needle)); + } + else + { + trigger_error('needle is not a string or an integer', E_USER_WARNING); + return false; + } + + return strpos(strtolower($haystack), $needle, $offset); + } + } + + /** + * Similar to parse_str() + * + * Returns an associative array of name/value pairs, where the value is an + * array of values that have used the same name + * + * @static + * @access string + * @param string $str The input string. + * @return array + */ + function parse_str($str) + { + $return = array(); + $str = explode('&', $str); + + foreach ($str as $section) + { + if (strpos($section, '=') !== false) + { + list($name, $value) = explode('=', $section, 2); + $return[urldecode($name)][] = urldecode($value); + } + else + { + $return[urldecode($section)][] = null; + } + } + + return $return; + } + + /** + * Detect XML encoding, as per XML 1.0 Appendix F.1 + * + * @todo Add support for EBCDIC + * @param string $data XML data + * @return array Possible encodings + */ + function xml_encoding($data) + { + // UTF-32 Big Endian BOM + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") + { + $encoding[] = 'UTF-32BE'; + } + // UTF-32 Little Endian BOM + elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") + { + $encoding[] = 'UTF-32LE'; + } + // UTF-16 Big Endian BOM + elseif (substr($data, 0, 2) === "\xFE\xFF") + { + $encoding[] = 'UTF-16BE'; + } + // UTF-16 Little Endian BOM + elseif (substr($data, 0, 2) === "\xFF\xFE") + { + $encoding[] = 'UTF-16LE'; + } + // UTF-8 BOM + elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") + { + $encoding[] = 'UTF-8'; + } + // UTF-32 Big Endian Without BOM + elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C") + { + if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-32BE'; + } + // UTF-32 Little Endian Without BOM + elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00") + { + if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-32LE'; + } + // UTF-16 Big Endian Without BOM + elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C") + { + if ($pos = strpos($data, "\x00\x3F\x00\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-16BE'; + } + // UTF-16 Little Endian Without BOM + elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00") + { + if ($pos = strpos($data, "\x3F\x00\x3E\x00")) + { + $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-16LE'; + } + // US-ASCII (or superset) + elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C") + { + if ($pos = strpos($data, "\x3F\x3E")) + { + $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); + if ($parser->parse()) + { + $encoding[] = $parser->encoding; + } + } + $encoding[] = 'UTF-8'; + } + // Fallback to UTF-8 + else + { + $encoding[] = 'UTF-8'; + } + return $encoding; + } +} + +/** + * Decode HTML Entities + * + * This implements HTML5 as of revision 967 (2007-06-28) + * + * @package SimplePie + */ +class SimplePie_Decode_HTML_Entities +{ + /** + * Data to be parsed + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Currently consumed bytes + * + * @access private + * @var string + */ + var $consumed = ''; + + /** + * Position of the current byte being parsed + * + * @access private + * @var int + */ + var $position = 0; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_Decode_HTML_Entities($data) + { + $this->data = $data; + } + + /** + * Parse the input data + * + * @access public + * @return string Output data + */ + function parse() + { + while (($this->position = strpos($this->data, '&', $this->position)) !== false) + { + $this->consume(); + $this->entity(); + $this->consumed = ''; + } + return $this->data; + } + + /** + * Consume the next byte + * + * @access private + * @return mixed The next byte, or false, if there is no more data + */ + function consume() + { + if (isset($this->data[$this->position])) + { + $this->consumed .= $this->data[$this->position]; + return $this->data[$this->position++]; + } + else + { + $this->consumed = false; + return false; + } + } + + /** + * Consume a range of characters + * + * @access private + * @param string $chars Characters to consume + * @return mixed A series of characters that match the range, or false + */ + function consume_range($chars) + { + if ($len = strspn($this->data, $chars, $this->position)) + { + $data = substr($this->data, $this->position, $len); + $this->consumed .= $data; + $this->position += $len; + return $data; + } + else + { + $this->consumed = false; + return false; + } + } + + /** + * Unconsume one byte + * + * @access private + */ + function unconsume() + { + $this->consumed = substr($this->consumed, 0, -1); + $this->position--; + } + + /** + * Decode an entity + * + * @access private + */ + function entity() + { + switch ($this->consume()) + { + case "\x09": + case "\x0A": + case "\x0B": + case "\x0B": + case "\x0C": + case "\x20": + case "\x3C": + case "\x26": + case false: + break; + + case "\x23": + switch ($this->consume()) + { + case "\x78": + case "\x58": + $range = '0123456789ABCDEFabcdef'; + $hex = true; + break; + + default: + $range = '0123456789'; + $hex = false; + $this->unconsume(); + break; + } + + if ($codepoint = $this->consume_range($range)) + { + static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8"); + + if ($hex) + { + $codepoint = hexdec($codepoint); + } + else + { + $codepoint = intval($codepoint); + } + + if (isset($windows_1252_specials[$codepoint])) + { + $replacement = $windows_1252_specials[$codepoint]; + } + else + { + $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint); + } + + if ($this->consume() != ';') + { + $this->unconsume(); + } + + $consumed_length = strlen($this->consumed); + $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length); + $this->position += strlen($replacement) - $consumed_length; + } + break; + + default: + static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C"); + + for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++) + { + $consumed = substr($this->consumed, 1); + if (isset($entities[$consumed])) + { + $match = $consumed; + } + } + + if ($match !== null) + { + $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1); + $this->position += strlen($entities[$match]) - strlen($consumed) - 1; + } + break; + } + } +} + +/** + * Date Parser + * + * @package SimplePie + */ +class SimplePie_Parse_Date +{ + /** + * Input data + * + * @access protected + * @var string + */ + var $date; + + /** + * List of days, calendar day name => ordinal day number in the week + * + * @access protected + * @var array + */ + var $day = array( + // English + 'mon' => 1, + 'monday' => 1, + 'tue' => 2, + 'tuesday' => 2, + 'wed' => 3, + 'wednesday' => 3, + 'thu' => 4, + 'thursday' => 4, + 'fri' => 5, + 'friday' => 5, + 'sat' => 6, + 'saturday' => 6, + 'sun' => 7, + 'sunday' => 7, + // Dutch + 'maandag' => 1, + 'dinsdag' => 2, + 'woensdag' => 3, + 'donderdag' => 4, + 'vrijdag' => 5, + 'zaterdag' => 6, + 'zondag' => 7, + // French + 'lundi' => 1, + 'mardi' => 2, + 'mercredi' => 3, + 'jeudi' => 4, + 'vendredi' => 5, + 'samedi' => 6, + 'dimanche' => 7, + // German + 'montag' => 1, + 'dienstag' => 2, + 'mittwoch' => 3, + 'donnerstag' => 4, + 'freitag' => 5, + 'samstag' => 6, + 'sonnabend' => 6, + 'sonntag' => 7, + // Italian + 'lunedì' => 1, + 'martedì' => 2, + 'mercoledì' => 3, + 'giovedì' => 4, + 'venerdì' => 5, + 'sabato' => 6, + 'domenica' => 7, + // Spanish + 'lunes' => 1, + 'martes' => 2, + 'miércoles' => 3, + 'jueves' => 4, + 'viernes' => 5, + 'sábado' => 6, + 'domingo' => 7, + // Finnish + 'maanantai' => 1, + 'tiistai' => 2, + 'keskiviikko' => 3, + 'torstai' => 4, + 'perjantai' => 5, + 'lauantai' => 6, + 'sunnuntai' => 7, + // Hungarian + 'hétfő' => 1, + 'kedd' => 2, + 'szerda' => 3, + 'csütörtok' => 4, + 'péntek' => 5, + 'szombat' => 6, + 'vasárnap' => 7, + // Greek + 'Δευ' => 1, + 'Τρι' => 2, + 'Τετ' => 3, + 'Πεμ' => 4, + 'Παρ' => 5, + 'Σαβ' => 6, + 'Κυρ' => 7, + ); + + /** + * List of months, calendar month name => calendar month number + * + * @access protected + * @var array + */ + var $month = array( + // English + 'jan' => 1, + 'january' => 1, + 'feb' => 2, + 'february' => 2, + 'mar' => 3, + 'march' => 3, + 'apr' => 4, + 'april' => 4, + 'may' => 5, + // No long form of May + 'jun' => 6, + 'june' => 6, + 'jul' => 7, + 'july' => 7, + 'aug' => 8, + 'august' => 8, + 'sep' => 9, + 'september' => 8, + 'oct' => 10, + 'october' => 10, + 'nov' => 11, + 'november' => 11, + 'dec' => 12, + 'december' => 12, + // Dutch + 'januari' => 1, + 'februari' => 2, + 'maart' => 3, + 'april' => 4, + 'mei' => 5, + 'juni' => 6, + 'juli' => 7, + 'augustus' => 8, + 'september' => 9, + 'oktober' => 10, + 'november' => 11, + 'december' => 12, + // French + 'janvier' => 1, + 'février' => 2, + 'mars' => 3, + 'avril' => 4, + 'mai' => 5, + 'juin' => 6, + 'juillet' => 7, + 'août' => 8, + 'septembre' => 9, + 'octobre' => 10, + 'novembre' => 11, + 'décembre' => 12, + // German + 'januar' => 1, + 'februar' => 2, + 'märz' => 3, + 'april' => 4, + 'mai' => 5, + 'juni' => 6, + 'juli' => 7, + 'august' => 8, + 'september' => 9, + 'oktober' => 10, + 'november' => 11, + 'dezember' => 12, + // Italian + 'gennaio' => 1, + 'febbraio' => 2, + 'marzo' => 3, + 'aprile' => 4, + 'maggio' => 5, + 'giugno' => 6, + 'luglio' => 7, + 'agosto' => 8, + 'settembre' => 9, + 'ottobre' => 10, + 'novembre' => 11, + 'dicembre' => 12, + // Spanish + 'enero' => 1, + 'febrero' => 2, + 'marzo' => 3, + 'abril' => 4, + 'mayo' => 5, + 'junio' => 6, + 'julio' => 7, + 'agosto' => 8, + 'septiembre' => 9, + 'setiembre' => 9, + 'octubre' => 10, + 'noviembre' => 11, + 'diciembre' => 12, + // Finnish + 'tammikuu' => 1, + 'helmikuu' => 2, + 'maaliskuu' => 3, + 'huhtikuu' => 4, + 'toukokuu' => 5, + 'kesäkuu' => 6, + 'heinäkuu' => 7, + 'elokuu' => 8, + 'suuskuu' => 9, + 'lokakuu' => 10, + 'marras' => 11, + 'joulukuu' => 12, + // Hungarian + 'január' => 1, + 'február' => 2, + 'március' => 3, + 'április' => 4, + 'május' => 5, + 'június' => 6, + 'július' => 7, + 'augusztus' => 8, + 'szeptember' => 9, + 'október' => 10, + 'november' => 11, + 'december' => 12, + // Greek + 'Ιαν' => 1, + 'Φεβ' => 2, + 'Μάώ' => 3, + 'Μαώ' => 3, + 'Απρ' => 4, + 'Μάι' => 5, + 'Μαϊ' => 5, + 'Μαι' => 5, + 'Ιούν' => 6, + 'Ιον' => 6, + 'Ιούλ' => 7, + 'Ιολ' => 7, + 'Αύγ' => 8, + 'Αυγ' => 8, + 'Σεπ' => 9, + 'Οκτ' => 10, + 'Νοέ' => 11, + 'Δεκ' => 12, + ); + + /** + * List of timezones, abbreviation => offset from UTC + * + * @access protected + * @var array + */ + var $timezone = array( + 'ACDT' => 37800, + 'ACIT' => 28800, + 'ACST' => 34200, + 'ACT' => -18000, + 'ACWDT' => 35100, + 'ACWST' => 31500, + 'AEDT' => 39600, + 'AEST' => 36000, + 'AFT' => 16200, + 'AKDT' => -28800, + 'AKST' => -32400, + 'AMDT' => 18000, + 'AMT' => -14400, + 'ANAST' => 46800, + 'ANAT' => 43200, + 'ART' => -10800, + 'AZOST' => -3600, + 'AZST' => 18000, + 'AZT' => 14400, + 'BIOT' => 21600, + 'BIT' => -43200, + 'BOT' => -14400, + 'BRST' => -7200, + 'BRT' => -10800, + 'BST' => 3600, + 'BTT' => 21600, + 'CAST' => 18000, + 'CAT' => 7200, + 'CCT' => 23400, + 'CDT' => -18000, + 'CEDT' => 7200, + 'CET' => 3600, + 'CGST' => -7200, + 'CGT' => -10800, + 'CHADT' => 49500, + 'CHAST' => 45900, + 'CIST' => -28800, + 'CKT' => -36000, + 'CLDT' => -10800, + 'CLST' => -14400, + 'COT' => -18000, + 'CST' => -21600, + 'CVT' => -3600, + 'CXT' => 25200, + 'DAVT' => 25200, + 'DTAT' => 36000, + 'EADT' => -18000, + 'EAST' => -21600, + 'EAT' => 10800, + 'ECT' => -18000, + 'EDT' => -14400, + 'EEST' => 10800, + 'EET' => 7200, + 'EGT' => -3600, + 'EKST' => 21600, + 'EST' => -18000, + 'FJT' => 43200, + 'FKDT' => -10800, + 'FKST' => -14400, + 'FNT' => -7200, + 'GALT' => -21600, + 'GEDT' => 14400, + 'GEST' => 10800, + 'GFT' => -10800, + 'GILT' => 43200, + 'GIT' => -32400, + 'GST' => 14400, + 'GST' => -7200, + 'GYT' => -14400, + 'HAA' => -10800, + 'HAC' => -18000, + 'HADT' => -32400, + 'HAE' => -14400, + 'HAP' => -25200, + 'HAR' => -21600, + 'HAST' => -36000, + 'HAT' => -9000, + 'HAY' => -28800, + 'HKST' => 28800, + 'HMT' => 18000, + 'HNA' => -14400, + 'HNC' => -21600, + 'HNE' => -18000, + 'HNP' => -28800, + 'HNR' => -25200, + 'HNT' => -12600, + 'HNY' => -32400, + 'IRDT' => 16200, + 'IRKST' => 32400, + 'IRKT' => 28800, + 'IRST' => 12600, + 'JFDT' => -10800, + 'JFST' => -14400, + 'JST' => 32400, + 'KGST' => 21600, + 'KGT' => 18000, + 'KOST' => 39600, + 'KOVST' => 28800, + 'KOVT' => 25200, + 'KRAST' => 28800, + 'KRAT' => 25200, + 'KST' => 32400, + 'LHDT' => 39600, + 'LHST' => 37800, + 'LINT' => 50400, + 'LKT' => 21600, + 'MAGST' => 43200, + 'MAGT' => 39600, + 'MAWT' => 21600, + 'MDT' => -21600, + 'MESZ' => 7200, + 'MEZ' => 3600, + 'MHT' => 43200, + 'MIT' => -34200, + 'MNST' => 32400, + 'MSDT' => 14400, + 'MSST' => 10800, + 'MST' => -25200, + 'MUT' => 14400, + 'MVT' => 18000, + 'MYT' => 28800, + 'NCT' => 39600, + 'NDT' => -9000, + 'NFT' => 41400, + 'NMIT' => 36000, + 'NOVST' => 25200, + 'NOVT' => 21600, + 'NPT' => 20700, + 'NRT' => 43200, + 'NST' => -12600, + 'NUT' => -39600, + 'NZDT' => 46800, + 'NZST' => 43200, + 'OMSST' => 25200, + 'OMST' => 21600, + 'PDT' => -25200, + 'PET' => -18000, + 'PETST' => 46800, + 'PETT' => 43200, + 'PGT' => 36000, + 'PHOT' => 46800, + 'PHT' => 28800, + 'PKT' => 18000, + 'PMDT' => -7200, + 'PMST' => -10800, + 'PONT' => 39600, + 'PST' => -28800, + 'PWT' => 32400, + 'PYST' => -10800, + 'PYT' => -14400, + 'RET' => 14400, + 'ROTT' => -10800, + 'SAMST' => 18000, + 'SAMT' => 14400, + 'SAST' => 7200, + 'SBT' => 39600, + 'SCDT' => 46800, + 'SCST' => 43200, + 'SCT' => 14400, + 'SEST' => 3600, + 'SGT' => 28800, + 'SIT' => 28800, + 'SRT' => -10800, + 'SST' => -39600, + 'SYST' => 10800, + 'SYT' => 7200, + 'TFT' => 18000, + 'THAT' => -36000, + 'TJT' => 18000, + 'TKT' => -36000, + 'TMT' => 18000, + 'TOT' => 46800, + 'TPT' => 32400, + 'TRUT' => 36000, + 'TVT' => 43200, + 'TWT' => 28800, + 'UYST' => -7200, + 'UYT' => -10800, + 'UZT' => 18000, + 'VET' => -14400, + 'VLAST' => 39600, + 'VLAT' => 36000, + 'VOST' => 21600, + 'VUT' => 39600, + 'WAST' => 7200, + 'WAT' => 3600, + 'WDT' => 32400, + 'WEST' => 3600, + 'WFT' => 43200, + 'WIB' => 25200, + 'WIT' => 32400, + 'WITA' => 28800, + 'WKST' => 18000, + 'WST' => 28800, + 'YAKST' => 36000, + 'YAKT' => 32400, + 'YAPT' => 36000, + 'YEKST' => 21600, + 'YEKT' => 18000, + ); + + /** + * Cached PCRE for SimplePie_Parse_Date::$day + * + * @access protected + * @var string + */ + var $day_pcre; + + /** + * Cached PCRE for SimplePie_Parse_Date::$month + * + * @access protected + * @var string + */ + var $month_pcre; + + /** + * Array of user-added callback methods + * + * @access private + * @var array + */ + var $built_in = array(); + + /** + * Array of user-added callback methods + * + * @access private + * @var array + */ + var $user = array(); + + /** + * Create new SimplePie_Parse_Date object, and set self::day_pcre, + * self::month_pcre, and self::built_in + * + * @access private + */ + function SimplePie_Parse_Date() + { + $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')'; + $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')'; + + static $cache; + if (!isset($cache[get_class($this)])) + { + if (extension_loaded('Reflection')) + { + $class = new ReflectionClass(get_class($this)); + $methods = $class->getMethods(); + $all_methods = array(); + foreach ($methods as $method) + { + $all_methods[] = $method->getName(); + } + } + else + { + $all_methods = get_class_methods($this); + } + + foreach ($all_methods as $method) + { + if (strtolower(substr($method, 0, 5)) === 'date_') + { + $cache[get_class($this)][] = $method; + } + } + } + + foreach ($cache[get_class($this)] as $method) + { + $this->built_in[] = $method; + } + } + + /** + * Get the object + * + * @access public + */ + function get() + { + static $object; + if (!$object) + { + $object = new SimplePie_Parse_Date; + } + return $object; + } + + /** + * Parse a date + * + * @final + * @access public + * @param string $date Date to parse + * @return int Timestamp corresponding to date string, or false on failure + */ + function parse($date) + { + foreach ($this->user as $method) + { + if (($returned = call_user_func($method, $date)) !== false) + { + return $returned; + } + } + + foreach ($this->built_in as $method) + { + if (($returned = call_user_func(array(&$this, $method), $date)) !== false) + { + return $returned; + } + } + + return false; + } + + /** + * Add a callback method to parse a date + * + * @final + * @access public + * @param callback $callback + */ + function add_callback($callback) + { + if (is_callable($callback)) + { + $this->user[] = $callback; + } + else + { + trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); + } + } + + /** + * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as + * well as allowing any of upper or lower case "T", horizontal tabs, or + * spaces to be used as the time seperator (including more than one)) + * + * @access protected + * @return int Timestamp + */ + function date_w3cdtf($date) + { + static $pcre; + if (!$pcre) + { + $year = '([0-9]{4})'; + $month = $day = $hour = $minute = $second = '([0-9]{2})'; + $decimal = '([0-9]*)'; + $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))'; + $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Year + 2: Month + 3: Day + 4: Hour + 5: Minute + 6: Second + 7: Decimal fraction of a second + 8: Zulu + 9: Timezone ± + 10: Timezone hours + 11: Timezone minutes + */ + + // Fill in empty matches + for ($i = count($match); $i <= 3; $i++) + { + $match[$i] = '1'; + } + + for ($i = count($match); $i <= 7; $i++) + { + $match[$i] = '0'; + } + + // Numeric timezone + if (isset($match[9]) && $match[9] !== '') + { + $timezone = $match[10] * 3600; + $timezone += $match[11] * 60; + if ($match[9] === '-') + { + $timezone = 0 - $timezone; + } + } + else + { + $timezone = 0; + } + + // Convert the number of seconds to an integer, taking decimals into account + $second = round($match[6] + $match[7] / pow(10, strlen($match[7]))); + + return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; + } + else + { + return false; + } + } + + /** + * Remove RFC822 comments + * + * @access protected + * @param string $data Data to strip comments from + * @return string Comment stripped string + */ + function remove_rfc2822_comments($string) + { + $string = (string) $string; + $position = 0; + $length = strlen($string); + $depth = 0; + + $output = ''; + + while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) + { + $output .= substr($string, $position, $pos - $position); + $position = $pos + 1; + if ($string[$pos - 1] !== '\\') + { + $depth++; + while ($depth && $position < $length) + { + $position += strcspn($string, '()', $position); + if ($string[$position - 1] === '\\') + { + $position++; + continue; + } + elseif (isset($string[$position])) + { + switch ($string[$position]) + { + case '(': + $depth++; + break; + + case ')': + $depth--; + break; + } + $position++; + } + else + { + break; + } + } + } + else + { + $output .= '('; + } + } + $output .= substr($string, $position); + + return $output; + } + + /** + * Parse RFC2822's date format + * + * @access protected + * @return int Timestamp + */ + function date_rfc2822($date) + { + static $pcre; + if (!$pcre) + { + $wsp = '[\x09\x20]'; + $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; + $optional_fws = $fws . '?'; + $day_name = $this->day_pcre; + $month = $this->month_pcre; + $day = '([0-9]{1,2})'; + $hour = $minute = $second = '([0-9]{2})'; + $year = '([0-9]{2,4})'; + $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; + $character_zone = '([A-Z]{1,5})'; + $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; + $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i'; + } + if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Day + 3: Month + 4: Year + 5: Hour + 6: Minute + 7: Second + 8: Timezone ± + 9: Timezone hours + 10: Timezone minutes + 11: Alphabetic timezone + */ + + // Find the month number + $month = $this->month[strtolower($match[3])]; + + // Numeric timezone + if ($match[8] !== '') + { + $timezone = $match[9] * 3600; + $timezone += $match[10] * 60; + if ($match[8] === '-') + { + $timezone = 0 - $timezone; + } + } + // Character timezone + elseif (isset($this->timezone[strtoupper($match[11])])) + { + $timezone = $this->timezone[strtoupper($match[11])]; + } + // Assume everything else to be -0000 + else + { + $timezone = 0; + } + + // Deal with 2/3 digit years + if ($match[4] < 50) + { + $match[4] += 2000; + } + elseif ($match[4] < 1000) + { + $match[4] += 1900; + } + + // Second is optional, if it is empty set it to zero + if ($match[7] !== '') + { + $second = $match[7]; + } + else + { + $second = 0; + } + + return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; + } + else + { + return false; + } + } + + /** + * Parse RFC850's date format + * + * @access protected + * @return int Timestamp + */ + function date_rfc850($date) + { + static $pcre; + if (!$pcre) + { + $space = '[\x09\x20]+'; + $day_name = $this->day_pcre; + $month = $this->month_pcre; + $day = '([0-9]{1,2})'; + $year = $hour = $minute = $second = '([0-9]{2})'; + $zone = '([A-Z]{1,5})'; + $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Day + 3: Month + 4: Year + 5: Hour + 6: Minute + 7: Second + 8: Timezone + */ + + // Month + $month = $this->month[strtolower($match[3])]; + + // Character timezone + if (isset($this->timezone[strtoupper($match[8])])) + { + $timezone = $this->timezone[strtoupper($match[8])]; + } + // Assume everything else to be -0000 + else + { + $timezone = 0; + } + + // Deal with 2 digit year + if ($match[4] < 50) + { + $match[4] += 2000; + } + else + { + $match[4] += 1900; + } + + return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; + } + else + { + return false; + } + } + + /** + * Parse C99's asctime()'s date format + * + * @access protected + * @return int Timestamp + */ + function date_asctime($date) + { + static $pcre; + if (!$pcre) + { + $space = '[\x09\x20]+'; + $wday_name = $this->day_pcre; + $mon_name = $this->month_pcre; + $day = '([0-9]{1,2})'; + $hour = $sec = $min = '([0-9]{2})'; + $year = '([0-9]{4})'; + $terminator = '\x0A?\x00?'; + $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; + } + if (preg_match($pcre, $date, $match)) + { + /* + Capturing subpatterns: + 1: Day name + 2: Month + 3: Day + 4: Hour + 5: Minute + 6: Second + 7: Year + */ + + $month = $this->month[strtolower($match[2])]; + return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); + } + else + { + return false; + } + } + + /** + * Parse dates using strtotime() + * + * @access protected + * @return int Timestamp + */ + function date_strtotime($date) + { + $strtotime = strtotime($date); + if ($strtotime === -1 || $strtotime === false) + { + return false; + } + else + { + return $strtotime; + } + } +} + +/** + * Content-type sniffing + * + * @package SimplePie + */ +class SimplePie_Content_Type_Sniffer +{ + /** + * File object + * + * @var SimplePie_File + * @access private + */ + var $file; + + /** + * Create an instance of the class with the input file + * + * @access public + * @param SimplePie_Content_Type_Sniffer $file Input file + */ + function SimplePie_Content_Type_Sniffer($file) + { + $this->file = $file; + } + + /** + * Get the Content-Type of the specified file + * + * @access public + * @return string Actual Content-Type + */ + function get_type() + { + if (isset($this->file->headers['content-type'])) + { + if (!isset($this->file->headers['content-encoding']) + && ($this->file->headers['content-type'] === 'text/plain' + || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1' + || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1')) + { + return $this->text_or_binary(); + } + + if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) + { + $official = substr($this->file->headers['content-type'], 0, $pos); + } + else + { + $official = $this->file->headers['content-type']; + } + $official = strtolower($official); + + if ($official === 'unknown/unknown' + || $official === 'application/unknown') + { + return $this->unknown(); + } + elseif (substr($official, -4) === '+xml' + || $official === 'text/xml' + || $official === 'application/xml') + { + return $official; + } + elseif (substr($official, 0, 6) === 'image/') + { + if ($return = $this->image()) + { + return $return; + } + else + { + return $official; + } + } + elseif ($official === 'text/html') + { + return $this->feed_or_html(); + } + else + { + return $official; + } + } + else + { + return $this->unknown(); + } + } + + /** + * Sniff text or binary + * + * @access private + * @return string Actual Content-Type + */ + function text_or_binary() + { + if (substr($this->file->body, 0, 2) === "\xFE\xFF" + || substr($this->file->body, 0, 2) === "\xFF\xFE" + || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF" + || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") + { + return 'text/plain'; + } + elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) + { + return 'application/octect-stream'; + } + else + { + return 'text/plain'; + } + } + + /** + * Sniff unknown + * + * @access private + * @return string Actual Content-Type + */ + function unknown() + { + $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20"); + if (strtolower(substr($this->file->body, $ws, 14)) === 'file->body, $ws, 5)) === 'file->body, $ws, 7)) === 'file->body, 0, 5) === '%PDF-') + { + return 'application/pdf'; + } + elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') + { + return 'application/postscript'; + } + elseif (substr($this->file->body, 0, 6) === 'GIF87a' + || substr($this->file->body, 0, 6) === 'GIF89a') + { + return 'image/gif'; + } + elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") + { + return 'image/png'; + } + elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") + { + return 'image/jpeg'; + } + elseif (substr($this->file->body, 0, 2) === "\x42\x4D") + { + return 'image/bmp'; + } + else + { + return $this->text_or_binary(); + } + } + + /** + * Sniff images + * + * @access private + * @return string Actual Content-Type + */ + function image() + { + if (substr($this->file->body, 0, 6) === 'GIF87a' + || substr($this->file->body, 0, 6) === 'GIF89a') + { + return 'image/gif'; + } + elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") + { + return 'image/png'; + } + elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") + { + return 'image/jpeg'; + } + elseif (substr($this->file->body, 0, 2) === "\x42\x4D") + { + return 'image/bmp'; + } + else + { + return false; + } + } + + /** + * Sniff HTML + * + * @access private + * @return string Actual Content-Type + */ + function feed_or_html() + { + $len = strlen($this->file->body); + $pos = strspn($this->file->body, "\x09\x0A\x0D\x20"); + + while ($pos < $len) + { + switch ($this->file->body[$pos]) + { + case "\x09": + case "\x0A": + case "\x0D": + case "\x20": + $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos); + continue 2; + + case '<': + $pos++; + break; + + default: + return 'text/html'; + } + + if (substr($this->file->body, $pos, 3) === '!--') + { + $pos += 3; + if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) + { + $pos += 3; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 1) === '!') + { + if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) + { + $pos++; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 1) === '?') + { + if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) + { + $pos += 2; + } + else + { + return 'text/html'; + } + } + elseif (substr($this->file->body, $pos, 3) === 'rss' + || substr($this->file->body, $pos, 7) === 'rdf:RDF') + { + return 'application/rss+xml'; + } + elseif (substr($this->file->body, $pos, 4) === 'feed') + { + return 'application/atom+xml'; + } + else + { + return 'text/html'; + } + } + + return 'text/html'; + } +} + +/** + * Parses the XML Declaration + * + * @package SimplePie + */ +class SimplePie_XML_Declaration_Parser +{ + /** + * XML Version + * + * @access public + * @var string + */ + var $version = '1.0'; + + /** + * Encoding + * + * @access public + * @var string + */ + var $encoding = 'UTF-8'; + + /** + * Standalone + * + * @access public + * @var bool + */ + var $standalone = false; + + /** + * Current state of the state machine + * + * @access private + * @var string + */ + var $state = 'before_version_name'; + + /** + * Input data + * + * @access private + * @var string + */ + var $data = ''; + + /** + * Input data length (to avoid calling strlen() everytime this is needed) + * + * @access private + * @var int + */ + var $data_length = 0; + + /** + * Current position of the pointer + * + * @var int + * @access private + */ + var $position = 0; + + /** + * Create an instance of the class with the input data + * + * @access public + * @param string $data Input data + */ + function SimplePie_XML_Declaration_Parser($data) + { + $this->data = $data; + $this->data_length = strlen($this->data); + } + + /** + * Parse the input data + * + * @access public + * @return bool true on success, false on failure + */ + function parse() + { + while ($this->state && $this->state !== 'emit' && $this->has_data()) + { + $state = $this->state; + $this->$state(); + } + $this->data = ''; + if ($this->state === 'emit') + { + return true; + } + else + { + $this->version = ''; + $this->encoding = ''; + $this->standalone = ''; + return false; + } + } + + /** + * Check whether there is data beyond the pointer + * + * @access private + * @return bool true if there is further data, false if not + */ + function has_data() + { + return (bool) ($this->position < $this->data_length); + } + + /** + * Advance past any whitespace + * + * @return int Number of whitespace characters passed + */ + function skip_whitespace() + { + $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position); + $this->position += $whitespace; + return $whitespace; + } + + /** + * Read value + */ + function get_value() + { + $quote = substr($this->data, $this->position, 1); + if ($quote === '"' || $quote === "'") + { + $this->position++; + $len = strcspn($this->data, $quote, $this->position); + if ($this->has_data()) + { + $value = substr($this->data, $this->position, $len); + $this->position += $len + 1; + return $value; + } + } + return false; + } + + function before_version_name() + { + if ($this->skip_whitespace()) + { + $this->state = 'version_name'; + } + else + { + $this->state = false; + } + } + + function version_name() + { + if (substr($this->data, $this->position, 7) === 'version') + { + $this->position += 7; + $this->skip_whitespace(); + $this->state = 'version_equals'; + } + else + { + $this->state = false; + } + } + + function version_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'version_value'; + } + else + { + $this->state = false; + } + } + + function version_value() + { + if ($this->version = $this->get_value()) + { + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = 'encoding_name'; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = 'standalone_name'; + } + } + + function encoding_name() + { + if (substr($this->data, $this->position, 8) === 'encoding') + { + $this->position += 8; + $this->skip_whitespace(); + $this->state = 'encoding_equals'; + } + else + { + $this->state = false; + } + } + + function encoding_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'encoding_value'; + } + else + { + $this->state = false; + } + } + + function encoding_value() + { + if ($this->encoding = $this->get_value()) + { + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = 'standalone_name'; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = false; + } + } + + function standalone_name() + { + if (substr($this->data, $this->position, 10) === 'standalone') + { + $this->position += 10; + $this->skip_whitespace(); + $this->state = 'standalone_equals'; + } + else + { + $this->state = false; + } + } + + function standalone_equals() + { + if (substr($this->data, $this->position, 1) === '=') + { + $this->position++; + $this->skip_whitespace(); + $this->state = 'standalone_value'; + } + else + { + $this->state = false; + } + } + + function standalone_value() + { + if ($standalone = $this->get_value()) + { + switch ($standalone) + { + case 'yes': + $this->standalone = true; + break; + + case 'no': + $this->standalone = false; + break; + + default: + $this->state = false; + return; + } + + $this->skip_whitespace(); + if ($this->has_data()) + { + $this->state = false; + } + else + { + $this->state = 'emit'; + } + } + else + { + $this->state = false; + } + } +} + +class SimplePie_Locator +{ + var $useragent; + var $timeout; + var $file; + var $local = array(); + var $elsewhere = array(); + var $file_class = 'SimplePie_File'; + var $cached_entities = array(); + var $http_base; + var $base; + var $base_location = 0; + var $checked_feeds = 0; + var $max_checked_feeds = 10; + var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; + + function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer') + { + $this->file =& $file; + $this->file_class = $file_class; + $this->useragent = $useragent; + $this->timeout = $timeout; + $this->max_checked_feeds = $max_checked_feeds; + $this->content_type_sniffer_class; + } + + function find($type = SIMPLEPIE_LOCATOR_ALL) + { + if ($this->is_feed($this->file)) + { + return $this->file; + } + + if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) + { + $sniffer = new $this->content_type_sniffer_class($this->file); + if ($sniffer->get_type() !== 'text/html') + { + return null; + } + } + + if ($type & ~SIMPLEPIE_LOCATOR_NONE) + { + $this->get_base(); + } + + if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) + { + return $working; + } + + if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) + { + if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) + { + return $working; + } + + if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) + { + return $working; + } + } + return null; + } + + function is_feed(&$file) + { + if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) + { + $sniffer = new $this->content_type_sniffer_class($file); + $sniffed = $sniffer->get_type(); + if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain'))) + { + return true; + } + else + { + return false; + } + } + elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) + { + return true; + } + else + { + return false; + } + } + + function get_base() + { + $this->http_base = $this->file->url; + $this->base = $this->http_base; + $elements = SimplePie_Misc::get_element('base', $this->file->body); + foreach ($elements as $element) + { + if ($element['attribs']['href']['data'] !== '') + { + $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base); + $this->base_location = $element['offset']; + break; + } + } + } + + function autodiscovery() + { + $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body)); + $done = array(); + foreach ($links as $link) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data'])) + { + $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data']))); + + if ($this->base_location < $link['offset']) + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); + } + else + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); + } + + if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml')))) + { + $this->checked_feeds++; + $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + } + $done[] = $href; + } + } + return null; + } + + function get_links() + { + $links = SimplePie_Misc::get_element('a', $this->file->body); + foreach ($links as $link) + { + if (isset($link['attribs']['href']['data'])) + { + $href = trim($link['attribs']['href']['data']); + $parsed = SimplePie_Misc::parse_url($href); + if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) + { + if ($this->base_location < $link['offset']) + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); + } + else + { + $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); + } + + $current = SimplePie_Misc::parse_url($this->file->url); + + if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority']) + { + $this->local[] = $href; + } + else + { + $this->elsewhere[] = $href; + } + } + } + } + $this->local = array_unique($this->local); + $this->elsewhere = array_unique($this->elsewhere); + if (!empty($this->local) || !empty($this->elsewhere)) + { + return true; + } + return null; + } + + function extension(&$array) + { + foreach ($array as $key => $value) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) + { + $this->checked_feeds++; + $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + else + { + unset($array[$key]); + } + } + } + return null; + } + + function body(&$array) + { + foreach ($array as $key => $value) + { + if ($this->checked_feeds == $this->max_checked_feeds) + { + break; + } + if (preg_match('/(rss|rdf|atom|xml)/i', $value)) + { + $this->checked_feeds++; + $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); + if ($this->is_feed($feed)) + { + return $feed; + } + else + { + unset($array[$key]); + } + } + } + return null; + } +} + +class SimplePie_Parser +{ + var $error_code; + var $error_string; + var $current_line; + var $current_column; + var $current_byte; + var $separator = ' '; + var $feed = false; + var $namespace = array(''); + var $element = array(''); + var $xml_base = array(''); + var $xml_base_explicit = array(false); + var $xml_lang = array(''); + var $data = array(); + var $datas = array(array()); + var $current_xhtml_construct = -1; + var $encoding; + + function parse(&$data, $encoding) + { + // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character + if (strtoupper($encoding) == 'US-ASCII') + { + $this->encoding = 'UTF-8'; + } + else + { + $this->encoding = $encoding; + } + + // Strip BOM: + // UTF-32 Big Endian BOM + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") + { + $data = substr($data, 4); + } + // UTF-32 Little Endian BOM + elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") + { + $data = substr($data, 4); + } + // UTF-16 Big Endian BOM + elseif (substr($data, 0, 2) === "\xFE\xFF") + { + $data = substr($data, 2); + } + // UTF-16 Little Endian BOM + elseif (substr($data, 0, 2) === "\xFF\xFE") + { + $data = substr($data, 2); + } + // UTF-8 BOM + elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") + { + $data = substr($data, 3); + } + + if (substr($data, 0, 5) === '')) !== false) + { + $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); + if ($declaration->parse()) + { + $data = substr($data, $pos + 2); + $data = 'version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data; + } + else + { + $this->error_string = 'SimplePie bug! Please report this!'; + return false; + } + } + + $return = true; + + // Create the parser + $xml = xml_parser_create_ns($this->encoding, $this->separator); + xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xml, $this); + xml_set_character_data_handler($xml, 'cdata'); + xml_set_element_handler($xml, 'tag_open', 'tag_close'); + + // Parse! + if (!xml_parse($xml, $data, true)) + { + $this->error_code = xml_get_error_code($xml); + $this->error_string = xml_error_string($this->error_code); + $return = false; + } + $this->current_line = xml_get_current_line_number($xml); + $this->current_column = xml_get_current_column_number($xml); + $this->current_byte = xml_get_current_byte_index($xml); + xml_parser_free($xml); + return $return; + } + + function get_error_code() + { + return $this->error_code; + } + + function get_error_string() + { + return $this->error_string; + } + + function get_current_line() + { + return $this->current_line; + } + + function get_current_column() + { + return $this->current_column; + } + + function get_current_byte() + { + return $this->current_byte; + } + + function get_data() + { + return $this->data; + } + + function tag_open($parser, $tag, $attributes) + { + if ($this->feed === 0) + { + return; + } + elseif ($this->feed == false) + { + if (in_array($tag, array( + SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed', + SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed', + 'rss', + SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF' + ))) + { + $this->feed = 1; + } + } + else + { + $this->feed++; + } + + list($this->namespace[], $this->element[]) = $this->split_ns($tag); + + $attribs = array(); + foreach ($attributes as $name => $value) + { + list($attrib_namespace, $attribute) = $this->split_ns($name); + $attribs[$attrib_namespace][$attribute] = $value; + } + + if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base'])) + { + $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)); + $this->xml_base_explicit[] = true; + } + else + { + $this->xml_base[] = end($this->xml_base); + $this->xml_base_explicit[] = end($this->xml_base_explicit); + } + + if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang'])) + { + $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang']; + } + else + { + $this->xml_lang[] = end($this->xml_lang); + } + + if ($this->current_xhtml_construct >= 0) + { + $this->current_xhtml_construct++; + if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML) + { + $this->data['data'] .= '<' . end($this->element); + if (isset($attribs[''])) + { + foreach ($attribs[''] as $name => $value) + { + $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"'; + } + } + $this->data['data'] .= '>'; + } + } + else + { + $this->datas[] =& $this->data; + $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][]; + $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang)); + if ((end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] == 'xml') + || (end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] == 'xhtml')) + { + $this->current_xhtml_construct = 0; + } + } + } + + function cdata($parser, $cdata) + { + if ($this->current_xhtml_construct >= 0) + { + $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding); + } + elseif ($this->feed > 1) + { + $this->data['data'] .= $cdata; + } + } + + function tag_close($parser, $tag) + { + if (!$this->feed) + { + return; + } + + if ($this->current_xhtml_construct >= 0) + { + $this->current_xhtml_construct--; + if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'))) + { + $this->data['data'] .= 'element) . '>'; + } + } + if ($this->current_xhtml_construct == -1) + { + $this->data =& $this->datas[$this->feed]; + array_pop($this->datas); + } + + array_pop($this->element); + array_pop($this->namespace); + array_pop($this->xml_base); + array_pop($this->xml_base_explicit); + array_pop($this->xml_lang); + $this->feed--; + } + + function split_ns($string) + { + static $cache = array(); + if (!isset($cache[$string])) + { + if ($pos = strpos($string, $this->separator)) + { + static $separator_length; + if (!$separator_length) + { + $separator_length = strlen($this->separator); + } + $namespace = substr($string, 0, $pos); + $local_name = substr($string, $pos + $separator_length); + if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES) + { + $namespace = SIMPLEPIE_NAMESPACE_ITUNES; + } + $cache[$string] = array($namespace, $local_name); + } + else + { + $cache[$string] = array('', $string); + } + } + return $cache[$string]; + } +} + +/** + * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags + */ +class SimplePie_Sanitize +{ + // Private vars + var $base; + + // Options + var $remove_div = true; + var $image_handler = ''; + var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); + var $encode_instead_of_strip = false; + var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); + var $strip_comments = false; + var $output_encoding = 'UTF-8'; + var $enable_cache = true; + var $cache_location = './cache'; + var $cache_name_function = 'md5'; + var $cache_class = 'SimplePie_Cache'; + var $file_class = 'SimplePie_File'; + var $timeout = 10; + var $useragent = ''; + var $force_fsockopen = false; + + var $replace_url_attributes = array( + 'a' => 'href', + 'area' => 'href', + 'blockquote' => 'cite', + 'del' => 'cite', + 'form' => 'action', + 'img' => array('longdesc', 'src'), + 'input' => 'src', + 'ins' => 'cite', + 'q' => 'cite' + ); + + function remove_div($enable = true) + { + $this->remove_div = (bool) $enable; + } + + function set_image_handler($page = false) + { + if ($page) + { + $this->image_handler = (string) $page; + } + else + { + $this->image_handler = false; + } + } + + function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache') + { + if (isset($enable_cache)) + { + $this->enable_cache = (bool) $enable_cache; + } + + if ($cache_location) + { + $this->cache_location = (string) $cache_location; + } + + if ($cache_name_function) + { + $this->cache_name_function = (string) $cache_name_function; + } + + if ($cache_class) + { + $this->cache_class = (string) $cache_class; + } + } + + function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false) + { + if ($file_class) + { + $this->file_class = (string) $file_class; + } + + if ($timeout) + { + $this->timeout = (string) $timeout; + } + + if ($useragent) + { + $this->useragent = (string) $useragent; + } + + if ($force_fsockopen) + { + $this->force_fsockopen = (string) $force_fsockopen; + } + } + + function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) + { + if ($tags) + { + if (is_array($tags)) + { + $this->strip_htmltags = $tags; + } + else + { + $this->strip_htmltags = explode(',', $tags); + } + } + else + { + $this->strip_htmltags = false; + } + } + + function encode_instead_of_strip($encode = false) + { + $this->encode_instead_of_strip = (bool) $encode; + } + + function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc')) + { + if ($attribs) + { + if (is_array($attribs)) + { + $this->strip_attributes = $attribs; + } + else + { + $this->strip_attributes = explode(',', $attribs); + } + } + else + { + $this->strip_attributes = false; + } + } + + function strip_comments($strip = false) + { + $this->strip_comments = (bool) $strip; + } + + function set_output_encoding($encoding = 'UTF-8') + { + $this->output_encoding = (string) $encoding; + } + + /** + * Set element/attribute key/value pairs of HTML attributes + * containing URLs that need to be resolved relative to the feed + * + * @access public + * @since 1.0 + * @param array $element_attribute Element/attribute key/value pairs + */ + function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) + { + $this->replace_url_attributes = (array) $element_attribute; + } + + function sanitize($data, $type, $base = '') + { + $data = trim($data); + if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI) + { + if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) + { + if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) + { + $type |= SIMPLEPIE_CONSTRUCT_HTML; + } + else + { + $type |= SIMPLEPIE_CONSTRUCT_TEXT; + } + } + + if ($type & SIMPLEPIE_CONSTRUCT_BASE64) + { + $data = base64_decode($data); + } + + if ($type & SIMPLEPIE_CONSTRUCT_XHTML) + { + if ($this->remove_div) + { + $data = preg_replace('/^/', '', $data); + $data = preg_replace('/<\/div>$/', '', $data); + } + else + { + $data = preg_replace('/^/', '
    ', $data); + } + } + + if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) + { + // Strip comments + if ($this->strip_comments) + { + $data = SimplePie_Misc::strip_comments($data); + } + + // Strip out HTML tags and attributes that might cause various security problems. + // Based on recommendations by Mark Pilgrim at: + // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely + if ($this->strip_htmltags) + { + foreach ($this->strip_htmltags as $tag) + { + $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU'; + while (preg_match($pcre, $data)) + { + $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data); + } + } + } + + if ($this->strip_attributes) + { + foreach ($this->strip_attributes as $attrib) + { + $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data); + } + } + + // Replace relative URLs + $this->base = $base; + foreach ($this->replace_url_attributes as $element => $attributes) + { + $data = $this->replace_urls($data, $element, $attributes); + } + + // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags. + if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache) + { + $images = SimplePie_Misc::get_element('img', $data); + foreach ($images as $img) + { + if (isset($img['attribs']['src']['data'])) + { + $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']); + $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi'); + + if ($cache->load()) + { + $img['attribs']['src']['data'] = $this->image_handler . $image_url; + $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); + } + else + { + $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); + $headers = $file->headers; + + if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300))) + { + if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) + { + $img['attribs']['src']['data'] = $this->image_handler . $image_url; + $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); + } + else + { + trigger_error("$cache->name is not writeable", E_USER_WARNING); + } + } + } + } + } + } + + // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data + $data = trim($data); + } + + if ($type & SIMPLEPIE_CONSTRUCT_IRI) + { + $data = SimplePie_Misc::absolutize_url($data, $base); + } + + if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) + { + $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8'); + } + + if ($this->output_encoding != 'UTF-8') + { + $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding); + } + } + return $data; + } + + function replace_urls($data, $tag, $attributes) + { + if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags)) + { + $elements = SimplePie_Misc::get_element($tag, $data); + foreach ($elements as $element) + { + if (is_array($attributes)) + { + foreach ($attributes as $attribute) + { + if (isset($element['attribs'][$attribute]['data'])) + { + $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base); + $new_element = SimplePie_Misc::element_implode($element); + $data = str_replace($element['full'], $new_element, $data); + $element['full'] = $new_element; + } + } + } + elseif (isset($element['attribs'][$attributes]['data'])) + { + $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base); + $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data); + } + } + } + return $data; + } + + function do_strip_htmltags($match) + { + if ($this->encode_instead_of_strip) + { + if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) + { + $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8'); + $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8'); + return "<$match[1]$match[2]>$match[3]</$match[1]>"; + } + else + { + return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8'); + } + } + elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) + { + return $match[4]; + } + else + { + return ''; + } + } +} + +?> \ No newline at end of file diff --git a/system/application/libraries/sweetcron.php b/system/application/libraries/sweetcron.php new file mode 100644 index 0000000..82f2687 --- /dev/null +++ b/system/application/libraries/sweetcron.php @@ -0,0 +1,392 @@ +CI =& get_instance(); + $this->CI->config->set_item('sweetcron_version', '1.08e'); + } + + function fetch_items() + { + if(!ini_get('safe_mode')){ + //requires php to not be running in "safe mode" + set_time_limit(0); + } + //soz + $option->option_name = 'last_fetch'; + $option->option_value = time(); + $this->CI->option_model->add_option($option); + + $feeds = $this->CI->feed_model->get_active_feeds(); + if ($feeds) { + foreach ($feeds as $feed) { + $this->CI->simplepie->set_feed_url($feed->feed_url); + $this->CI->simplepie->enable_cache(FALSE); + $this->CI->simplepie->init(); + $items = $this->CI->simplepie->get_items(); + $this->add_new_items($items, $feed); + } + } + + } + + function add_new_items($items, $feed) + { + foreach ($items as $item) { + + $new->item_data = array(); + $new->item_data['title'] = $item->get_title(); + $new->item_data['permalink'] = $item->get_permalink(); + $new->item_data['content'] = $item->get_content(); + $new->item_data['enclosures'] = $item->get_enclosures(); + $new->item_data['categories'] = $item->get_categories(); + $new->item_data['tags'] = $this->get_tags($new->item_data); + $new->item_data['image'] = $this->get_image($item->get_content()); + + //build out clean item + $new->item_status = 'publish'; + $new->item_date = strtotime($item->get_date('D M j G:i:s Y')); + $new->item_title = $this->CI->input->xss_clean(trim(strip_tags($item->get_title()))); + $new->item_permalink = $item->get_permalink(); + $new->item_content = $this->CI->input->xss_clean(trim(strip_tags($item->get_content()))); + $new->item_name = url_title($new->item_title); + $new->item_feed_id = $feed->feed_id; + + $new = $this->extend('pre_db', $feed->feed_domain, $new, $item); + + //and add + $this->CI->item_model->add_item($new); + + } + } + + function pseudo_cron() + { + if ($this->CI->config->item('cron_type') == 'pseudo') { + //time in seconds between each pseudo cron + //if you want more frequent cron updates it's better to rely on "true cron" and to turn off pseudo cron + $interval = 1800; //1800 = 30 minutes + if (($this->CI->config->item('last_access') - $this->CI->config->item('last_fetch')) > $interval) { + $this->fetch_items(); + } + } + } + + function extend($method = 'pre_db', $feed_domain = NULL, $item = NULL, $simplepie_object = NULL) + { + //we can extend what sweetcron does at various points in the import / output process by using plugin architecture + //see system/applications/plugins for example plugins + if ($feed_domain && $item) { + $class = str_replace('.', '_', $feed_domain); + $plugin = BASEPATH.'application/plugins/'.$class.'.php'; + //support subdomain with base domain plugin if no subdomain-specific plugin exists + $domain = explode('.', $feed_domain); + if (isset($domain[2])) { + //this is a subdomain of a base domain + $is_subdomain = TRUE; + $base_class = str_replace($domain[0].'_', '', $class); + $base_plugin = BASEPATH.'application/plugins/'.$base_class.'.php'; + } else { + $is_subdomain = FALSE; + } + if (file_exists($plugin) || ($is_subdomain && file_exists($base_plugin))) { + //check if already loaded + if ($is_subdomain && file_exists($base_plugin)) { + if (!method_exists($base_class, $method)) { + include(BASEPATH.'application/plugins/'.$base_class.'.php'); + } + $plugin = new $base_class; + } else { + if (!method_exists($class, $method)) { + include(BASEPATH.'application/plugins/'.$class.'.php'); + } + $plugin = new $class; + } + return $plugin->$method($item, $simplepie_object); + } else { + return $item; + } + } + } + + function get_tags($data) + { + $tags = ''; + $other_tags = ''; + //attempt to pull from enclosures + if (isset($data['enclosures'][0]->categories[0]->term)) { + $tags = html_entity_decode($data['enclosures'][0]->categories[0]->term); + $tags = explode(' ', $tags); + } + + //attempt to pull from categories + if (isset($data['categories'][0]->term)) { + foreach ($data['categories'] as $category) { + //sometimes a tag is an ugly url that I don't think we want... + if (substr($category->term, 0, 7) != 'http://') { + $other_tags[] = html_entity_decode($category->term); + } + } + } + + $tags_count = count($tags); + $other_tags_count = count($other_tags); + + //lets go with whichever has the most... + if ($tags_count > $other_tags_count) { + $tags = $tags; + } else { + $tags = $other_tags; + } + + //clean before returning... + + return $tags; + } + + + function get_image($html) { + //kudos to: + //http://zytzagoo.net/blog/2008/01/23/extracting-images-from-html-using-regular-expressions/ + if (stripos($html, 'CI->uri->segment(2) == strtolower($page_name)) { + return true; + } + } + + function integrity_check() + { + if (!$this->CI->db->table_exists('feeds') || !$this->CI->db->table_exists('items') || !$this->CI->db->table_exists('options') || !$this->CI->db->table_exists('tags') || !$this->CI->db->table_exists('tag_relationships') || !$this->CI->db->table_exists('users')) { + if (file_exists(BASEPATH.'../.htaccess')) { + die('Whoo Hoo! Almost there - now just run the install script.'); + } else { + die('Looks like you are missing an .htaccess file...
    For instructions on creating one, please see the installation documentation'); + } + } + } + + function install_check() + { + if ($this->CI->db->table_exists('feeds') || $this->CI->db->table_exists('items') || $this->CI->db->table_exists('options') || $this->CI->db->table_exists('tags') || $this->CI->db->table_exists('tag_relationships') || $this->CI->db->table_exists('users')) { + die('Sweetcron is already (or partially) installed. If you wish to reinstall, please clear your database first.'); + } + } + + function compatibility_check() + { + //checks php version + if (version_compare(PHP_VERSION, '5.0.0', '<')) { + die('Sorry, Sweetcron is for PHP5 and above. Your version of PHP is lower than that. Time to upgrade?'); + } + if (function_exists('apache_get_modules')) { + $modules = apache_get_modules(); + if (!in_array("mod_rewrite", $modules)) { + die('Sorry, it looks like your server does not have mod_rewrite installed. Please contact your webhost to get it enabled.'); + } + } + } + + function do_search() + { + if ($this->CI->input->post('query')) { + //strip out stuff and send to page + $query = urlencode($this->CI->input->post('query')); + header('Location: '.$this->CI->config->item('base_url').'items/search/'.$query); + } else { + show_error('You must type some keywords to search'); + } + } + + function get_single_item_page($item_id = NULL) + { + if ($item_id) { + //remove query string (some 3rd party commenting services refer back after commenting) + $item_id = explode('?', $item_id); + $item_id = $item_id[0]; + $data->item = $this->CI->item_model->get_public_item_by_id($item_id); + $data->page_name = $data->item->get_title(); + $data->popular_tags = $this->CI->tag_model->get_all_tags('count', 50); + $data->all_tags = $this->CI->tag_model->get_all_tags('count'); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/single', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } + } + + function query_items($type = 'site', $query = NULL, $offset = 0, $limit = 10) + { + return $this->get_items_page($type, NULL, TRUE, $query, NULL, TRUE, $offset, $limit); + } + + function get_items_page($type = 'index', $current_page_num = 1, $public = FALSE, $query = NULL, $rss_filter = NULL, $query_items = NULL, $offset = NULL, $limit = NULL) + { + + //return raw items for query_items() + if ($query_items) { + if ($type == 'site') { + return $this->CI->item_model->get_items_by_feed_domain($offset, $limit, $query, $public); + } elseif ($type == 'tag') { + return $this->CI->item_model->get_items_by_tag($offset, $limit, $query, $public); + } elseif ($type == 'search') { + return $this->CI->item_model->get_items_by_search($offset, $limit, $query, $public); + } + exit(); + } + + $data->blog_posts = $this->CI->item_model->get_items_by_feed_domain(0, 10, 'sweetcron', $public); + $data->active_feeds = $this->CI->feed_model->get_active_feeds(TRUE); + $data->popular_tags = $this->CI->tag_model->get_all_tags('count', 50); + $data->all_tags = $this->CI->tag_model->get_all_tags('count'); + $data->page_type = $type; + + if ($type == 'rss_feed') { + if (!$rss_filter) { + $data->page_name = ''; + $data->items = $this->CI->item_model->get_all_items(0, 20, $public); + } elseif ($rss_filter == 'tag') { + $data->page_name = '- tagged with '.$query; + $data->items = $this->CI->item_model->get_items_by_tag(0, 20, $query, $public); + } elseif ($rss_filter == 'search') { + $data->page_name = '- search for '.$query; + $data->items = $this->CI->item_model->get_items_by_search(0, 20, $query, $public); + } elseif ($rss_filter == 'site') { + $data->page_name = '- imported from '.$query; + $data->items = $this->CI->item_model->get_items_by_feed_domain(0, 20, $query, $public); + } + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/rss_feed', $data); + } elseif ($type == 'static_page') { + + $page = $this->CI->uri->segment(2); + $data->page_name = ucwords($page); + if (file_exists(BASEPATH.'application/views/themes/'.$this->CI->config->item('theme').'/'.$page.'.php')) { + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/'.$page, $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } else { + show_404(); + } + } else { + + $this->CI->page->SetItemsPerPage($this->CI->config->item('per_page')); + $this->CI->page->SetQueryStringVar('page'); + $this->CI->page->SetLinksFormat('‹',' ','›'); + $this->CI->page->SetLinksToDisplay(10); + $this->CI->page->SetCurrentPage($current_page_num); + + if ($public) { + $admin = ''; + } else { + $admin = 'admin/'; + } + + //conditionals depending on page type + if ($type == 'index') { + $data->page_name = 'Home'; + $this->CI->page->SetItemCount($this->CI->item_model->count_all_items($public)); + if ($public) { + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin); + } else { + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/'); + } + $data->items = $this->CI->item_model->get_all_items($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $public); + } elseif ($type == 'search') { + $data->page_name = 'Items Search'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_search($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/search/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_search($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } elseif ($type == 'tag') { + $data->page_name = 'Items Tag'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_tag($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/tag/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_tag($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } elseif ($type == 'site') { + $data->page_name = 'Items Site'; + $this->CI->page->SetItemCount($this->CI->item_model->count_items_by_feed_domain($query, $public)); + $this->CI->page->SetLinksHref($this->CI->config->item('base_url').$admin.'items/site/'.$query.'/'); + $data->items = $this->CI->item_model->get_items_by_feed_domain($this->CI->page->GetOffset(), $this->CI->page->GetSqlLimit(), $query, $public); + } + + $data->page_query = $query; + + if ($query && $type == 'search') { + $data->query = $query; + } + + if ($query && $type == 'tag') { + $data->tag = urldecode($query); + } + + if ($query && $type == 'site') { + $data->site = $query; + } + + //load view + if ($public) { + $data->pages = $this->CI->page->GetPageLinks(); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_header', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/items', $data); + $this->CI->load->view('themes/'.$this->CI->config->item('theme').'/_footer', $data); + } else { + $data->pages = $this->CI->page->GetPageLinks(); + $this->CI->load->view('admin/_header', $data); + $this->CI->load->view('admin/items', $data); + $this->CI->load->view('admin/_footer'); + } + + } + } + +} +?> \ No newline at end of file diff --git a/system/application/libraries/sweetcron_item.php b/system/application/libraries/sweetcron_item.php new file mode 100644 index 0000000..729030a --- /dev/null +++ b/system/application/libraries/sweetcron_item.php @@ -0,0 +1,246 @@ +feed_id; + } + + function get_feed_title() + { + return $this->feed_title; + } + + function get_feed_icon() + { + return $this->feed_icon; + } + + function get_feed_url() + { + return $this->feed_url; + } + + function get_feed_data() + { + return $this->feed_data; + } + + function get_feed_status() + { + return $this->feed_status; + } + + function get_feed_domain() + { + return $this->feed_domain; + } + + function get_feed_class() + { + return $this->feed_class; + } + + //return item components + + function get_id() + { + return $this->ID; + } + + function get_date() + { + return $this->item_date; + } + + function get_nice_date() + { + return $this->nice_date; + } + + function get_human_date() + { + return $this->human_date; + } + + function get_content() + { + return $this->item_content; + } + + function get_title() + { + return $this->item_title; + } + + function get_permalink() + { + return $this->item_permalink; + } + + function get_original_permalink() + { + return $this->item_original_permalink; + } + + function get_status() + { + return $this->item_status; + } + + function get_name() + { + return $this->item_name; + } + + function get_parent() + { + return $this->item_parent; + } + + function get_data() + { + return $this->item_data; + } + + //"has" conditionals for item data + function has_content() + { + if (isset($this->item_content) && $this->item_content != '') { + return true; + } + } + + function has_permalink() + { + if (isset($this->item_permalink)) { + return true; + } + } + + function has_original_permalink() + { + if (isset($this->item_original_permalink)) { + return true; + } + } + + function has_video() + { + if (isset($this->item_data['video'])) { + return true; + } + } + + function has_audio() + { + if (isset($this->item_data['audio'])) { + return true; + } + } + + function has_image() + { + if (isset($this->item_data['image']) && !empty($this->item_data['image'])) { + return true; + } + } + + function has_tags() + { + if (isset($this->item_tags[0])) { + return true; + } + } + + function has_tag($query = NULL) + { + $query = strtolower($query); + if (isset($this->item_tags[0])) { + foreach ($this->item_tags as $tag) { + if ($tag->slug == $query) { + return true; + } + } + } + } + + function has_data($key = NULL) + { + if (isset($this->item_data[$key])) { + return true; + } + } + + //get item data + function get_video() + { + if ($this->has_video()) { + return $this->item_data['video']; + } + } + + function get_audio() + { + if ($this->has_audio()) { + return $this->item_data['audio']; + } + } + + function get_image() + { + if ($this->has_image()) { + return $this->item_data['image']; + } + } + + function get_tags() + { + if ($this->has_tags()) { + return $this->item_tags; + } else { + return array(); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/models/.svn/all-wcprops b/system/application/models/.svn/all-wcprops new file mode 100644 index 0000000..d7859ca --- /dev/null +++ b/system/application/models/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/124/trunk/system/application/models +END +tag_model.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/124/trunk/system/application/models/tag_model.php +END +item_model.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/124/trunk/system/application/models/item_model.php +END +feed_model.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/124/trunk/system/application/models/feed_model.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/application/models/index.html +END +option_model.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/124/trunk/system/application/models/option_model.php +END diff --git a/system/application/models/.svn/entries b/system/application/models/.svn/entries new file mode 100644 index 0000000..688d85f --- /dev/null +++ b/system/application/models/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/models +http://sweetcron.googlecode.com/svn + + + +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +tag_model.php +file + + + + +2009-09-15T00:17:47.000000Z +8f50323ba5ea05f36327000efdfe6d87 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2113 + +item_model.php +file + + + + +2009-09-15T00:17:47.000000Z +d45b0fc6d891f1ff6eedcd69961b2dcf +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +12900 + +feed_model.php +file + + + + +2009-09-15T00:17:47.000000Z +045bed0b4666822aae19f987335ee312 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2905 + +index.html +file + + + + +2009-09-15T00:17:47.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +option_model.php +file + + + + +2009-09-15T00:17:47.000000Z +26d7fcd0d2cd64a43e3f26430eb10866 +2008-12-22T02:10:08.113778Z +124 +yongfook + + + + + + + + + + + + + + + + + + + + + +2570 + diff --git a/system/application/models/.svn/prop-base/index.html.svn-base b/system/application/models/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/models/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/models/.svn/text-base/feed_model.php.svn-base b/system/application/models/.svn/text-base/feed_model.php.svn-base new file mode 100644 index 0000000..d1e12bf --- /dev/null +++ b/system/application/models/.svn/text-base/feed_model.php.svn-base @@ -0,0 +1,90 @@ + $value) { + $feeds[$key]->item_count = $this->db->select('ID')->get_where('items', array('item_status !=' => 'deleted', 'item_feed_id' => $feeds[$key]->feed_id))->num_rows(); + } + + return $feeds; + + } else { + return array(); + } + } + + function get_feeds() + { + return $this->_process($this->db->get('feeds')->result()); + } + + function count_active_feeds() + { + return $this->db->get_where('feeds', array('feed_status' => 'active'))->num_rows(); + } + + function get_active_feeds($group = FALSE) + { + if ($group) { + return $this->_process($this->db->group_by('feed_domain')->get_where('feeds', array('feed_status' => 'active'))->result()); + } else { + return $this->_process($this->db->get_where('feeds', array('feed_status' => 'active'))->result()); + } + } + + function add_feed($feed) + { + $this->db->insert('feeds', $feed); + //om nom nom + } + + function delete_feed($feed_id) + { + $this->db->update('feeds', array('feed_status' => 'deleted'), array('feed_id' => $feed_id)); + } + +} +?> \ No newline at end of file diff --git a/system/application/models/.svn/text-base/index.html.svn-base b/system/application/models/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/models/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/models/.svn/text-base/item_model.php.svn-base b/system/application/models/.svn/text-base/item_model.php.svn-base new file mode 100644 index 0000000..eac7d0e --- /dev/null +++ b/system/application/models/.svn/text-base/item_model.php.svn-base @@ -0,0 +1,340 @@ +load->helper('url'); + if ($items) { + foreach ($items as $key => $value) { + $new_item = new Sweetcron_item; + + //item feed components + $new_item->feed_id = $items[$key]->feed_id; + $new_item->feed_title = $items[$key]->feed_title; + $new_item->feed_icon = $items[$key]->feed_icon; + $new_item->feed_url = $items[$key]->feed_url; + $new_item->feed_data = $items[$key]->feed_data; + $new_item->feed_status = $items[$key]->feed_status; + $new_item->feed_domain = $items[$key]->feed_domain; + + //standard item components + $new_item->ID = $items[$key]->ID; + $new_item->item_date = $items[$key]->item_date; + //autolinks + $new_item->item_content = auto_link($items[$key]->item_content); + + $new_item->item_content = markdown($new_item->item_content); + $new_item->item_title = auto_link($items[$key]->item_title); + $new_item->item_original_permalink = $items[$key]->item_permalink; + $new_item->item_permalink = $this->config->item('base_url').'items/view/'.$new_item->ID; + $new_item->item_status = $items[$key]->item_status; + $new_item->item_name = $items[$key]->item_name; + $new_item->item_data = unserialize($items[$key]->item_data); + $new_item->item_tags = $this->get_tags($items[$key]->ID); + + //make adjustments if blog post + if (!$items[$key]->feed_id) { + $new_item->feed_icon = '/favicon.ico'; + $url = parse_url($this->config->item('base_url')); + if (substr($url['host'], 0, 4) == 'www.') { + $new_item->feed_domain = substr($url['host'], 4); + } else { + $new_item->feed_domain = $url['host']; + } + } + + $new_item->feed_class = str_replace('.','_',$new_item->feed_domain); + + //extended item components + if ($new_item->feed_id) { + $new_item = $this->sweetcron->extend('pre_display', $new_item->feed_domain, $new_item); + } + + //custom item components + $new_item->nice_date = timespan($items[$key]->item_date); + if ($new_item->item_date < strtotime('1 day ago')) { + $new_item->human_date = date('F j Y, g:ia', $items[$key]->item_date); + } else { + $new_item->human_date = $new_item->nice_date.' ago'; + } + + $items[$key] = $new_item; + + } + if ($return_single) { + return $items[0]; + } else { + return $items; + } + } else { + return false; + } + } + + function get_public_item_by_id($item_id) + { + $item = $this->db->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', array('ID' => $item_id, 'item_status' => 'publish'))->result(); + if ($item) { + return $this->_process($item, TRUE); + } else { + show_404(); + } + } + + function count_all_items($public = FALSE) + { + if ($public) { + $where = array('item_status' => 'publish'); + } else { + $where = array('item_status !=' => 'deleted'); + } + return $this->db->select('ID')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', $where)->num_rows(); + } + + function get_all_items($offset = 0, $limit = 10, $public = FALSE) + { + if ($public) { + $where = array('item_status' => 'publish'); + } else { + $where = array('item_status !=' => 'deleted'); + } + $items = $this->db->limit($limit)->offset($offset)->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->order_by('item_date', 'DESC')->get_where('items', $where)->result(); + return $this->_process($items); + } + + function count_items_by_search($query, $public = FALSE) + { + if ($public) { + $where = 'item_status = "publish"'; + } else { + $where = 'item_status != "deleted"'; + } + return $this->db->select('*, MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).') AS score')->where($where.' AND MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).')')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->orderby('score', 'desc')->limit($limit)->offset($offset)->get('items')->num_rows(); + } + + function get_items_by_search($offset = 0, $limit = 10, $query, $public = FALSE) + { + if ($public) { + $where = 'item_status = "publish"'; + } else { + $where = 'item_status != "deleted"'; + } + $items = $this->db->select('*, MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).') AS score')->where($where.' AND MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).')')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->orderby('score', 'desc')->limit($limit)->offset($offset)->get('items')->result(); + return $this->_process($items); + } + + function count_items_by_tag($query, $public = FALSE) + { + if ($public) { + $where = array('tags.slug' => $query, 'item_status' => 'publish'); + } else { + $where = array('tags.slug' => $query, 'item_status !=' => 'deleted'); + } + return $this->db + ->join('tag_relationships', 'items.ID = tag_relationships.item_id') + ->join('tags', 'tags.tag_id = tag_relationships.tag_id', 'left outer') + ->getwhere('items', $where)->num_rows(); + } + + function get_items_by_tag($offset = 0, $limit = 10, $query, $public = FALSE) + { + if ($public) { + $where = array('tags.slug' => $query, 'item_status' => 'publish'); + } else { + $where = array('tags.slug' => $query, 'item_status !=' => 'deleted'); + } + $items = $this->db + ->join('tag_relationships', 'items.ID = tag_relationships.item_id') + ->join('tags', 'tags.tag_id = tag_relationships.tag_id') + ->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer') + ->order_by('item_date', 'DESC') + ->limit($limit, $offset) + ->getwhere('items', $where)->result(); + return $this->_process($items); + } + + function count_items_by_feed_domain($feed_domain, $public = FALSE) + { + if ($public) { + if ($feed_domain == 'sweetcron') { + $where = array('item_status' => 'publish', 'item_feed_id' => 0); + } else { + $where = array('item_status' => 'publish', 'feed_domain' => $feed_domain); + } + } else { + if ($feed_domain == 'sweetcron') { + $where = array('item_status !=' => 'deleted', 'item_feed_id' => 0); + } else { + $where = array('item_status !=' => 'deleted', 'feed_domain' => $feed_domain); + } + } + return $this->db->select('ID')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', $where)->num_rows(); + } + + function get_items_by_feed_domain($offset = 0, $limit = 10, $feed_domain, $public = FALSE) + { + $url = parse_url($this->config->item('base_url')); + if (substr($url['host'], 0, 4) == 'www.') { + $domain = substr($url['host'], 4); + } else { + $domain = $url['host']; + } + if ($public) { + if ($feed_domain == 'sweetcron' || $feed_domain == $domain) { + $where = array('item_status' => 'publish', 'item_feed_id' => 0); + } else { + $where = array('item_status' => 'publish', 'feed_domain' => $feed_domain); + } + } else { + if ($feed_domain == 'sweetcron' || $feed_domain == $domain) { + $where = array('item_status !=' => 'deleted', 'item_feed_id' => 0); + } else { + $where = array('item_status !=' => 'deleted', 'feed_domain' => $feed_domain); + } + } + $items = $this->db->limit($limit)->offset($offset)->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->order_by('item_date', 'DESC')->get_where('items', $where)->result(); + return $this->_process($items); + } + + function get_tags($item_id = NULL) + { + return $this->db->join('tag_relationships', 'tags.tag_id = tag_relationships.tag_id')->get_where('tags', array('item_id' => $item_id))->result(); + } + + function add_item($item = NULL) + { + + //we assume that if an item has the exact same timestamp and origin as one in the db, it's a dupe + if (!$this->db->join('feeds', 'feeds.feed_id = items.item_feed_id')->get_where('items', array('item_feed_id' => $item->item_feed_id, 'item_date' => $item->item_date))->row()) { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->insert('items', $item); + //om nom nom + $this->tag_item($tags, $this->db->insert_id()); + } + } + + function add_blog_post($item = NULL) + { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->insert('items', $item); + //om nom nom + $this->tag_item($tags, $this->db->insert_id()); + } + + function tag_item($tags = array(), $item_id = NULL) + { + //nuke all item tags from orbit. it's the only way to be sure. + $this->db->delete('tag_relationships', array('item_id' => $item_id)); + $this->clean_tags(); + if (isset($tags[0])) { + foreach ($tags as $tag) { + //too strict, wasn't letting non-latin characters through + //$tag = preg_replace('/[^a-z \d]/i', '', $tag); + + //lets just get rid of some typical meh stuff from tags + $disallow = array('(',')',',','.','*','\'','"','|'); + $tag = $this->input->xss_clean(str_replace($disallow,'',$tag)); + + $slug = url_title($tag); + + //for unicode characters the slug might be blank, so... + if ($slug == '') { + $slug = urlencode($tag); + } + + if (!$this->db->get_where('tags', array('slug' => $slug))->row()) { + $new->name = $tag; + $new->slug = $slug; + $this->db->insert('tags', $new); + } + $tag = $this->db->get_where('tags', array('slug' => $slug))->row(); + $criteria = array('tag_id' => $tag->tag_id, 'item_id' => $item_id); + if (!$this->db->get_where('tag_relationships', $criteria)->row()) { + $this->db->insert('tag_relationships', $criteria); + } + //update tag count + $count = $this->db->get_where('tag_relationships', array('tag_id' => $tag->tag_id))->num_rows(); + $this->db->update('tags', array('count' => $count), array('tag_id' => $tag->tag_id)); + } + } + } + + function clean_tags() + { + //sweeps through your tags and removes ones that + //are not associated with any posts (e.g. for when you delete tags when editing an item) + $tags = $this->db->select('*, tags.tag_id AS tag_id')->join('tag_relationships', 'tag_relationships.tag_id = tags.tag_id', 'left outer')->get('tags')->result(); + foreach ($tags as $tag) { + $count = $this->db->get_where('tag_relationships', array('tag_id' => $tag->tag_id))->num_rows(); + $this->db->update('tags', array('count' => $count), array('tag_id' => $tag->tag_id)); + if ($tag->item_id == '') { + $this->db->delete('tags', array('tag_id' => $tag->tag_id)); + } + } + } + + function delete_item($item_id) + { + $this->db->update('items', array('item_status' => 'deleted'), array('ID' => $item_id)); + } + + function get_edit_item_by_id($item_id) + { + $item = $this->db->get_where('items', array('ID' => $item_id))->row(); + $item->item_tags = $this->get_tags($item->ID); + $item->item_data = unserialize($item->item_data); + return $item; + } + + function update_item($item = NULL, $old = NULL) + { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->update('items', $item, array('ID' => $old->ID)); + $this->tag_item($tags, $old->ID); + } + +} +?> \ No newline at end of file diff --git a/system/application/models/.svn/text-base/option_model.php.svn-base b/system/application/models/.svn/text-base/option_model.php.svn-base new file mode 100644 index 0000000..e05b9bf --- /dev/null +++ b/system/application/models/.svn/text-base/option_model.php.svn-base @@ -0,0 +1,69 @@ +db->get_where('options', array('autoload' => 'yes'))->result(); + foreach ($options as $option) { + $this->config->set_item($option->option_name, $option->option_value); + } + //add theme folder + $this->config->set_item('theme_folder', $this->config->item('base_url').'system/application/views/themes/'.$this->config->item('theme').'/'); + } + + function add_option($option = NULL) + { + if (!$this->db->get_where('options', array('option_name' => $option->option_name))->row()) { + $this->db->insert('options', $option); + } else { + $this->db->update('options', $option, array('option_name' => $option->option_name)); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/models/.svn/text-base/tag_model.php.svn-base b/system/application/models/.svn/text-base/tag_model.php.svn-base new file mode 100644 index 0000000..9c84ca3 --- /dev/null +++ b/system/application/models/.svn/text-base/tag_model.php.svn-base @@ -0,0 +1,60 @@ +_process($this->db->limit($limit)->order_by($orderby, 'desc')->get('tags')->result()); + if ($tags) { + return $tags; + } else { + return array(); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/models/feed_model.php b/system/application/models/feed_model.php new file mode 100644 index 0000000..d1e12bf --- /dev/null +++ b/system/application/models/feed_model.php @@ -0,0 +1,90 @@ + $value) { + $feeds[$key]->item_count = $this->db->select('ID')->get_where('items', array('item_status !=' => 'deleted', 'item_feed_id' => $feeds[$key]->feed_id))->num_rows(); + } + + return $feeds; + + } else { + return array(); + } + } + + function get_feeds() + { + return $this->_process($this->db->get('feeds')->result()); + } + + function count_active_feeds() + { + return $this->db->get_where('feeds', array('feed_status' => 'active'))->num_rows(); + } + + function get_active_feeds($group = FALSE) + { + if ($group) { + return $this->_process($this->db->group_by('feed_domain')->get_where('feeds', array('feed_status' => 'active'))->result()); + } else { + return $this->_process($this->db->get_where('feeds', array('feed_status' => 'active'))->result()); + } + } + + function add_feed($feed) + { + $this->db->insert('feeds', $feed); + //om nom nom + } + + function delete_feed($feed_id) + { + $this->db->update('feeds', array('feed_status' => 'deleted'), array('feed_id' => $feed_id)); + } + +} +?> \ No newline at end of file diff --git a/system/application/models/index.html b/system/application/models/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/models/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/models/item_model.php b/system/application/models/item_model.php new file mode 100644 index 0000000..eac7d0e --- /dev/null +++ b/system/application/models/item_model.php @@ -0,0 +1,340 @@ +load->helper('url'); + if ($items) { + foreach ($items as $key => $value) { + $new_item = new Sweetcron_item; + + //item feed components + $new_item->feed_id = $items[$key]->feed_id; + $new_item->feed_title = $items[$key]->feed_title; + $new_item->feed_icon = $items[$key]->feed_icon; + $new_item->feed_url = $items[$key]->feed_url; + $new_item->feed_data = $items[$key]->feed_data; + $new_item->feed_status = $items[$key]->feed_status; + $new_item->feed_domain = $items[$key]->feed_domain; + + //standard item components + $new_item->ID = $items[$key]->ID; + $new_item->item_date = $items[$key]->item_date; + //autolinks + $new_item->item_content = auto_link($items[$key]->item_content); + + $new_item->item_content = markdown($new_item->item_content); + $new_item->item_title = auto_link($items[$key]->item_title); + $new_item->item_original_permalink = $items[$key]->item_permalink; + $new_item->item_permalink = $this->config->item('base_url').'items/view/'.$new_item->ID; + $new_item->item_status = $items[$key]->item_status; + $new_item->item_name = $items[$key]->item_name; + $new_item->item_data = unserialize($items[$key]->item_data); + $new_item->item_tags = $this->get_tags($items[$key]->ID); + + //make adjustments if blog post + if (!$items[$key]->feed_id) { + $new_item->feed_icon = '/favicon.ico'; + $url = parse_url($this->config->item('base_url')); + if (substr($url['host'], 0, 4) == 'www.') { + $new_item->feed_domain = substr($url['host'], 4); + } else { + $new_item->feed_domain = $url['host']; + } + } + + $new_item->feed_class = str_replace('.','_',$new_item->feed_domain); + + //extended item components + if ($new_item->feed_id) { + $new_item = $this->sweetcron->extend('pre_display', $new_item->feed_domain, $new_item); + } + + //custom item components + $new_item->nice_date = timespan($items[$key]->item_date); + if ($new_item->item_date < strtotime('1 day ago')) { + $new_item->human_date = date('F j Y, g:ia', $items[$key]->item_date); + } else { + $new_item->human_date = $new_item->nice_date.' ago'; + } + + $items[$key] = $new_item; + + } + if ($return_single) { + return $items[0]; + } else { + return $items; + } + } else { + return false; + } + } + + function get_public_item_by_id($item_id) + { + $item = $this->db->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', array('ID' => $item_id, 'item_status' => 'publish'))->result(); + if ($item) { + return $this->_process($item, TRUE); + } else { + show_404(); + } + } + + function count_all_items($public = FALSE) + { + if ($public) { + $where = array('item_status' => 'publish'); + } else { + $where = array('item_status !=' => 'deleted'); + } + return $this->db->select('ID')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', $where)->num_rows(); + } + + function get_all_items($offset = 0, $limit = 10, $public = FALSE) + { + if ($public) { + $where = array('item_status' => 'publish'); + } else { + $where = array('item_status !=' => 'deleted'); + } + $items = $this->db->limit($limit)->offset($offset)->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->order_by('item_date', 'DESC')->get_where('items', $where)->result(); + return $this->_process($items); + } + + function count_items_by_search($query, $public = FALSE) + { + if ($public) { + $where = 'item_status = "publish"'; + } else { + $where = 'item_status != "deleted"'; + } + return $this->db->select('*, MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).') AS score')->where($where.' AND MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).')')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->orderby('score', 'desc')->limit($limit)->offset($offset)->get('items')->num_rows(); + } + + function get_items_by_search($offset = 0, $limit = 10, $query, $public = FALSE) + { + if ($public) { + $where = 'item_status = "publish"'; + } else { + $where = 'item_status != "deleted"'; + } + $items = $this->db->select('*, MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).') AS score')->where($where.' AND MATCH(item_title, item_content) AGAINST('.$this->db->escape($query).')')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->orderby('score', 'desc')->limit($limit)->offset($offset)->get('items')->result(); + return $this->_process($items); + } + + function count_items_by_tag($query, $public = FALSE) + { + if ($public) { + $where = array('tags.slug' => $query, 'item_status' => 'publish'); + } else { + $where = array('tags.slug' => $query, 'item_status !=' => 'deleted'); + } + return $this->db + ->join('tag_relationships', 'items.ID = tag_relationships.item_id') + ->join('tags', 'tags.tag_id = tag_relationships.tag_id', 'left outer') + ->getwhere('items', $where)->num_rows(); + } + + function get_items_by_tag($offset = 0, $limit = 10, $query, $public = FALSE) + { + if ($public) { + $where = array('tags.slug' => $query, 'item_status' => 'publish'); + } else { + $where = array('tags.slug' => $query, 'item_status !=' => 'deleted'); + } + $items = $this->db + ->join('tag_relationships', 'items.ID = tag_relationships.item_id') + ->join('tags', 'tags.tag_id = tag_relationships.tag_id') + ->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer') + ->order_by('item_date', 'DESC') + ->limit($limit, $offset) + ->getwhere('items', $where)->result(); + return $this->_process($items); + } + + function count_items_by_feed_domain($feed_domain, $public = FALSE) + { + if ($public) { + if ($feed_domain == 'sweetcron') { + $where = array('item_status' => 'publish', 'item_feed_id' => 0); + } else { + $where = array('item_status' => 'publish', 'feed_domain' => $feed_domain); + } + } else { + if ($feed_domain == 'sweetcron') { + $where = array('item_status !=' => 'deleted', 'item_feed_id' => 0); + } else { + $where = array('item_status !=' => 'deleted', 'feed_domain' => $feed_domain); + } + } + return $this->db->select('ID')->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->get_where('items', $where)->num_rows(); + } + + function get_items_by_feed_domain($offset = 0, $limit = 10, $feed_domain, $public = FALSE) + { + $url = parse_url($this->config->item('base_url')); + if (substr($url['host'], 0, 4) == 'www.') { + $domain = substr($url['host'], 4); + } else { + $domain = $url['host']; + } + if ($public) { + if ($feed_domain == 'sweetcron' || $feed_domain == $domain) { + $where = array('item_status' => 'publish', 'item_feed_id' => 0); + } else { + $where = array('item_status' => 'publish', 'feed_domain' => $feed_domain); + } + } else { + if ($feed_domain == 'sweetcron' || $feed_domain == $domain) { + $where = array('item_status !=' => 'deleted', 'item_feed_id' => 0); + } else { + $where = array('item_status !=' => 'deleted', 'feed_domain' => $feed_domain); + } + } + $items = $this->db->limit($limit)->offset($offset)->join('feeds', 'feeds.feed_id = items.item_feed_id', 'left outer')->order_by('item_date', 'DESC')->get_where('items', $where)->result(); + return $this->_process($items); + } + + function get_tags($item_id = NULL) + { + return $this->db->join('tag_relationships', 'tags.tag_id = tag_relationships.tag_id')->get_where('tags', array('item_id' => $item_id))->result(); + } + + function add_item($item = NULL) + { + + //we assume that if an item has the exact same timestamp and origin as one in the db, it's a dupe + if (!$this->db->join('feeds', 'feeds.feed_id = items.item_feed_id')->get_where('items', array('item_feed_id' => $item->item_feed_id, 'item_date' => $item->item_date))->row()) { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->insert('items', $item); + //om nom nom + $this->tag_item($tags, $this->db->insert_id()); + } + } + + function add_blog_post($item = NULL) + { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->insert('items', $item); + //om nom nom + $this->tag_item($tags, $this->db->insert_id()); + } + + function tag_item($tags = array(), $item_id = NULL) + { + //nuke all item tags from orbit. it's the only way to be sure. + $this->db->delete('tag_relationships', array('item_id' => $item_id)); + $this->clean_tags(); + if (isset($tags[0])) { + foreach ($tags as $tag) { + //too strict, wasn't letting non-latin characters through + //$tag = preg_replace('/[^a-z \d]/i', '', $tag); + + //lets just get rid of some typical meh stuff from tags + $disallow = array('(',')',',','.','*','\'','"','|'); + $tag = $this->input->xss_clean(str_replace($disallow,'',$tag)); + + $slug = url_title($tag); + + //for unicode characters the slug might be blank, so... + if ($slug == '') { + $slug = urlencode($tag); + } + + if (!$this->db->get_where('tags', array('slug' => $slug))->row()) { + $new->name = $tag; + $new->slug = $slug; + $this->db->insert('tags', $new); + } + $tag = $this->db->get_where('tags', array('slug' => $slug))->row(); + $criteria = array('tag_id' => $tag->tag_id, 'item_id' => $item_id); + if (!$this->db->get_where('tag_relationships', $criteria)->row()) { + $this->db->insert('tag_relationships', $criteria); + } + //update tag count + $count = $this->db->get_where('tag_relationships', array('tag_id' => $tag->tag_id))->num_rows(); + $this->db->update('tags', array('count' => $count), array('tag_id' => $tag->tag_id)); + } + } + } + + function clean_tags() + { + //sweeps through your tags and removes ones that + //are not associated with any posts (e.g. for when you delete tags when editing an item) + $tags = $this->db->select('*, tags.tag_id AS tag_id')->join('tag_relationships', 'tag_relationships.tag_id = tags.tag_id', 'left outer')->get('tags')->result(); + foreach ($tags as $tag) { + $count = $this->db->get_where('tag_relationships', array('tag_id' => $tag->tag_id))->num_rows(); + $this->db->update('tags', array('count' => $count), array('tag_id' => $tag->tag_id)); + if ($tag->item_id == '') { + $this->db->delete('tags', array('tag_id' => $tag->tag_id)); + } + } + } + + function delete_item($item_id) + { + $this->db->update('items', array('item_status' => 'deleted'), array('ID' => $item_id)); + } + + function get_edit_item_by_id($item_id) + { + $item = $this->db->get_where('items', array('ID' => $item_id))->row(); + $item->item_tags = $this->get_tags($item->ID); + $item->item_data = unserialize($item->item_data); + return $item; + } + + function update_item($item = NULL, $old = NULL) + { + $tags = $item->item_data['tags']; + $item->item_data = serialize($item->item_data); + $this->db->update('items', $item, array('ID' => $old->ID)); + $this->tag_item($tags, $old->ID); + } + +} +?> \ No newline at end of file diff --git a/system/application/models/option_model.php b/system/application/models/option_model.php new file mode 100644 index 0000000..e05b9bf --- /dev/null +++ b/system/application/models/option_model.php @@ -0,0 +1,69 @@ +db->get_where('options', array('autoload' => 'yes'))->result(); + foreach ($options as $option) { + $this->config->set_item($option->option_name, $option->option_value); + } + //add theme folder + $this->config->set_item('theme_folder', $this->config->item('base_url').'system/application/views/themes/'.$this->config->item('theme').'/'); + } + + function add_option($option = NULL) + { + if (!$this->db->get_where('options', array('option_name' => $option->option_name))->row()) { + $this->db->insert('options', $option); + } else { + $this->db->update('options', $option, array('option_name' => $option->option_name)); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/models/tag_model.php b/system/application/models/tag_model.php new file mode 100644 index 0000000..9c84ca3 --- /dev/null +++ b/system/application/models/tag_model.php @@ -0,0 +1,60 @@ +_process($this->db->limit($limit)->order_by($orderby, 'desc')->get('tags')->result()); + if ($tags) { + return $tags; + } else { + return array(); + } + } + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/all-wcprops b/system/application/plugins/.svn/all-wcprops new file mode 100644 index 0000000..fc1cc5f --- /dev/null +++ b/system/application/plugins/.svn/all-wcprops @@ -0,0 +1,71 @@ +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/123/trunk/system/application/plugins +END +friendfeed_com.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/79/trunk/system/application/plugins/friendfeed_com.php +END +slideshare_net.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/96/trunk/system/application/plugins/slideshare_net.php +END +youtube_com.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/123/trunk/system/application/plugins/youtube_com.php +END +vimeo_com.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/79/trunk/system/application/plugins/vimeo_com.php +END +twitter_com.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/81/trunk/system/application/plugins/twitter_com.php +END +qik_com.php +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/!svn/ver/80/trunk/system/application/plugins/qik_com.php +END +blogsearch_google_com.php +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/!svn/ver/79/trunk/system/application/plugins/blogsearch_google_com.php +END +tumblr_com.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/115/trunk/system/application/plugins/tumblr_com.php +END +search_twitter_com.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/81/trunk/system/application/plugins/search_twitter_com.php +END +seesmic_com.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/115/trunk/system/application/plugins/seesmic_com.php +END +flickr_com.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/117/trunk/system/application/plugins/flickr_com.php +END diff --git a/system/application/plugins/.svn/entries b/system/application/plugins/.svn/entries new file mode 100644 index 0000000..bdd7e8f --- /dev/null +++ b/system/application/plugins/.svn/entries @@ -0,0 +1,402 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/plugins +http://sweetcron.googlecode.com/svn + + + +2008-12-04T09:43:27.013015Z +123 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +friendfeed_com.php +file + + + + +2009-09-15T00:17:46.000000Z +b5190dfa1e34267ea6f4770b59205024 +2008-09-05T05:44:48.712049Z +79 +yongfook + + + + + + + + + + + + + + + + + + + + + +677 + +slideshare_net.php +file + + + + +2009-09-15T00:17:46.000000Z +776a76c94b963d65072298cbe9c2a16e +2008-09-09T06:36:43.925152Z +96 +yongfook + + + + + + + + + + + + + + + + + + + + + +1178 + +youtube_com.php +file + + + + +2009-09-15T00:17:46.000000Z +ff8ae87c070aee028541f06381a87d11 +2008-12-04T09:43:27.013015Z +123 +yongfook + + + + + + + + + + + + + + + + + + + + + +977 + +vimeo_com.php +file + + + + +2009-09-15T00:17:46.000000Z +d026fa3c08bd298a998b824ded2657af +2008-09-05T05:44:48.712049Z +79 +yongfook + + + + + + + + + + + + + + + + + + + + + +998 + +twitter_com.php +file + + + + +2009-09-15T00:17:46.000000Z +3097f7cf658ea54305aa72a0fcba2a2b +2008-09-05T06:55:46.419814Z +81 +yongfook + + + + + + + + + + + + + + + + + + + + + +758 + +qik_com.php +file + + + + +2009-09-15T00:17:46.000000Z +9db5f922d03a6242a4a11d8190534268 +2008-09-05T06:28:33.235345Z +80 +yongfook + + + + + + + + + + + + + + + + + + + + + +1414 + +blogsearch_google_com.php +file + + + + +2009-09-15T00:17:46.000000Z +111d2712b9eb560c07dffe87c41b634a +2008-09-05T05:44:48.712049Z +79 +yongfook + + + + + + + + + + + + + + + + + + + + + +538 + +tumblr_com.php +file + + + + +2009-09-15T00:17:46.000000Z +c6e441825a3867a076cb0ccf18748d14 +2008-09-29T16:59:04.143119Z +115 +yongfook + + + + + + + + + + + + + + + + + + + + + +1300 + +search_twitter_com.php +file + + + + +2009-09-15T00:17:46.000000Z +df15d2d403134310b6765be8a9583765 +2008-09-05T06:55:46.419814Z +81 +yongfook + + + + + + + + + + + + + + + + + + + + + +449 + +seesmic_com.php +file + + + + +2009-09-15T00:17:46.000000Z +53f7ec2aa04898f33e5aefda8342620a +2008-09-29T16:59:04.143119Z +115 +yongfook + + + + + + + + + + + + + + + + + + + + + +1099 + +flickr_com.php +file + + + + +2009-09-15T00:17:46.000000Z +b8d600d7e48228c9060737f90b52f905 +2008-10-05T07:25:02.976982Z +117 +yongfook + + + + + + + + + + + + + + + + + + + + + +1881 + diff --git a/system/application/plugins/.svn/text-base/blogsearch_google_com.php.svn-base b/system/application/plugins/.svn/text-base/blogsearch_google_com.php.svn-base new file mode 100644 index 0000000..2fbe5d7 --- /dev/null +++ b/system/application/plugins/.svn/text-base/blogsearch_google_com.php.svn-base @@ -0,0 +1,24 @@ +get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'publisher'); + if (isset($original_publisher[0]['data'])) { + $item->item_data['publisher'] = $original_publisher[0]['data']; + } + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/flickr_com.php.svn-base b/system/application/plugins/.svn/text-base/flickr_com.php.svn-base new file mode 100644 index 0000000..5c5d0a5 --- /dev/null +++ b/system/application/plugins/.svn/text-base/flickr_com.php.svn-base @@ -0,0 +1,51 @@ +get_item_tags('http://purl.org/dc/elements/1.1/', 'date.Taken'); + $item->item_date = strtotime(str_replace('T', ' ', substr($date[0]['data'], 0, -6))); + } + + //remove username etc + $flickr_username = $original->get_item_tags('', 'author'); + $flickr_username = $flickr_username[0]['data']; + preg_match('/.*\((.*)\).*/', $flickr_username, $matches); + $flickr_username = $matches[1]; + if (!$flickr_username) { + //flickr stores usernames in various places it seems... + $flickr_username = $original->get_item_tags('http://www.w3.org/2005/Atom', 'author'); + $flickr_username = $flickr_username[0]['child']['http://www.w3.org/2005/Atom']['name'][0]['data']; + } + $remove_this = $flickr_username.' posted a photo:'; + $item->item_content = trim(str_replace($remove_this, '', $item->item_content)); + + //some flickr feeds have different tag formatting OMGWTF + if (isset($item->item_data['categories'])) { + foreach ($item->item_data['categories'] as $key => $value) { + $item->item_data['tags'][$key] = $value->term; + } + } + return $item; + } + + function pre_display($item) + { + $item->item_data['flickr_com']['image']['m'] = substr($item->item_data['image'], 0, -6).'.jpg'; + $item->item_data['flickr_com']['image']['l'] = substr($item->item_data['image'], 0, -5).'b.jpg'; + $item->item_data['flickr_com']['image']['o'] = substr($item->item_data['image'], 0, -5).'o.jpg'; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/friendfeed_com.php.svn-base b/system/application/plugins/.svn/text-base/friendfeed_com.php.svn-base new file mode 100644 index 0000000..8193df7 --- /dev/null +++ b/system/application/plugins/.svn/text-base/friendfeed_com.php.svn-base @@ -0,0 +1,30 @@ +item_data['enclosures'][0]->link; + //check if is image + $format = substr($big_pic, -4); + if ($format == '.jpg' || $format == '.gif' || $format == '.png') { + $item->item_data['image'] = $big_pic; + } + + //remove small icons as image + if (substr($item->item_data['image'], 0, 42) == 'http://friendfeed.com/static/images/icons/') { + $item->item_data['image'] = ''; + } + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/qik_com.php.svn-base b/system/application/plugins/.svn/text-base/qik_com.php.svn-base new file mode 100644 index 0000000..24697d1 --- /dev/null +++ b/system/application/plugins/.svn/text-base/qik_com.php.svn-base @@ -0,0 +1,32 @@ +item_data['enclosures'][0]->link); + $streamname = str_replace('.flv','',$streamname[4]); + + //get video id + $videoid = explode('/', $item->item_data['permalink']); + $videoid = $videoid[4]; + + //get username + $username = explode('/', $item->feed_url); + $username = $username[3]; + + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/search_twitter_com.php.svn-base b/system/application/plugins/.svn/text-base/search_twitter_com.php.svn-base new file mode 100644 index 0000000..497120c --- /dev/null +++ b/system/application/plugins/.svn/text-base/search_twitter_com.php.svn-base @@ -0,0 +1,22 @@ +get_author(); + $item->item_data['publisher'] = $original_publisher->name; + $item->item_data['publisher_link'] = $original_publisher->link; + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/seesmic_com.php.svn-base b/system/application/plugins/.svn/text-base/seesmic_com.php.svn-base new file mode 100644 index 0000000..fca12ba --- /dev/null +++ b/system/application/plugins/.svn/text-base/seesmic_com.php.svn-base @@ -0,0 +1,28 @@ +item_data['image'] = $item->item_data['enclosures'][0]->thumbnails[0]; + + //get video id + $videoid = explode('/', $item->item_data['permalink']); + $videoid = $videoid[4]; + + //create teh video + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/slideshare_net.php.svn-base b/system/application/plugins/.svn/text-base/slideshare_net.php.svn-base new file mode 100644 index 0000000..03779f3 --- /dev/null +++ b/system/application/plugins/.svn/text-base/slideshare_net.php.svn-base @@ -0,0 +1,37 @@ +get_item_tags('http://search.yahoo.com/mrss/', 'content'); + $item->item_content = $nice_content[0]['child']['http://search.yahoo.com/mrss/']['description'][0]['data']; + $embed = $original->get_item_tags('http://slideshare.net/api/1', 'embed'); + $embed = $embed[0]['data']; + + //strip out just the movie bit + $embed = strip_tags($embed, ''); + $embed = str_replace(' style="margin:0px" width="425" height="355"', '', $embed); + $embed = explode('object', $embed); + $embed = ''; + $item->item_data['video'] = $embed; + return $item; + } + + function pre_display($item) + { + $height = '355'; + $width = '425'; + $video = $item->get_video(); + $video = str_replace('355', $height, $video); + $video = str_replace('425', $width, $video); + $item->item_data['video'] = $video; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/tumblr_com.php.svn-base b/system/application/plugins/.svn/text-base/tumblr_com.php.svn-base new file mode 100644 index 0000000..987e1f8 --- /dev/null +++ b/system/application/plugins/.svn/text-base/tumblr_com.php.svn-base @@ -0,0 +1,43 @@ +get_feed(); + $feed = parse_url($feed->get_link()); + $username = explode('.', $feed['host']); + + $tumblr_username = $username[0]; + + $item_permalink = $item->item_permalink; // Gets the permalink from $item + $item_permalink_array = explode("/", $item_permalink); // Boom! + $tumblr_id = end($item_permalink_array); // uses explode() and the last element in the array to find the Post ID + + $URL = ( "http://$tumblr_username.tumblr.com/api/read/?id=$tumblr_id" ); // Uses the Tumblr API to get teh XML for the post + $c = curl_init(); + curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($c, CURLOPT_URL, $URL); + $tumblr_xml = curl_exec($c); + curl_close($c); + + $xml = new SimpleXMLElement($tumblr_xml); + $tumblr_post = $xml->posts[0]->post->attributes(); // Creates an array of attributes of the post + $type = $tumblr_post['type']; // Finally, gets the type! + + + //Put the type into the item object + $item->item_data['type'] = (string)($type); // Cast it to a String to avoid unserialize errors + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/twitter_com.php.svn-base b/system/application/plugins/.svn/text-base/twitter_com.php.svn-base new file mode 100644 index 0000000..909263b --- /dev/null +++ b/system/application/plugins/.svn/text-base/twitter_com.php.svn-base @@ -0,0 +1,33 @@ +get_permalink(); + $twitter_username = explode('/', $original_publisher); + $twitter_username = $twitter_username[3]; + + //remove username from front of posts + $item->item_title = trim(str_replace($twitter_username.':', '', $item->item_title)); + + //filter out @replies (set as unpublished) + if (substr($item->item_title, 0, 1) == '@') { + $item->item_status = 'draft'; + } + + //remove item_content as it's just the same as the title anyway + $item->item_content = ''; + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/vimeo_com.php.svn-base b/system/application/plugins/.svn/text-base/vimeo_com.php.svn-base new file mode 100644 index 0000000..baa71b5 --- /dev/null +++ b/system/application/plugins/.svn/text-base/vimeo_com.php.svn-base @@ -0,0 +1,23 @@ +item_data['permalink']; + $link = parse_url($link); + $link = substr($link['path'], 1); + $item->item_data['video'] = ' '; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/.svn/text-base/youtube_com.php.svn-base b/system/application/plugins/.svn/text-base/youtube_com.php.svn-base new file mode 100644 index 0000000..14e4450 --- /dev/null +++ b/system/application/plugins/.svn/text-base/youtube_com.php.svn-base @@ -0,0 +1,31 @@ +item_content); + $item->item_content = $content[0]; + + //looky, youtube has an image too + $item->item_data['image'] = $item->item_data['enclosures'][0]->thumbnails[0]; + return $item; + } + + function pre_display($item) + { + $link = $item->item_data['permalink']; + $link = str_replace('?v=', '/v/', $link); + + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/blogsearch_google_com.php b/system/application/plugins/blogsearch_google_com.php new file mode 100644 index 0000000..2fbe5d7 --- /dev/null +++ b/system/application/plugins/blogsearch_google_com.php @@ -0,0 +1,24 @@ +get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'publisher'); + if (isset($original_publisher[0]['data'])) { + $item->item_data['publisher'] = $original_publisher[0]['data']; + } + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/flickr_com.php b/system/application/plugins/flickr_com.php new file mode 100644 index 0000000..5c5d0a5 --- /dev/null +++ b/system/application/plugins/flickr_com.php @@ -0,0 +1,51 @@ +get_item_tags('http://purl.org/dc/elements/1.1/', 'date.Taken'); + $item->item_date = strtotime(str_replace('T', ' ', substr($date[0]['data'], 0, -6))); + } + + //remove username etc + $flickr_username = $original->get_item_tags('', 'author'); + $flickr_username = $flickr_username[0]['data']; + preg_match('/.*\((.*)\).*/', $flickr_username, $matches); + $flickr_username = $matches[1]; + if (!$flickr_username) { + //flickr stores usernames in various places it seems... + $flickr_username = $original->get_item_tags('http://www.w3.org/2005/Atom', 'author'); + $flickr_username = $flickr_username[0]['child']['http://www.w3.org/2005/Atom']['name'][0]['data']; + } + $remove_this = $flickr_username.' posted a photo:'; + $item->item_content = trim(str_replace($remove_this, '', $item->item_content)); + + //some flickr feeds have different tag formatting OMGWTF + if (isset($item->item_data['categories'])) { + foreach ($item->item_data['categories'] as $key => $value) { + $item->item_data['tags'][$key] = $value->term; + } + } + return $item; + } + + function pre_display($item) + { + $item->item_data['flickr_com']['image']['m'] = substr($item->item_data['image'], 0, -6).'.jpg'; + $item->item_data['flickr_com']['image']['l'] = substr($item->item_data['image'], 0, -5).'b.jpg'; + $item->item_data['flickr_com']['image']['o'] = substr($item->item_data['image'], 0, -5).'o.jpg'; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/friendfeed_com.php b/system/application/plugins/friendfeed_com.php new file mode 100644 index 0000000..8193df7 --- /dev/null +++ b/system/application/plugins/friendfeed_com.php @@ -0,0 +1,30 @@ +item_data['enclosures'][0]->link; + //check if is image + $format = substr($big_pic, -4); + if ($format == '.jpg' || $format == '.gif' || $format == '.png') { + $item->item_data['image'] = $big_pic; + } + + //remove small icons as image + if (substr($item->item_data['image'], 0, 42) == 'http://friendfeed.com/static/images/icons/') { + $item->item_data['image'] = ''; + } + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/qik_com.php b/system/application/plugins/qik_com.php new file mode 100644 index 0000000..24697d1 --- /dev/null +++ b/system/application/plugins/qik_com.php @@ -0,0 +1,32 @@ +item_data['enclosures'][0]->link); + $streamname = str_replace('.flv','',$streamname[4]); + + //get video id + $videoid = explode('/', $item->item_data['permalink']); + $videoid = $videoid[4]; + + //get username + $username = explode('/', $item->feed_url); + $username = $username[3]; + + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/search_twitter_com.php b/system/application/plugins/search_twitter_com.php new file mode 100644 index 0000000..497120c --- /dev/null +++ b/system/application/plugins/search_twitter_com.php @@ -0,0 +1,22 @@ +get_author(); + $item->item_data['publisher'] = $original_publisher->name; + $item->item_data['publisher_link'] = $original_publisher->link; + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/seesmic_com.php b/system/application/plugins/seesmic_com.php new file mode 100644 index 0000000..fca12ba --- /dev/null +++ b/system/application/plugins/seesmic_com.php @@ -0,0 +1,28 @@ +item_data['image'] = $item->item_data['enclosures'][0]->thumbnails[0]; + + //get video id + $videoid = explode('/', $item->item_data['permalink']); + $videoid = $videoid[4]; + + //create teh video + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/slideshare_net.php b/system/application/plugins/slideshare_net.php new file mode 100644 index 0000000..03779f3 --- /dev/null +++ b/system/application/plugins/slideshare_net.php @@ -0,0 +1,37 @@ +get_item_tags('http://search.yahoo.com/mrss/', 'content'); + $item->item_content = $nice_content[0]['child']['http://search.yahoo.com/mrss/']['description'][0]['data']; + $embed = $original->get_item_tags('http://slideshare.net/api/1', 'embed'); + $embed = $embed[0]['data']; + + //strip out just the movie bit + $embed = strip_tags($embed, ''); + $embed = str_replace(' style="margin:0px" width="425" height="355"', '', $embed); + $embed = explode('object', $embed); + $embed = ''; + $item->item_data['video'] = $embed; + return $item; + } + + function pre_display($item) + { + $height = '355'; + $width = '425'; + $video = $item->get_video(); + $video = str_replace('355', $height, $video); + $video = str_replace('425', $width, $video); + $item->item_data['video'] = $video; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/tumblr_com.php b/system/application/plugins/tumblr_com.php new file mode 100644 index 0000000..987e1f8 --- /dev/null +++ b/system/application/plugins/tumblr_com.php @@ -0,0 +1,43 @@ +get_feed(); + $feed = parse_url($feed->get_link()); + $username = explode('.', $feed['host']); + + $tumblr_username = $username[0]; + + $item_permalink = $item->item_permalink; // Gets the permalink from $item + $item_permalink_array = explode("/", $item_permalink); // Boom! + $tumblr_id = end($item_permalink_array); // uses explode() and the last element in the array to find the Post ID + + $URL = ( "http://$tumblr_username.tumblr.com/api/read/?id=$tumblr_id" ); // Uses the Tumblr API to get teh XML for the post + $c = curl_init(); + curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($c, CURLOPT_URL, $URL); + $tumblr_xml = curl_exec($c); + curl_close($c); + + $xml = new SimpleXMLElement($tumblr_xml); + $tumblr_post = $xml->posts[0]->post->attributes(); // Creates an array of attributes of the post + $type = $tumblr_post['type']; // Finally, gets the type! + + + //Put the type into the item object + $item->item_data['type'] = (string)($type); // Cast it to a String to avoid unserialize errors + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/twitter_com.php b/system/application/plugins/twitter_com.php new file mode 100644 index 0000000..909263b --- /dev/null +++ b/system/application/plugins/twitter_com.php @@ -0,0 +1,33 @@ +get_permalink(); + $twitter_username = explode('/', $original_publisher); + $twitter_username = $twitter_username[3]; + + //remove username from front of posts + $item->item_title = trim(str_replace($twitter_username.':', '', $item->item_title)); + + //filter out @replies (set as unpublished) + if (substr($item->item_title, 0, 1) == '@') { + $item->item_status = 'draft'; + } + + //remove item_content as it's just the same as the title anyway + $item->item_content = ''; + return $item; + } + + function pre_display($item) + { + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/vimeo_com.php b/system/application/plugins/vimeo_com.php new file mode 100644 index 0000000..baa71b5 --- /dev/null +++ b/system/application/plugins/vimeo_com.php @@ -0,0 +1,23 @@ +item_data['permalink']; + $link = parse_url($link); + $link = substr($link['path'], 1); + $item->item_data['video'] = ' '; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/plugins/youtube_com.php b/system/application/plugins/youtube_com.php new file mode 100644 index 0000000..14e4450 --- /dev/null +++ b/system/application/plugins/youtube_com.php @@ -0,0 +1,31 @@ +item_content); + $item->item_content = $content[0]; + + //looky, youtube has an image too + $item->item_data['image'] = $item->item_data['enclosures'][0]->thumbnails[0]; + return $item; + } + + function pre_display($item) + { + $link = $item->item_data['permalink']; + $link = str_replace('?v=', '/v/', $link); + + $item->item_data['video'] = ''; + return $item; + } + + +} +?> \ No newline at end of file diff --git a/system/application/views/.svn/all-wcprops b/system/application/views/.svn/all-wcprops new file mode 100644 index 0000000..b84b959 --- /dev/null +++ b/system/application/views/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/122/trunk/system/application/views +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/application/views/index.html +END diff --git a/system/application/views/.svn/entries b/system/application/views/.svn/entries new file mode 100644 index 0000000..41c2c47 --- /dev/null +++ b/system/application/views/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views +http://sweetcron.googlecode.com/svn + + + +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +themes +dir + +admin +dir + +index.html +file + + + + +2009-09-15T00:18:04.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/application/views/.svn/prop-base/index.html.svn-base b/system/application/views/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/application/views/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/application/views/.svn/text-base/index.html.svn-base b/system/application/views/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/views/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/views/admin/.svn/all-wcprops b/system/application/views/admin/.svn/all-wcprops new file mode 100644 index 0000000..f46d600 --- /dev/null +++ b/system/application/views/admin/.svn/all-wcprops @@ -0,0 +1,77 @@ +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/95/trunk/system/application/views/admin +END +write.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/18/trunk/system/application/views/admin/write.php +END +feed_add.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/18/trunk/system/application/views/admin/feed_add.php +END +options.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/95/trunk/system/application/views/admin/options.php +END +_footer.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/35/trunk/system/application/views/admin/_footer.php +END +forgot.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/application/views/admin/forgot.php +END +items.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/56/trunk/system/application/views/admin/items.php +END +_activity_list.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/18/trunk/system/application/views/admin/_activity_list.php +END +feeds.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/77/trunk/system/application/views/admin/feeds.php +END +install.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/24/trunk/system/application/views/admin/install.php +END +dashboard.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/application/views/admin/dashboard.php +END +_header.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/24/trunk/system/application/views/admin/_header.php +END +login.php +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/24/trunk/system/application/views/admin/login.php +END diff --git a/system/application/views/admin/.svn/entries b/system/application/views/admin/.svn/entries new file mode 100644 index 0000000..3e9d5b8 --- /dev/null +++ b/system/application/views/admin/.svn/entries @@ -0,0 +1,436 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views/admin +http://sweetcron.googlecode.com/svn + + + +2008-09-08T23:42:22.477310Z +95 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +write.php +file + + + + +2009-09-15T00:18:04.000000Z +dc81161bc6388c7ad11197932bb4fe20 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +3428 + +feed_add.php +file + + + + +2009-09-15T00:18:04.000000Z +3df2edfcc4c701e62250ea421feaa663 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +907 + +options.php +file + + + + +2009-09-15T00:18:04.000000Z +5288846e5189d9d0d1a9c5ab3be67cba +2008-09-08T23:42:22.477310Z +95 +yongfook + + + + + + + + + + + + + + + + + + + + + +3628 + +_footer.php +file + + + + +2009-09-15T00:18:04.000000Z +c1cc8a90f23797a878f291f714aaa2d3 +2008-08-28T14:34:43.505984Z +35 +yongfook + + + + + + + + + + + + + + + + + + + + + +408 + +forgot.php +file + + + + +2009-09-15T00:18:04.000000Z +2712ed8254bc30a884a80cf6eb0d13d3 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +946 + +items.php +file + + + + +2009-09-15T00:18:04.000000Z +ff20f9ce497b82d4a29b79e75d02f532 +2008-08-30T02:00:46.521391Z +56 +yongfook + + + + + + + + + + + + + + + + + + + + + +3482 + +_activity_list.php +file + + + + +2009-09-15T00:18:04.000000Z +bccdb20375ae8285d8ad7608d3e9c8c7 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +1843 + +feeds.php +file + + + + +2009-09-15T00:18:04.000000Z +77a86b3fd8900ee2c4b4d7caf57449f0 +2008-09-03T14:17:36.359480Z +77 +yongfook + + + + + + + + + + + + + + + + + + + + + +1026 + +install.php +file + + + + +2009-09-15T00:18:04.000000Z +333a65638ac6fa8bb710f7f416e48929 +2008-08-28T08:47:13.192013Z +24 +yongfook + + + + + + + + + + + + + + + + + + + + + +1341 + +dashboard.php +file + + + + +2009-09-15T00:18:04.000000Z +3754eb15ee9422b2f9663b7899ef6ea9 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +1303 + +_header.php +file + + + + +2009-09-15T00:18:04.000000Z +541d339be4dd0be6f30223954576bd60 +2008-08-28T08:47:13.192013Z +24 +yongfook + + + + + + + + + + + + + + + + + + + + + +2728 + +login.php +file + + + + +2009-09-15T00:18:04.000000Z +fbb24fe5cb57a2ab5768d58c6389d1be +2008-08-28T08:47:13.192013Z +24 +yongfook + + + + + + + + + + + + + + + + + + + + + +978 + diff --git a/system/application/views/admin/.svn/text-base/_activity_list.php.svn-base b/system/application/views/admin/.svn/text-base/_activity_list.php.svn-base new file mode 100644 index 0000000..88dacfd --- /dev/null +++ b/system/application/views/admin/.svn/text-base/_activity_list.php.svn-base @@ -0,0 +1,38 @@ +

      + +
    • + +

      get_feed_domain()?> — get_human_date()?>

      +
      +

      get_title()?>

      + has_original_permalink()): ?> + + +
      get_content()?>
      + has_image()): ?> +
      + + +
      has_video()): ?> +
      get_video()?>
      +
      + + has_tags()): ?> +
        +
      • Tags:
      • + get_tags() as $tag): ?> +
      • name?>
      • + +
      + +
      +
      +
    • + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/_footer.php.svn-base b/system/application/views/admin/.svn/text-base/_footer.php.svn-base new file mode 100644 index 0000000..db80c75 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/_footer.php.svn-base @@ -0,0 +1,9 @@ + +config)):?> +

    + +
    + + + + \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/_header.php.svn-base b/system/application/views/admin/.svn/text-base/_header.php.svn-base new file mode 100644 index 0000000..5656c96 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/_header.php.svn-base @@ -0,0 +1,48 @@ + + + + + + + <?php echo $page_name?> › Sweetcron Admin Panel + + + + + + + + + + +
    + auth)): ?> +

    Welcome to Sweetcron

    +

    Installation - Step 1 of 1

    + auth->is_logged()): ?> +

    config->item('lifestream_title')?>

    +

    Logged in as data->user->user_login?> | logout?

    + +

    Welcome to Sweetcron

    +

    Please log in

    + +
    + +auth)): ?> + + + + \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/dashboard.php.svn-base b/system/application/views/admin/.svn/text-base/dashboard.php.svn-base new file mode 100644 index 0000000..d0327a7 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/dashboard.php.svn-base @@ -0,0 +1,40 @@ +
    + + + +load->view('admin/_activity_list')?> + + + +
    You have no items :/
    + + + +
    + +
    + + +

    Hello there!
    Looks like it's your first time here. Why not start by adding some feeds?

    + + + +

    Greetings!
    This page shows the last 5 public items in your lifestream.

    + +

    Your Sweetcron Stats

    +
      +
    • Public Items:
    • +
    • Feeds:
    • +
    • Last Fetch: config->item('last_fetch'))?> ago
    • +
    + +

    Useful Links

    + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/feed_add.php.svn-base b/system/application/views/admin/.svn/text-base/feed_add.php.svn-base new file mode 100644 index 0000000..5c729a9 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/feed_add.php.svn-base @@ -0,0 +1,27 @@ +
    + + + + +
    + + +
    + +

    +

    + +
    + +
    + + + +
    + +
    +

    Not sure how to find a feed?
    Try simply putting the url of a webpage in the input box
    (e.g. http://twitter.com/yongfook) — it works 90% of the time!

    +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/feeds.php.svn-base b/system/application/views/admin/.svn/text-base/feeds.php.svn-base new file mode 100644 index 0000000..e6562fd --- /dev/null +++ b/system/application/views/admin/.svn/text-base/feeds.php.svn-base @@ -0,0 +1,37 @@ +
    + + + +
      + +
    • +
        +
      • x
      • +
      +

      feed_title?>

      + + +

      item_count?> items

      + +
    • + +
    + + + +
    You have no feeds :/
    + + + +
    + + \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/forgot.php.svn-base b/system/application/views/admin/.svn/text-base/forgot.php.svn-base new file mode 100644 index 0000000..177d88e --- /dev/null +++ b/system/application/views/admin/.svn/text-base/forgot.php.svn-base @@ -0,0 +1,32 @@ +
    + + +
    + +
    + + + +
    + Instructions have been sent to your email acount. +
    + + +
    + +

    + disabled="disabled" class="text_input" type="text" name="email" value="input->post('email')?>" />

    + Input the administrator email address

    + + +
    + +
    + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/install.php.svn-base b/system/application/views/admin/.svn/text-base/install.php.svn-base new file mode 100644 index 0000000..4ad2857 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/install.php.svn-base @@ -0,0 +1,41 @@ +
    + + +
    + +
    + + + + +

    Installation Successful! Your login details are below:

    + +

    Username: validation->username?>
    + Password:

    + +

    You can now Log In »

    + + +
    + +

    +

    + +

    +

    + +

    +

    + +
    + +
    + + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/items.php.svn-base b/system/application/views/admin/.svn/text-base/items.php.svn-base new file mode 100644 index 0000000..1b7c5ea --- /dev/null +++ b/system/application/views/admin/.svn/text-base/items.php.svn-base @@ -0,0 +1,97 @@ +
    + + + + + + + + + + + + + + + +load->view('admin/_activity_list')?> + + + +
    You have no items :/
    + + +

    +
    + +
    + + + +config->item('last_fetch')): ?> +

    Last fetch config->item('last_fetch'))?> ago

    + +

    Pending first fetch...

    + + +

    Search

    + +

    + + + +

    Your Feeds

    + + +

    Tags

    + +
      + +
    • + slug): ?> + name?> + + name?> + +
    • + +
    + +
      + +
    • + slug): ?> + name?> + + name?> + +
    • + +
    +

    Show All Tags

    + +No tags + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/login.php.svn-base b/system/application/views/admin/.svn/text-base/login.php.svn-base new file mode 100644 index 0000000..296804b --- /dev/null +++ b/system/application/views/admin/.svn/text-base/login.php.svn-base @@ -0,0 +1,31 @@ +
    + + +
    + +
    + + +
    + +

    +

    + +

    +

    + +
    + +
    + + + +
    + +
    +

    Forgot Password?
    Reset my password »

    + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/options.php.svn-base b/system/application/views/admin/.svn/text-base/options.php.svn-base new file mode 100644 index 0000000..59d82f7 --- /dev/null +++ b/system/application/views/admin/.svn/text-base/options.php.svn-base @@ -0,0 +1,63 @@ +
    + + +
    + + +
    + +

    +

    + +

    +

    + +

    + + + +

    + +

    + +config->item('cron_type') == 'pseudo'): ?>checked="checked" type="radio" name="cron_type" value="pseudo" id="radio_pseudo" /> (updates every 30 mins) +config->item('cron_type') == 'true'): ?>checked="checked" type="radio" name="cron_type" value="true" id="radio_true" /> + +

    +config->item('cron_type') == 'pseudo'): ?>style="display: none" id="cron_url" class="input_explain">config->item('base_url')?>cron/fetch_items/config->item('cron_key')?>
    Point your cron job to the above url Reset Key?
    + +

    + + + +

    + +

    ">Change Password

    + +
    validation->new_password_error) || isset($this->validation->new_password_confirm_error)):?> style="display: block;"> +

    +

    + +

    +

    +
    + +
    + +
    + + + +
    + +
    +

    Remember!
    After you change any options, click the "Save Options" button at the bottom of the page.

    + +
    \ No newline at end of file diff --git a/system/application/views/admin/.svn/text-base/write.php.svn-base b/system/application/views/admin/.svn/text-base/write.php.svn-base new file mode 100644 index 0000000..e01efaa --- /dev/null +++ b/system/application/views/admin/.svn/text-base/write.php.svn-base @@ -0,0 +1,67 @@ +
    + + + + + + +
    + + +
    + +

    +

    + +

    +

    + +

    +

    +Separate with commas e.g. these, are, my, tags

    + +item_feed_id)): ?> + +

    + +input->post('timestamp') == 'no_change'): ?> checked="checked" type="radio" name="timestamp" value="no_change" id="radio_no_change" /> +input->post('timestamp') == 'make_current'): ?> checked="checked" type="radio" name="timestamp" value="make_current" id="radio_make_current" /> +item_status == 'draft'): ?> +input->post('timestamp') == 'make_current_publish'): ?> checked="checked" type="radio" name="timestamp" value="make_current_publish" id="radio_make_current_publish" /> + + +

    + + + +
    + + +
    + + + + + + + + + Save as Draft + + +
    + + + +
    + +
    +

    Shorthand
    The blog post content area supports the Markdown method of shorthand markup.

    + +
    \ No newline at end of file diff --git a/system/application/views/admin/_activity_list.php b/system/application/views/admin/_activity_list.php new file mode 100644 index 0000000..88dacfd --- /dev/null +++ b/system/application/views/admin/_activity_list.php @@ -0,0 +1,38 @@ +
      + +
    • + +

      get_feed_domain()?> — get_human_date()?>

      +
      +

      get_title()?>

      + has_original_permalink()): ?> + + +
      get_content()?>
      + has_image()): ?> +
      + + +
      has_video()): ?> +
      get_video()?>
      +
      + + has_tags()): ?> +
        +
      • Tags:
      • + get_tags() as $tag): ?> +
      • name?>
      • + +
      + +
      +
      +
    • + +
    \ No newline at end of file diff --git a/system/application/views/admin/_footer.php b/system/application/views/admin/_footer.php new file mode 100644 index 0000000..db80c75 --- /dev/null +++ b/system/application/views/admin/_footer.php @@ -0,0 +1,9 @@ + +config)):?> +

    + +
    + + + + \ No newline at end of file diff --git a/system/application/views/admin/_header.php b/system/application/views/admin/_header.php new file mode 100644 index 0000000..5656c96 --- /dev/null +++ b/system/application/views/admin/_header.php @@ -0,0 +1,48 @@ + + + + + + + <?php echo $page_name?> › Sweetcron Admin Panel + + + + + + + + + + +
    + auth)): ?> +

    Welcome to Sweetcron

    +

    Installation - Step 1 of 1

    + auth->is_logged()): ?> +

    config->item('lifestream_title')?>

    +

    Logged in as data->user->user_login?> | logout?

    + +

    Welcome to Sweetcron

    +

    Please log in

    + +
    + +auth)): ?> + + + + \ No newline at end of file diff --git a/system/application/views/admin/dashboard.php b/system/application/views/admin/dashboard.php new file mode 100644 index 0000000..d0327a7 --- /dev/null +++ b/system/application/views/admin/dashboard.php @@ -0,0 +1,40 @@ +
    + + + +load->view('admin/_activity_list')?> + + + +
    You have no items :/
    + + + +
    + +
    + + +

    Hello there!
    Looks like it's your first time here. Why not start by adding some feeds?

    + + + +

    Greetings!
    This page shows the last 5 public items in your lifestream.

    + +

    Your Sweetcron Stats

    +
      +
    • Public Items:
    • +
    • Feeds:
    • +
    • Last Fetch: config->item('last_fetch'))?> ago
    • +
    + +

    Useful Links

    + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/feed_add.php b/system/application/views/admin/feed_add.php new file mode 100644 index 0000000..5c729a9 --- /dev/null +++ b/system/application/views/admin/feed_add.php @@ -0,0 +1,27 @@ +
    + + + + +
    + + +
    + +

    +

    + +
    + +
    + + + +
    + +
    +

    Not sure how to find a feed?
    Try simply putting the url of a webpage in the input box
    (e.g. http://twitter.com/yongfook) — it works 90% of the time!

    +
    \ No newline at end of file diff --git a/system/application/views/admin/feeds.php b/system/application/views/admin/feeds.php new file mode 100644 index 0000000..e6562fd --- /dev/null +++ b/system/application/views/admin/feeds.php @@ -0,0 +1,37 @@ +
    + + + +
      + +
    • +
        +
      • x
      • +
      +

      feed_title?>

      + + +

      item_count?> items

      + +
    • + +
    + + + +
    You have no feeds :/
    + + + +
    + + \ No newline at end of file diff --git a/system/application/views/admin/forgot.php b/system/application/views/admin/forgot.php new file mode 100644 index 0000000..177d88e --- /dev/null +++ b/system/application/views/admin/forgot.php @@ -0,0 +1,32 @@ +
    + + +
    + +
    + + + +
    + Instructions have been sent to your email acount. +
    + + +
    + +

    + disabled="disabled" class="text_input" type="text" name="email" value="input->post('email')?>" />

    + Input the administrator email address

    + + +
    + +
    + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/install.php b/system/application/views/admin/install.php new file mode 100644 index 0000000..4ad2857 --- /dev/null +++ b/system/application/views/admin/install.php @@ -0,0 +1,41 @@ +
    + + +
    + +
    + + + + +

    Installation Successful! Your login details are below:

    + +

    Username: validation->username?>
    + Password:

    + +

    You can now Log In »

    + + +
    + +

    +

    + +

    +

    + +

    +

    + +
    + +
    + + + + + +
    \ No newline at end of file diff --git a/system/application/views/admin/items.php b/system/application/views/admin/items.php new file mode 100644 index 0000000..1b7c5ea --- /dev/null +++ b/system/application/views/admin/items.php @@ -0,0 +1,97 @@ +
    + + + + + + + + + + + + + + + +load->view('admin/_activity_list')?> + + + +
    You have no items :/
    + + +

    +
    + +
    + + + +config->item('last_fetch')): ?> +

    Last fetch config->item('last_fetch'))?> ago

    + +

    Pending first fetch...

    + + +

    Search

    + +

    + + + +

    Your Feeds

    + + +

    Tags

    + +
      + +
    • + slug): ?> + name?> + + name?> + +
    • + +
    + +
      + +
    • + slug): ?> + name?> + + name?> + +
    • + +
    +

    Show All Tags

    + +No tags + +
    \ No newline at end of file diff --git a/system/application/views/admin/login.php b/system/application/views/admin/login.php new file mode 100644 index 0000000..296804b --- /dev/null +++ b/system/application/views/admin/login.php @@ -0,0 +1,31 @@ +
    + + +
    + +
    + + +
    + +

    +

    + +

    +

    + +
    + +
    + + + +
    + +
    +

    Forgot Password?
    Reset my password »

    + +
    \ No newline at end of file diff --git a/system/application/views/admin/options.php b/system/application/views/admin/options.php new file mode 100644 index 0000000..59d82f7 --- /dev/null +++ b/system/application/views/admin/options.php @@ -0,0 +1,63 @@ +
    + + +
    + + +
    + +

    +

    + +

    +

    + +

    + + + +

    + +

    + +config->item('cron_type') == 'pseudo'): ?>checked="checked" type="radio" name="cron_type" value="pseudo" id="radio_pseudo" /> (updates every 30 mins) +config->item('cron_type') == 'true'): ?>checked="checked" type="radio" name="cron_type" value="true" id="radio_true" /> + +

    +config->item('cron_type') == 'pseudo'): ?>style="display: none" id="cron_url" class="input_explain">config->item('base_url')?>cron/fetch_items/config->item('cron_key')?>
    Point your cron job to the above url Reset Key?
    + +

    + + + +

    + +

    ">Change Password

    + +
    validation->new_password_error) || isset($this->validation->new_password_confirm_error)):?> style="display: block;"> +

    +

    + +

    +

    +
    + +
    + +
    + + + +
    + +
    +

    Remember!
    After you change any options, click the "Save Options" button at the bottom of the page.

    + +
    \ No newline at end of file diff --git a/system/application/views/admin/write.php b/system/application/views/admin/write.php new file mode 100644 index 0000000..e01efaa --- /dev/null +++ b/system/application/views/admin/write.php @@ -0,0 +1,67 @@ +
    + + + + + + +
    + + +
    + +

    +

    + +

    +

    + +

    +

    +Separate with commas e.g. these, are, my, tags

    + +item_feed_id)): ?> + +

    + +input->post('timestamp') == 'no_change'): ?> checked="checked" type="radio" name="timestamp" value="no_change" id="radio_no_change" /> +input->post('timestamp') == 'make_current'): ?> checked="checked" type="radio" name="timestamp" value="make_current" id="radio_make_current" /> +item_status == 'draft'): ?> +input->post('timestamp') == 'make_current_publish'): ?> checked="checked" type="radio" name="timestamp" value="make_current_publish" id="radio_make_current_publish" /> + + +

    + + + +
    + + +
    + + + + + + + + + Save as Draft + + +
    + + + +
    + +
    +

    Shorthand
    The blog post content area supports the Markdown method of shorthand markup.

    + +
    \ No newline at end of file diff --git a/system/application/views/index.html b/system/application/views/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/application/views/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/views/themes/.svn/all-wcprops b/system/application/views/themes/.svn/all-wcprops new file mode 100644 index 0000000..9786d14 --- /dev/null +++ b/system/application/views/themes/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/122/trunk/system/application/views/themes +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/119/trunk/system/application/views/themes/index.html +END diff --git a/system/application/views/themes/.svn/entries b/system/application/views/themes/.svn/entries new file mode 100644 index 0000000..93eb251 --- /dev/null +++ b/system/application/views/themes/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views/themes +http://sweetcron.googlecode.com/svn + + + +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +boxy +dir + +index.html +file + + + + +2009-09-15T00:18:03.000000Z +dd54539243bb14cf4e88be902741435d +2008-11-13T12:07:45.088871Z +119 +yongfook + + + + + + + + + + + + + + + + + + + + + +135 + +sandbox +dir + diff --git a/system/application/views/themes/.svn/text-base/index.html.svn-base b/system/application/views/themes/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..233ae63 --- /dev/null +++ b/system/application/views/themes/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/all-wcprops b/system/application/views/themes/boxy/.svn/all-wcprops new file mode 100644 index 0000000..6739b92 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/all-wcprops @@ -0,0 +1,65 @@ +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/122/trunk/system/application/views/themes/boxy +END +rss_feed.php +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/122/trunk/system/application/views/themes/boxy/rss_feed.php +END +contact.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/contact.php +END +_footer.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/93/trunk/system/application/views/themes/boxy/_footer.php +END +_activity_feed.php +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/!svn/ver/91/trunk/system/application/views/themes/boxy/_activity_feed.php +END +items.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/items.php +END +single.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/94/trunk/system/application/views/themes/boxy/single.php +END +main.css +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/88/trunk/system/application/views/themes/boxy/main.css +END +_header.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/92/trunk/system/application/views/themes/boxy/_header.php +END +_sidebar.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/_sidebar.php +END +home.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/home.php +END diff --git a/system/application/views/themes/boxy/.svn/entries b/system/application/views/themes/boxy/.svn/entries new file mode 100644 index 0000000..6676b91 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/entries @@ -0,0 +1,371 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views/themes/boxy +http://sweetcron.googlecode.com/svn + + + +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +rss_feed.php +file + + + + +2009-09-15T00:18:03.000000Z +c87610c0e43b2534ae90bf0767dd494f +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + + + + + + + + +1291 + +contact.php +file + + + + +2009-09-15T00:18:03.000000Z +613a47d0e1add2aab9293e62ebf63df0 +2008-09-07T02:09:53.708186Z +86 +yongfook + + + + + + + + + + + + + + + + + + + + + +265 + +_footer.php +file + + + + +2009-09-15T00:18:03.000000Z +a1178d283cbd3b83b70e77911b1c9c87 +2008-09-08T16:05:27.804169Z +93 +yongfook + + + + + + + + + + + + + + + + + + + + + +419 + +_activity_feed.php +file + + + + +2009-09-15T00:18:03.000000Z +f74369bbe59aff6afe535e79c8103727 +2008-09-07T15:15:11.804117Z +91 +yongfook + + + + + + + + + + + + + + + + + + + + + +4972 + +images +dir + +items.php +file + + + + +2009-09-15T00:18:03.000000Z +c01153ae65a874f44daa573af69ba38a +2008-09-07T02:09:53.708186Z +86 +yongfook + + + + + + + + + + + + + + + + + + + + + +161 + +single.php +file + + + + +2009-09-15T00:18:03.000000Z +f93b4819fe337876db7e266c35846f3f +2008-09-08T23:39:43.153801Z +94 +yongfook + + + + + + + + + + + + + + + + + + + + + +2108 + +main.css +file + + + + +2009-09-15T00:18:03.000000Z +a4e86c66ab0be96ef65bbc4ff81e2a76 +2008-09-07T15:10:46.295258Z +88 +yongfook + + + + + + + + + + + + + + + + + + + + + +10675 + +_header.php +file + + + + +2009-09-15T00:18:03.000000Z +799d60497aee5926feb7bcf625cc6e92 +2008-09-07T15:28:33.621296Z +92 +yongfook + + + + + + + + + + + + + + + + + + + + + +2249 + +_sidebar.php +file + + + + +2009-09-15T00:18:03.000000Z +5849a2d0463071d1209b8f94b56b5f23 +2008-09-07T02:09:53.708186Z +86 +yongfook + + + + + + + + + + + + + + + + + + + + + +989 + +home.php +file + + + + +2009-09-15T00:18:03.000000Z +c01153ae65a874f44daa573af69ba38a +2008-09-07T02:09:53.708186Z +86 +yongfook + + + + + + + + + + + + + + + + + + + + + +161 + diff --git a/system/application/views/themes/boxy/.svn/text-base/_activity_feed.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/_activity_feed.php.svn-base new file mode 100644 index 0000000..9dacd3b --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/_activity_feed.php.svn-base @@ -0,0 +1,77 @@ +

    + + + + + + + + + + + + + +
      + + +
    • +

      I posted to get_feed_domain()?>

      +
      + + + + get_feed_domain() == 'opensourcefood.com'): ?> +
      + +

      get_title()?>get_content()), 28)?>

      + + get_feed_domain() == 'twitter.com'): ?> + + + + get_feed_domain() == 'vimeo.com'): ?> + get_video()?> +

      get_title()?>

      + + get_feed_domain() == 'youtube.com'): ?> + get_video()?> +

      get_title()?>

      +

      get_content()), 8)?>

      + + get_feed_domain() == 'digg.com'): ?> +
      +

      get_title()?>

      +

      get_content()), 38)?>

      +
      + + get_feed_domain() == 'flickr.com'): ?> +

      get_title()?>

      + + + feed_id): //this means it came from Sweetcron itself ?> +
      +

      get_title()?>

      +

      A blog post

      +
      + + +
      +

      The Boxy theme does not have a custom style for this type of item.

      +

      You can create one by editing the _activity_feed.php and main.css files.

      +

      Please read the Theme Docs and API for more information.

      +
      + + + +
      +

      get_human_date()?> | Comments »

      + +
    • + + +
    +
    +

    Page:

    + +
    \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/_footer.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/_footer.php.svn-base new file mode 100644 index 0000000..112a60d --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/_footer.php.svn-base @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/_header.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/_header.php.svn-base new file mode 100644 index 0000000..04d783e --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/_header.php.svn-base @@ -0,0 +1,41 @@ + + + + + + + + + <?php echo $page_name?> › <?php echo $this->config->item('lifestream_title')?> + + + + + + + + + + + + + + + + + + +
    diff --git a/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base new file mode 100644 index 0000000..08fb3ea --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/_sidebar.php.svn-base @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base new file mode 100644 index 0000000..65d32b7 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/contact.php.svn-base @@ -0,0 +1,8 @@ +
    +
    + + I recommend www.wufoo.com to create a contact form and paste it here! + +
    +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/home.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/home.php.svn-base new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/home.php.svn-base @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/items.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/items.php.svn-base new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/items.php.svn-base @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/main.css.svn-base b/system/application/views/themes/boxy/.svn/text-base/main.css.svn-base new file mode 100644 index 0000000..cadef23 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/main.css.svn-base @@ -0,0 +1,567 @@ +/* Sweetcron Boxy CSS - 08/09/2008 + + Table of Contents: + Reset + Typography + Positioning + Per-Domain Styling + IE Fixes + 3rd Party + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Arial, Helvetica, sans serif; + font-size: 12px; + color: #000; + line-height: 1.7em; +} + +ul#activity_list li.item.yongfook_com div.item_inner { + font-family: Georgia, 'Times New Roman', Times, serif; +} + +h1 { + font-size: 28px; +} + +a { + color: #3399ff; +} + +a:hover { + color: #003399; +} + +div#aboutme h3 { + color: #333; +} + +ul#navigation li.current a, ul#navigation li a:hover { + color: black; +} + +ul#activity_list li.item p.date, p.original_link a, p.activity_image_text span, p.site_info a, div#aboutme, p.blog_cite, div#single_header p, ul#navigation li a, p.osf_recipe { + color: #999; +} + +p.vimeo_title a, li.item.digg_com div.item_inner a, ul#activity_list li.item.youtube_com div.item_inner a, p.osf_recipe a, div#header h1 a { + color: white; +} + +ul#activity_list li.item.youtube_com div.item_inner { + color: #fd8585; +} + +li.item.digg_com div.item_inner { + color: #7698b7; +} + +div#explanation { + color: #999933; +} + +div#explanation strong { + color: #666633; +} + +input.text_input { + font-size: 13px; +} + +h2, div#explanation, div#single_container, ul#navigation li, p.osf_recipe { + font-size: 15px; +} + +p#pagination, ul#activity_list li.item.yongfook_com div.item_inner, div#single_container h3, div#single_container h4, div#single_container h5 { + font-size: 20px; +} + +div#single_container h2 { + font-size: 25px; +} + +ul#activity_list li.item p.date { + font-size: 9px; +} + +p.blog_cite, p.site_info, p.date, p.original_link, p.activity_image_text, div#aboutme, div#footer, ul#activity_list li.item.youtube_com div.item_inner, p.osf_recipe span { + font-size: 10px; +} + +p.activity_image_text a, p.twitter_tweet, p.vimeo_title, li.item.digg_com div.item_inner a, div#explanation strong, p#pagination, ul#activity_list li.item.youtube_com div.item_inner a, ul#activity_list li.item.yongfook_com div.item_inner, div#single_header, div#single_container strong, ul.item_tag_list, ul#navigation li, p.osf_recipe, div.instructions strong { + font-weight: bold; +} + +ul#activity_list li.item.yongfook_com div.item_inner p.blog_cite { + font-weight: normal; +} + +p.original_link a, p.activity_image_text a, p.site_info a, p.vimeo_title a, li.item.digg_com div.item_inner a, ul#activity_list li.item.youtube_com div.item_inner a, ul#navigation li a, p.osf_recipe a, div#header h1 a { + text-decoration: none; +} + +p.original_link a:hover, p.activity_image_text a:hover, li.item.digg_com div.item_inner a:hover { + text-decoration: underline; +} + +p.vimeo_title, ul#activity_list li.item.youtube_com div.item_inner, ul#activity_list li.item.yongfook_com div.item_inner { + text-align: center; +} + +div#single_header h2 { + line-height: 1.1em; +} + +p.activity_image_text { + line-height: 1.5em; +} + +p.twitter_tweet, div#aboutme, ul#activity_list li.item.youtube_com div.item_inner { + line-height: 1.6em; +} + + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body { + background: white; +} + +div.center_box { + width: 980px; + margin: 0 auto; + position: relative; +} + +div#header { + background: #99ccff; +} + +div#header div.center_box { + height: 150px; +} + +div#header h1 { + position: absolute; + top: 50px; + left: 0; +} + +div#header h1 a { + border: 1px solid #b8dbfe; + border-style: none none solid none; +} + +div#header h1 a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +ul#navigation { + position: absolute; + left: 0; + bottom: 0; +} + +ul#navigation li { + float: left; + margin-right: 1px; +} + +ul#navigation li a { + float: left; + padding: 8px 15px; + background: white url(images/blogback.jpg) bottom left no-repeat; +} + +ul#navigation li.current a { + background: white; +} + +div#main_container { + margin: 15px 0 0 0; + width: 663px; + float: left; +} + +div#sidebar_container { + display: inline; + width: 300px; + float: left; + margin: 15px 0 0 15px; +} + +p.site_info { + padding: 3px 3px 3px 22px; +} + +ul#activity_list { + float: left; +} + +ul#activity_list li.item { + width: 211px; + margin: 0 15px 15px 0; + float: left; + overflow: hidden; +} + +div.item_inner { + border: 1px solid #CCC; + height: 250px; + overflow: hidden; + position: relative; +} + +ul#activity_list li.item.last { + margin-right: 0; +} + +li.item img, div#single_container img { + display: block; +} + +ul.item_tag_list li { + display: inline; +} + +div.clear { + clear: both; +} + +p#breadcrumb, p#pagination { + margin-bottom: 15px; + padding: 3px; + border: 1px solid #CCC; + border-style: dotted none; +} + +p#pagination { + padding: 10px 0; +} + +div#sidebar_container h3 { + border: 1px solid #CCC; + border-style: none none solid none; + margin: 10px 0 5px 0; +} + +div#sidebar_container div#aboutme_blurb h3 { + margin-top: 0; + border: none; +} + +ul.tag_list li { + display: inline; + margin: 0 5px 0 0; +} + +div#comments_container { + border: 1px solid #EEE; + border-style: solid none none none; + padding: 10px 0; + margin-top: 20px; +} + +div.ad_container img { + display: block; +} + +div.ad_container.bottom { + margin: 15px 0; +} + +form#search_form { + margin: 8px 0 0 0; +} + +form#mailing_list { + margin-top: 15px; + background: white url(images/mailinglist.gif) 0 0 no-repeat; + border: 1px solid #CCC; +} + +form#mailing_list p { + padding: 70px 10px 10px 10px; +} + +input.text_input { + background: #FFFFCC; + width: 180px; +} + +div#explanation { + background: #FFFFCC; + padding: 10px; + margin: 15px 0; +} + +div#aboutme_blurb { + width: 180px; + border: 1px solid #EEE; + border-style: none solid none none; + padding: 0 15px 0 0; + float: left; + margin-right: 15px; +} + +div#aboutme ul { + list-style-type: disc; +} + +div#aboutme ul li { + padding-bottom: 5px; +} + +div#aboutme h3, div#aboutme ul, div#aboutme p { + margin-left: 20px; +} + +div#aboutme h3 { + margin-bottom: 5px; +} + +p.sidebar_small_banner img { + display: block; + margin-bottom: 10px; +} + +div#footer { + clear: both; +} + +div#footer { + background: #EEE; + padding: 8px; + position: relative; +} + +a#credits { + position: absolute; + right: 10px; + top: 6px; +} + +div#single_header { + padding: 10px 0 15px 0; +} + +div#single_content p, div#single_container object, div#single_container img, div#single_container ul, div#single_container ol { + margin-bottom: 15px; +} + +div#single_container img { + border: 1px solid #CCC; + padding: 5px; +} + +div#single_container h3, div#single_container h4, div#single_container h5 { + border: 1px solid #CCC; + border-style: none none dotted none; + padding-bottom: 8px; + margin-bottom: 8px; + margin-top: 25px; +} + +p#original_permalink span { + background: #FFFFCC; +} + +div.activity_list_inner img { + float: left; + margin-right: 10px; +} + +li.activity_item { + clear: both; +} + +/* Per-Domain Styling +---------------------------------------------------------------------------------------- */ + +li.item.flickr_com { + background: white url(images/flickrlogo.gif) center center no-repeat; +} + +li.item.flickr_com p.site_info { + background: blue; +} + +li.item.vimeo_com div.item_inner { + background: #80ceff url(images/vimeoback.jpg) bottom center no-repeat; +} + +li.item.vimeo_com div.item_inner object { + border: 1px solid white; + border-style: none none solid none; +} + +ul#activity_list li.item.twitter_com div.item_inner { + background: url(images/twitterback.jpg); +} + +p.vimeo_title a { + border: 1px solid #a7dafa; + border-style: none none solid none; +} + +p.vimeo_title a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +p.twitter_user { + margin: 10px 0 0 10px; + padding-bottom: 10px; + background: transparent url(images/twittertail.gif) bottom 60px no-repeat; +} + +p.twitter_user img { + display: block; + border: 1px solid #999; +} + +p.twitter_tweet { + background: white; + padding: 8px 10px; + overflow: hidden; + background: white url(images/twitterdither.gif) bottom left repeat-x; + border: 1px solid #DDD; + border-style: none none solid none; + margin: 0 10px; +} + +ul#activity_list li.item.digg_com div.item_inner { + background: #1b5790 url(images/diggback.gif) bottom right no-repeat; +} + +li.item.digg_com div.item_inner a { + border: 1px solid #7698b7; + border-style: none none dotted none; + display: block; + padding-bottom: 5px; + margin-bottom: 5px; +} + +div.inner_container { + padding: 8px 10px; +} + +ul#activity_list li.item.youtube_com div.item_inner { + background: #FE3333 url(images/youtubeback.gif) bottom left repeat-x; +} + +ul#activity_list li.item.youtube_com div.item_inner object { + border: 1px solid white; + border-style: none none solid none; + margin-bottom: 7px; +} + +ul#activity_list li.item.youtube_com div.item_inner p { + padding: 0 10px; +} + +ul#activity_list li.item.youtube_com div.item_inner a { + border: 1px solid #f07777; + border-style: none none solid none; +} + +ul#activity_list li.item.youtube_com div.item_inner a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +ul#activity_list li.item.yongfook_com div.item_inner { + background: white url(images/blogback.jpg) bottom left no-repeat; +} + +p.blog_title, p.blog_cite { + margin: 15px 0 20px 0; +} + +ul#activity_list li.item.yongfook_com div.item_inner img { + display: inline; +} + +li.item.opensourcefood_com img { + position: absolute; + bottom: 0; + right: 0; + z-index: 0; +} + +div.osf_fold a { + height: 250px; + width: 211px; + background: transparent url(images/osfback.png) bottom right no-repeat; + z-index: 1000; + position: absolute; +} + +p.osf_recipe { + position: absolute; + z-index: 1001; + top: 10px; + left: 10px; + width: 190px; +} + +p.osf_recipe a { + border: 1px solid #333; + border-style: none none solid none; +} + +p.osf_recipe a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +p.osf_recipe span { + margin-top: 3px; + display: block; + width: 180px; +} + +a.activity_image { + display: block; + height: 250px; +} + +p.activity_image_text { + position: absolute; + top: 0; + padding: 3px 5px; + background: black; +} + +div.instructions code { + background: #FFFFCC; +} + + +/* IE Fixes (lulz) +---------------------------------------------------------------------------------------- */ + +body { + word-wrap: break-word; +} + + +/* 3rd Party +---------------------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/rss_feed.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/rss_feed.php.svn-base new file mode 100644 index 0000000..2ba3a05 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/rss_feed.php.svn-base @@ -0,0 +1,27 @@ + + + <?php echo $this->config->item('lifestream_title')?> <?php echo $page_name?> + config->item('base_url')?>feed + + en-us + http://blogs.law.harvard.edu/tech/rss + Sweetcron + config->item('admin_email')?> + + + <?php echo htmlspecialchars(htmlspecialchars_decode($item->get_title()))?> + get_permalink()?>/get_name()?> + get_content()?> + has_image() && !$item->has_video()): ?> + + + has_video()): ?> + get_video()?> + +
    ]]> + get_date())?> + get_permalink()?>/get_name()?> + + + + \ No newline at end of file diff --git a/system/application/views/themes/boxy/.svn/text-base/single.php.svn-base b/system/application/views/themes/boxy/.svn/text-base/single.php.svn-base new file mode 100644 index 0000000..092b724 --- /dev/null +++ b/system/application/views/themes/boxy/.svn/text-base/single.php.svn-base @@ -0,0 +1,52 @@ +
    +config->item('base_url'); +endif; ?> + + +
    +
    +

    get_title()?>

    +

    get_human_date()?>

    +
    + + has_content()): ?> +
    get_content()?>
    + + has_image() && !$item->has_video()): ?> + item_data[$item->get_feed_class()]['image']['m']) && !empty($item->item_data[$item->get_feed_class()]['image']['m'])): ?> +

    + +

    + + + has_video()): ?> +

    + get_video()); + $video = str_replace('height="159"', 'height="375"', $video); + $video = str_replace('height="178"', 'height="415"', $video); + echo $video?> +

    + + has_tags()): ?> +
      +
    • Tags:
    • + get_tags() as $tag): ?> +
    • name?>
    • + +
    + + get_original_permalink()): ?> + + +
    + +
    + Your favourite external commenting service goes here! I recommend http://www.disqus.com +
    + +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/_activity_feed.php b/system/application/views/themes/boxy/_activity_feed.php new file mode 100644 index 0000000..9dacd3b --- /dev/null +++ b/system/application/views/themes/boxy/_activity_feed.php @@ -0,0 +1,77 @@ +
    + + + + + + + + + + + + + +
      + + +
    • +

      I posted to get_feed_domain()?>

      +
      + + + + get_feed_domain() == 'opensourcefood.com'): ?> +
      + +

      get_title()?>get_content()), 28)?>

      + + get_feed_domain() == 'twitter.com'): ?> + + + + get_feed_domain() == 'vimeo.com'): ?> + get_video()?> +

      get_title()?>

      + + get_feed_domain() == 'youtube.com'): ?> + get_video()?> +

      get_title()?>

      +

      get_content()), 8)?>

      + + get_feed_domain() == 'digg.com'): ?> +
      +

      get_title()?>

      +

      get_content()), 38)?>

      +
      + + get_feed_domain() == 'flickr.com'): ?> +

      get_title()?>

      + + + feed_id): //this means it came from Sweetcron itself ?> +
      +

      get_title()?>

      +

      A blog post

      +
      + + +
      +

      The Boxy theme does not have a custom style for this type of item.

      +

      You can create one by editing the _activity_feed.php and main.css files.

      +

      Please read the Theme Docs and API for more information.

      +
      + + + +
      +

      get_human_date()?> | Comments »

      + +
    • + + +
    +
    +

    Page:

    + +
    \ No newline at end of file diff --git a/system/application/views/themes/boxy/_footer.php b/system/application/views/themes/boxy/_footer.php new file mode 100644 index 0000000..112a60d --- /dev/null +++ b/system/application/views/themes/boxy/_footer.php @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/system/application/views/themes/boxy/_header.php b/system/application/views/themes/boxy/_header.php new file mode 100644 index 0000000..04d783e --- /dev/null +++ b/system/application/views/themes/boxy/_header.php @@ -0,0 +1,41 @@ + + + + + + + + + <?php echo $page_name?> › <?php echo $this->config->item('lifestream_title')?> + + + + + + + + + + + + + + + + + + +
    diff --git a/system/application/views/themes/boxy/_sidebar.php b/system/application/views/themes/boxy/_sidebar.php new file mode 100644 index 0000000..08fb3ea --- /dev/null +++ b/system/application/views/themes/boxy/_sidebar.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/system/application/views/themes/boxy/contact.php b/system/application/views/themes/boxy/contact.php new file mode 100644 index 0000000..65d32b7 --- /dev/null +++ b/system/application/views/themes/boxy/contact.php @@ -0,0 +1,8 @@ +
    +
    + + I recommend www.wufoo.com to create a contact form and paste it here! + +
    +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/home.php b/system/application/views/themes/boxy/home.php new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/boxy/home.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/images/.svn/all-wcprops b/system/application/views/themes/boxy/images/.svn/all-wcprops new file mode 100644 index 0000000..4e235d2 --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/all-wcprops @@ -0,0 +1,71 @@ +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images +END +diggback.gif +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/diggback.gif +END +vimeoback.jpg +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/vimeoback.jpg +END +twittertail.gif +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/twittertail.gif +END +credits.gif +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/credits.gif +END +youtubeback.gif +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/youtubeback.gif +END +twitterback.jpg +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/twitterback.jpg +END +me_twitter.jpg +K 25 +svn:wc:ra_dav:version-url +V 81 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/me_twitter.jpg +END +ad.jpg +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/ad.jpg +END +blogback.jpg +K 25 +svn:wc:ra_dav:version-url +V 79 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/blogback.jpg +END +twitterdither.gif +K 25 +svn:wc:ra_dav:version-url +V 84 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/twitterdither.gif +END +osfback.png +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/!svn/ver/86/trunk/system/application/views/themes/boxy/images/osfback.png +END diff --git a/system/application/views/themes/boxy/images/.svn/entries b/system/application/views/themes/boxy/images/.svn/entries new file mode 100644 index 0000000..cff06a6 --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/entries @@ -0,0 +1,402 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views/themes/boxy/images +http://sweetcron.googlecode.com/svn + + + +2008-09-07T02:09:53.708186Z +86 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +diggback.gif +file + + + + +2009-09-15T00:18:03.000000Z +2c9e7a574ae6b16e0cd7932880f9a507 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1014 + +vimeoback.jpg +file + + + + +2009-09-15T00:18:03.000000Z +50c12cc1fa77b83aa97038940f4f4306 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7141 + +twittertail.gif +file + + + + +2009-09-15T00:18:03.000000Z +1d4936b6d9114b2c28d6d2fd16207df1 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +334 + +credits.gif +file + + + + +2009-09-15T00:18:03.000000Z +a07cda127cc38e51ab48ee9335529ace +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1561 + +youtubeback.gif +file + + + + +2009-09-15T00:18:03.000000Z +3f84ad471b3ea3a86569c79b26f37471 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2940 + +twitterback.jpg +file + + + + +2009-09-15T00:18:03.000000Z +52bec52662a6775da9aa2a631c800b56 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +11371 + +me_twitter.jpg +file + + + + +2009-09-15T00:18:03.000000Z +3fffbc138a39233ea19610535df8635e +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1246 + +ad.jpg +file + + + + +2009-09-15T00:18:03.000000Z +f59c7bc12870e980957e53d0f21d3b83 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15285 + +blogback.jpg +file + + + + +2009-09-15T00:18:03.000000Z +da5aa90b8fa055d17c4d4a247d8e4817 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1096 + +twitterdither.gif +file + + + + +2009-09-15T00:18:03.000000Z +b0178b2c4c8724bec3325eb51038eea7 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +131 + +osfback.png +file + + + + +2009-09-15T00:18:03.000000Z +aeaec7f905b09eb9640404a3e84632a2 +2008-09-07T02:09:53.708186Z +86 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1981 + diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/ad.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/ad.jpg.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/ad.jpg.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/blogback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/blogback.jpg.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/blogback.jpg.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/credits.gif.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/credits.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/credits.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/diggback.gif.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/diggback.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/diggback.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/me_twitter.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/me_twitter.jpg.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/me_twitter.jpg.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/osfback.png.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/osfback.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/osfback.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/twitterback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/twitterback.jpg.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/twitterback.jpg.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/twitterdither.gif.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/twitterdither.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/twitterdither.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/twittertail.gif.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/twittertail.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/twittertail.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/vimeoback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/vimeoback.jpg.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/vimeoback.jpg.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/prop-base/youtubeback.gif.svn-base b/system/application/views/themes/boxy/images/.svn/prop-base/youtubeback.gif.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/system/application/views/themes/boxy/images/.svn/prop-base/youtubeback.gif.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/application/views/themes/boxy/images/.svn/text-base/ad.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/ad.jpg.svn-base new file mode 100644 index 0000000..045ea84 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/ad.jpg.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/blogback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/blogback.jpg.svn-base new file mode 100644 index 0000000..ce7ed7e Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/blogback.jpg.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/credits.gif.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/credits.gif.svn-base new file mode 100644 index 0000000..32571d7 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/credits.gif.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/diggback.gif.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/diggback.gif.svn-base new file mode 100644 index 0000000..d811b51 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/diggback.gif.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/me_twitter.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/me_twitter.jpg.svn-base new file mode 100644 index 0000000..a10b2e7 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/me_twitter.jpg.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/osfback.png.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/osfback.png.svn-base new file mode 100644 index 0000000..cb71004 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/osfback.png.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/twitterback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/twitterback.jpg.svn-base new file mode 100644 index 0000000..f9d9177 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/twitterback.jpg.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/twitterdither.gif.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/twitterdither.gif.svn-base new file mode 100644 index 0000000..d1fd5f1 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/twitterdither.gif.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/twittertail.gif.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/twittertail.gif.svn-base new file mode 100644 index 0000000..0045e9f Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/twittertail.gif.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/vimeoback.jpg.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/vimeoback.jpg.svn-base new file mode 100644 index 0000000..780a524 Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/vimeoback.jpg.svn-base differ diff --git a/system/application/views/themes/boxy/images/.svn/text-base/youtubeback.gif.svn-base b/system/application/views/themes/boxy/images/.svn/text-base/youtubeback.gif.svn-base new file mode 100644 index 0000000..7e37eca Binary files /dev/null and b/system/application/views/themes/boxy/images/.svn/text-base/youtubeback.gif.svn-base differ diff --git a/system/application/views/themes/boxy/images/ad.jpg b/system/application/views/themes/boxy/images/ad.jpg new file mode 100644 index 0000000..045ea84 Binary files /dev/null and b/system/application/views/themes/boxy/images/ad.jpg differ diff --git a/system/application/views/themes/boxy/images/blogback.jpg b/system/application/views/themes/boxy/images/blogback.jpg new file mode 100644 index 0000000..ce7ed7e Binary files /dev/null and b/system/application/views/themes/boxy/images/blogback.jpg differ diff --git a/system/application/views/themes/boxy/images/credits.gif b/system/application/views/themes/boxy/images/credits.gif new file mode 100644 index 0000000..32571d7 Binary files /dev/null and b/system/application/views/themes/boxy/images/credits.gif differ diff --git a/system/application/views/themes/boxy/images/diggback.gif b/system/application/views/themes/boxy/images/diggback.gif new file mode 100644 index 0000000..d811b51 Binary files /dev/null and b/system/application/views/themes/boxy/images/diggback.gif differ diff --git a/system/application/views/themes/boxy/images/me_twitter.jpg b/system/application/views/themes/boxy/images/me_twitter.jpg new file mode 100644 index 0000000..a10b2e7 Binary files /dev/null and b/system/application/views/themes/boxy/images/me_twitter.jpg differ diff --git a/system/application/views/themes/boxy/images/osfback.png b/system/application/views/themes/boxy/images/osfback.png new file mode 100644 index 0000000..cb71004 Binary files /dev/null and b/system/application/views/themes/boxy/images/osfback.png differ diff --git a/system/application/views/themes/boxy/images/twitterback.jpg b/system/application/views/themes/boxy/images/twitterback.jpg new file mode 100644 index 0000000..f9d9177 Binary files /dev/null and b/system/application/views/themes/boxy/images/twitterback.jpg differ diff --git a/system/application/views/themes/boxy/images/twitterdither.gif b/system/application/views/themes/boxy/images/twitterdither.gif new file mode 100644 index 0000000..d1fd5f1 Binary files /dev/null and b/system/application/views/themes/boxy/images/twitterdither.gif differ diff --git a/system/application/views/themes/boxy/images/twittertail.gif b/system/application/views/themes/boxy/images/twittertail.gif new file mode 100644 index 0000000..0045e9f Binary files /dev/null and b/system/application/views/themes/boxy/images/twittertail.gif differ diff --git a/system/application/views/themes/boxy/images/vimeoback.jpg b/system/application/views/themes/boxy/images/vimeoback.jpg new file mode 100644 index 0000000..780a524 Binary files /dev/null and b/system/application/views/themes/boxy/images/vimeoback.jpg differ diff --git a/system/application/views/themes/boxy/images/youtubeback.gif b/system/application/views/themes/boxy/images/youtubeback.gif new file mode 100644 index 0000000..7e37eca Binary files /dev/null and b/system/application/views/themes/boxy/images/youtubeback.gif differ diff --git a/system/application/views/themes/boxy/items.php b/system/application/views/themes/boxy/items.php new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/boxy/items.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/boxy/main.css b/system/application/views/themes/boxy/main.css new file mode 100644 index 0000000..cadef23 --- /dev/null +++ b/system/application/views/themes/boxy/main.css @@ -0,0 +1,567 @@ +/* Sweetcron Boxy CSS - 08/09/2008 + + Table of Contents: + Reset + Typography + Positioning + Per-Domain Styling + IE Fixes + 3rd Party + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Arial, Helvetica, sans serif; + font-size: 12px; + color: #000; + line-height: 1.7em; +} + +ul#activity_list li.item.yongfook_com div.item_inner { + font-family: Georgia, 'Times New Roman', Times, serif; +} + +h1 { + font-size: 28px; +} + +a { + color: #3399ff; +} + +a:hover { + color: #003399; +} + +div#aboutme h3 { + color: #333; +} + +ul#navigation li.current a, ul#navigation li a:hover { + color: black; +} + +ul#activity_list li.item p.date, p.original_link a, p.activity_image_text span, p.site_info a, div#aboutme, p.blog_cite, div#single_header p, ul#navigation li a, p.osf_recipe { + color: #999; +} + +p.vimeo_title a, li.item.digg_com div.item_inner a, ul#activity_list li.item.youtube_com div.item_inner a, p.osf_recipe a, div#header h1 a { + color: white; +} + +ul#activity_list li.item.youtube_com div.item_inner { + color: #fd8585; +} + +li.item.digg_com div.item_inner { + color: #7698b7; +} + +div#explanation { + color: #999933; +} + +div#explanation strong { + color: #666633; +} + +input.text_input { + font-size: 13px; +} + +h2, div#explanation, div#single_container, ul#navigation li, p.osf_recipe { + font-size: 15px; +} + +p#pagination, ul#activity_list li.item.yongfook_com div.item_inner, div#single_container h3, div#single_container h4, div#single_container h5 { + font-size: 20px; +} + +div#single_container h2 { + font-size: 25px; +} + +ul#activity_list li.item p.date { + font-size: 9px; +} + +p.blog_cite, p.site_info, p.date, p.original_link, p.activity_image_text, div#aboutme, div#footer, ul#activity_list li.item.youtube_com div.item_inner, p.osf_recipe span { + font-size: 10px; +} + +p.activity_image_text a, p.twitter_tweet, p.vimeo_title, li.item.digg_com div.item_inner a, div#explanation strong, p#pagination, ul#activity_list li.item.youtube_com div.item_inner a, ul#activity_list li.item.yongfook_com div.item_inner, div#single_header, div#single_container strong, ul.item_tag_list, ul#navigation li, p.osf_recipe, div.instructions strong { + font-weight: bold; +} + +ul#activity_list li.item.yongfook_com div.item_inner p.blog_cite { + font-weight: normal; +} + +p.original_link a, p.activity_image_text a, p.site_info a, p.vimeo_title a, li.item.digg_com div.item_inner a, ul#activity_list li.item.youtube_com div.item_inner a, ul#navigation li a, p.osf_recipe a, div#header h1 a { + text-decoration: none; +} + +p.original_link a:hover, p.activity_image_text a:hover, li.item.digg_com div.item_inner a:hover { + text-decoration: underline; +} + +p.vimeo_title, ul#activity_list li.item.youtube_com div.item_inner, ul#activity_list li.item.yongfook_com div.item_inner { + text-align: center; +} + +div#single_header h2 { + line-height: 1.1em; +} + +p.activity_image_text { + line-height: 1.5em; +} + +p.twitter_tweet, div#aboutme, ul#activity_list li.item.youtube_com div.item_inner { + line-height: 1.6em; +} + + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body { + background: white; +} + +div.center_box { + width: 980px; + margin: 0 auto; + position: relative; +} + +div#header { + background: #99ccff; +} + +div#header div.center_box { + height: 150px; +} + +div#header h1 { + position: absolute; + top: 50px; + left: 0; +} + +div#header h1 a { + border: 1px solid #b8dbfe; + border-style: none none solid none; +} + +div#header h1 a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +ul#navigation { + position: absolute; + left: 0; + bottom: 0; +} + +ul#navigation li { + float: left; + margin-right: 1px; +} + +ul#navigation li a { + float: left; + padding: 8px 15px; + background: white url(images/blogback.jpg) bottom left no-repeat; +} + +ul#navigation li.current a { + background: white; +} + +div#main_container { + margin: 15px 0 0 0; + width: 663px; + float: left; +} + +div#sidebar_container { + display: inline; + width: 300px; + float: left; + margin: 15px 0 0 15px; +} + +p.site_info { + padding: 3px 3px 3px 22px; +} + +ul#activity_list { + float: left; +} + +ul#activity_list li.item { + width: 211px; + margin: 0 15px 15px 0; + float: left; + overflow: hidden; +} + +div.item_inner { + border: 1px solid #CCC; + height: 250px; + overflow: hidden; + position: relative; +} + +ul#activity_list li.item.last { + margin-right: 0; +} + +li.item img, div#single_container img { + display: block; +} + +ul.item_tag_list li { + display: inline; +} + +div.clear { + clear: both; +} + +p#breadcrumb, p#pagination { + margin-bottom: 15px; + padding: 3px; + border: 1px solid #CCC; + border-style: dotted none; +} + +p#pagination { + padding: 10px 0; +} + +div#sidebar_container h3 { + border: 1px solid #CCC; + border-style: none none solid none; + margin: 10px 0 5px 0; +} + +div#sidebar_container div#aboutme_blurb h3 { + margin-top: 0; + border: none; +} + +ul.tag_list li { + display: inline; + margin: 0 5px 0 0; +} + +div#comments_container { + border: 1px solid #EEE; + border-style: solid none none none; + padding: 10px 0; + margin-top: 20px; +} + +div.ad_container img { + display: block; +} + +div.ad_container.bottom { + margin: 15px 0; +} + +form#search_form { + margin: 8px 0 0 0; +} + +form#mailing_list { + margin-top: 15px; + background: white url(images/mailinglist.gif) 0 0 no-repeat; + border: 1px solid #CCC; +} + +form#mailing_list p { + padding: 70px 10px 10px 10px; +} + +input.text_input { + background: #FFFFCC; + width: 180px; +} + +div#explanation { + background: #FFFFCC; + padding: 10px; + margin: 15px 0; +} + +div#aboutme_blurb { + width: 180px; + border: 1px solid #EEE; + border-style: none solid none none; + padding: 0 15px 0 0; + float: left; + margin-right: 15px; +} + +div#aboutme ul { + list-style-type: disc; +} + +div#aboutme ul li { + padding-bottom: 5px; +} + +div#aboutme h3, div#aboutme ul, div#aboutme p { + margin-left: 20px; +} + +div#aboutme h3 { + margin-bottom: 5px; +} + +p.sidebar_small_banner img { + display: block; + margin-bottom: 10px; +} + +div#footer { + clear: both; +} + +div#footer { + background: #EEE; + padding: 8px; + position: relative; +} + +a#credits { + position: absolute; + right: 10px; + top: 6px; +} + +div#single_header { + padding: 10px 0 15px 0; +} + +div#single_content p, div#single_container object, div#single_container img, div#single_container ul, div#single_container ol { + margin-bottom: 15px; +} + +div#single_container img { + border: 1px solid #CCC; + padding: 5px; +} + +div#single_container h3, div#single_container h4, div#single_container h5 { + border: 1px solid #CCC; + border-style: none none dotted none; + padding-bottom: 8px; + margin-bottom: 8px; + margin-top: 25px; +} + +p#original_permalink span { + background: #FFFFCC; +} + +div.activity_list_inner img { + float: left; + margin-right: 10px; +} + +li.activity_item { + clear: both; +} + +/* Per-Domain Styling +---------------------------------------------------------------------------------------- */ + +li.item.flickr_com { + background: white url(images/flickrlogo.gif) center center no-repeat; +} + +li.item.flickr_com p.site_info { + background: blue; +} + +li.item.vimeo_com div.item_inner { + background: #80ceff url(images/vimeoback.jpg) bottom center no-repeat; +} + +li.item.vimeo_com div.item_inner object { + border: 1px solid white; + border-style: none none solid none; +} + +ul#activity_list li.item.twitter_com div.item_inner { + background: url(images/twitterback.jpg); +} + +p.vimeo_title a { + border: 1px solid #a7dafa; + border-style: none none solid none; +} + +p.vimeo_title a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +p.twitter_user { + margin: 10px 0 0 10px; + padding-bottom: 10px; + background: transparent url(images/twittertail.gif) bottom 60px no-repeat; +} + +p.twitter_user img { + display: block; + border: 1px solid #999; +} + +p.twitter_tweet { + background: white; + padding: 8px 10px; + overflow: hidden; + background: white url(images/twitterdither.gif) bottom left repeat-x; + border: 1px solid #DDD; + border-style: none none solid none; + margin: 0 10px; +} + +ul#activity_list li.item.digg_com div.item_inner { + background: #1b5790 url(images/diggback.gif) bottom right no-repeat; +} + +li.item.digg_com div.item_inner a { + border: 1px solid #7698b7; + border-style: none none dotted none; + display: block; + padding-bottom: 5px; + margin-bottom: 5px; +} + +div.inner_container { + padding: 8px 10px; +} + +ul#activity_list li.item.youtube_com div.item_inner { + background: #FE3333 url(images/youtubeback.gif) bottom left repeat-x; +} + +ul#activity_list li.item.youtube_com div.item_inner object { + border: 1px solid white; + border-style: none none solid none; + margin-bottom: 7px; +} + +ul#activity_list li.item.youtube_com div.item_inner p { + padding: 0 10px; +} + +ul#activity_list li.item.youtube_com div.item_inner a { + border: 1px solid #f07777; + border-style: none none solid none; +} + +ul#activity_list li.item.youtube_com div.item_inner a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +ul#activity_list li.item.yongfook_com div.item_inner { + background: white url(images/blogback.jpg) bottom left no-repeat; +} + +p.blog_title, p.blog_cite { + margin: 15px 0 20px 0; +} + +ul#activity_list li.item.yongfook_com div.item_inner img { + display: inline; +} + +li.item.opensourcefood_com img { + position: absolute; + bottom: 0; + right: 0; + z-index: 0; +} + +div.osf_fold a { + height: 250px; + width: 211px; + background: transparent url(images/osfback.png) bottom right no-repeat; + z-index: 1000; + position: absolute; +} + +p.osf_recipe { + position: absolute; + z-index: 1001; + top: 10px; + left: 10px; + width: 190px; +} + +p.osf_recipe a { + border: 1px solid #333; + border-style: none none solid none; +} + +p.osf_recipe a:hover { + border: 1px solid white; + border-style: none none solid none; +} + +p.osf_recipe span { + margin-top: 3px; + display: block; + width: 180px; +} + +a.activity_image { + display: block; + height: 250px; +} + +p.activity_image_text { + position: absolute; + top: 0; + padding: 3px 5px; + background: black; +} + +div.instructions code { + background: #FFFFCC; +} + + +/* IE Fixes (lulz) +---------------------------------------------------------------------------------------- */ + +body { + word-wrap: break-word; +} + + +/* 3rd Party +---------------------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/system/application/views/themes/boxy/rss_feed.php b/system/application/views/themes/boxy/rss_feed.php new file mode 100644 index 0000000..2ba3a05 --- /dev/null +++ b/system/application/views/themes/boxy/rss_feed.php @@ -0,0 +1,27 @@ + + + <?php echo $this->config->item('lifestream_title')?> <?php echo $page_name?> + config->item('base_url')?>feed + + en-us + http://blogs.law.harvard.edu/tech/rss + Sweetcron + config->item('admin_email')?> + + + <?php echo htmlspecialchars(htmlspecialchars_decode($item->get_title()))?> + get_permalink()?>/get_name()?> + get_content()?> + has_image() && !$item->has_video()): ?> + + + has_video()): ?> + get_video()?> + +
    ]]> + get_date())?> + get_permalink()?>/get_name()?> + + + + \ No newline at end of file diff --git a/system/application/views/themes/boxy/single.php b/system/application/views/themes/boxy/single.php new file mode 100644 index 0000000..092b724 --- /dev/null +++ b/system/application/views/themes/boxy/single.php @@ -0,0 +1,52 @@ +
    +config->item('base_url'); +endif; ?> + + +
    +
    +

    get_title()?>

    +

    get_human_date()?>

    +
    + + has_content()): ?> +
    get_content()?>
    + + has_image() && !$item->has_video()): ?> + item_data[$item->get_feed_class()]['image']['m']) && !empty($item->item_data[$item->get_feed_class()]['image']['m'])): ?> +

    + +

    + + + has_video()): ?> +

    + get_video()); + $video = str_replace('height="159"', 'height="375"', $video); + $video = str_replace('height="178"', 'height="415"', $video); + echo $video?> +

    + + has_tags()): ?> +
      +
    • Tags:
    • + get_tags() as $tag): ?> +
    • name?>
    • + +
    + + get_original_permalink()): ?> + + +
    + +
    + Your favourite external commenting service goes here! I recommend http://www.disqus.com +
    + +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/index.html b/system/application/views/themes/index.html new file mode 100644 index 0000000..233ae63 --- /dev/null +++ b/system/application/views/themes/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/all-wcprops b/system/application/views/themes/sandbox/.svn/all-wcprops new file mode 100644 index 0000000..879a06d --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/all-wcprops @@ -0,0 +1,65 @@ +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/122/trunk/system/application/views/themes/sandbox +END +rss_feed.php +K 25 +svn:wc:ra_dav:version-url +V 76 +/svn/!svn/ver/122/trunk/system/application/views/themes/sandbox/rss_feed.php +END +contact.php +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/contact.php +END +_footer.php +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/_footer.php +END +_activity_feed.php +K 25 +svn:wc:ra_dav:version-url +V 81 +/svn/!svn/ver/52/trunk/system/application/views/themes/sandbox/_activity_feed.php +END +items.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/items.php +END +single.php +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/72/trunk/system/application/views/themes/sandbox/single.php +END +main.css +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/main.css +END +_header.php +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/75/trunk/system/application/views/themes/sandbox/_header.php +END +home.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/home.php +END +_sidebar.php +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/!svn/ver/18/trunk/system/application/views/themes/sandbox/_sidebar.php +END diff --git a/system/application/views/themes/sandbox/.svn/entries b/system/application/views/themes/sandbox/.svn/entries new file mode 100644 index 0000000..3610135 --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/entries @@ -0,0 +1,368 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/application/views/themes/sandbox +http://sweetcron.googlecode.com/svn + + + +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +rss_feed.php +file + + + + +2009-09-15T00:18:03.000000Z +c87610c0e43b2534ae90bf0767dd494f +2008-11-30T08:10:34.779286Z +122 +yongfook + + + + + + + + + + + + + + + + + + + + + +1291 + +contact.php +file + + + + +2009-09-15T00:18:03.000000Z +410ae32709495a179fb596a7f581f287 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +281 + +_footer.php +file + + + + +2009-09-15T00:18:03.000000Z +03282892850f97457bd691fb5797eb32 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +46 + +_activity_feed.php +file + + + + +2009-09-15T00:18:03.000000Z +66e39951a78569e125cce01bfeab96ec +2008-08-29T16:57:11.428026Z +52 +yongfook + + + + + + + + + + + + + + + + + + + + + +2810 + +items.php +file + + + + +2009-09-15T00:18:03.000000Z +c01153ae65a874f44daa573af69ba38a +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +161 + +single.php +file + + + + +2009-09-15T00:18:03.000000Z +a6c3abc6abf6671a12b73b836a0aaee3 +2008-09-02T01:13:26.091244Z +72 +yongfook + + + + + + + + + + + + + + + + + + + + + +1858 + +main.css +file + + + + +2009-09-15T00:18:03.000000Z +d7b6cae19a18a751ce69dc1d9ae2367e +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +2417 + +_header.php +file + + + + +2009-09-15T00:18:03.000000Z +8c926d54d3e0afc55cf7868ab211386c +2008-09-03T14:07:24.349314Z +75 +yongfook + + + + + + + + + + + + + + + + + + + + + +1812 + +home.php +file + + + + +2009-09-15T00:18:03.000000Z +c01153ae65a874f44daa573af69ba38a +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +161 + +_sidebar.php +file + + + + +2009-09-15T00:18:03.000000Z +fa59d2046fcd1ff94c2f8cb06463ff77 +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + + + + + + + + +823 + diff --git a/system/application/views/themes/sandbox/.svn/text-base/_activity_feed.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/_activity_feed.php.svn-base new file mode 100644 index 0000000..1eaebaf --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/_activity_feed.php.svn-base @@ -0,0 +1,52 @@ +

    + + + + + + + + + + + + + +
      + + + +
    • + get_feed_domain() == $this->config->item('base_url')): ?> +

      I posted a blog entry

      + +

      I posted to get_feed_domain()?>

      + +

      get_title()?>

      + + has_content()): ?> +
      get_content()?>
      + + has_image() && !$item->has_video()): ?> +

      + + has_video()): ?> +
      get_video()?>
      + + has_tags()): ?> +
        +
      • Tags:
      • + get_tags() as $tag): ?> +
      • name?>
      • + +
      + +

      get_human_date()?> | Comments »

      +
    • + + +
    + +

    + +
    \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/_footer.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/_footer.php.svn-base new file mode 100644 index 0000000..c809a05 --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/_footer.php.svn-base @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/_header.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/_header.php.svn-base new file mode 100644 index 0000000..8e7a4e6 --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/_header.php.svn-base @@ -0,0 +1,33 @@ + + + + + + + + + <?php echo $page_name?> › <?php echo $this->config->item('lifestream_title')?> + + + + + + + + + + + + + +
    diff --git a/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base new file mode 100644 index 0000000..85a3e61 --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/_sidebar.php.svn-base @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base new file mode 100644 index 0000000..884036f --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/contact.php.svn-base @@ -0,0 +1,8 @@ +
    +
    + + I recommend www.wufoo.com to create a contact form and paste it here! + +
    +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/home.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/home.php.svn-base new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/home.php.svn-base @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/items.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/items.php.svn-base new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/items.php.svn-base @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/main.css.svn-base b/system/application/views/themes/sandbox/.svn/text-base/main.css.svn-base new file mode 100644 index 0000000..2b82bef --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/main.css.svn-base @@ -0,0 +1,144 @@ +/* Sweetcron Sandbox CSS - 28/08/08 + + Table of Contents: + Reset + Typography + Positioning + IE Fixes + 3rd Party + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + +h2, p#pagination { + font-size: 15px; +} + +p.site_info, p.date, p.original_link { + font-size: 10px; +} + +p.original_link a { + color: #999; + text-decoration: none; +} + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Arial, Helvetica, sans serif; + font-size: 12px; + color: #333; + line-height: 1.7em; +} + +h1 { + font-size: 18px; +} + + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body { + background: white; +} + +div.center_box { + width: 800px; + margin: 0 auto; + position: relative; +} + +div#header { + padding: 20px 0; + border: 2px solid #EEE; + border-style: none none solid none; +} + +ul#navigation { + position: absolute; + right: 0; +} + +ul#navigation li { + display: inline; + margin-left: 10px; +} + +div#main_container { + padding: 20px 20px 0 0; + width: 508px; + float: left; +} + +div#sidebar_container { + display: inline; + width: 250px; + float: left; + background: #F8F8F8; + border: 1px solid #EEE; + margin: 20px 0 0 0; + padding: 10px; +} + +p.site_info { + padding-left: 20px; +} + +ul#activity_list li.item { + margin-bottom: 20px; +} + +li.item img, div#single_container img { + display: block; + border: 1px solid #CCC; + padding: 3px; + margin: 5px 0; +} + +ul.item_tag_list li { + display: inline; +} + +p#breadcrumb, p#pagination { + background: #FFFFCC; + margin-bottom: 20px; + padding: 3px; +} + +div#sidebar_container h3 { + border: 1px solid #CCC; + border-style: none none solid none; + margin: 10px 0 5px 0; +} + +ul.tag_list li { + display: inline; + margin: 0 5px 0 0; +} + +div#comments_container { + border: 1px solid #EEE; + border-style: solid none none none; + padding: 10px 0; + margin-top: 20px; +} + +/* IE Fixes (lulz) +---------------------------------------------------------------------------------------- */ + + + +/* 3rd Party +---------------------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/rss_feed.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/rss_feed.php.svn-base new file mode 100644 index 0000000..2ba3a05 --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/rss_feed.php.svn-base @@ -0,0 +1,27 @@ + + + <?php echo $this->config->item('lifestream_title')?> <?php echo $page_name?> + config->item('base_url')?>feed + + en-us + http://blogs.law.harvard.edu/tech/rss + Sweetcron + config->item('admin_email')?> + + + <?php echo htmlspecialchars(htmlspecialchars_decode($item->get_title()))?> + get_permalink()?>/get_name()?> + get_content()?> + has_image() && !$item->has_video()): ?> + + + has_video()): ?> + get_video()?> + +
    ]]> + get_date())?> + get_permalink()?>/get_name()?> + + + + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/.svn/text-base/single.php.svn-base b/system/application/views/themes/sandbox/.svn/text-base/single.php.svn-base new file mode 100644 index 0000000..8863a4f --- /dev/null +++ b/system/application/views/themes/sandbox/.svn/text-base/single.php.svn-base @@ -0,0 +1,41 @@ +
    + +
    +

    I posted to get_feed_domain()?>

    +

    get_title()?>

    +

    get_original_permalink()?>

    + has_content()): ?> +
    get_content()?>
    + + has_image() && !$item->has_video()): ?> + item_data[$item->get_feed_class()]['image']['m']) && !empty($item->item_data[$item->get_feed_class()]['image']['m'])): ?> +

    + +

    + + + has_video()): ?> +
    + get_video()); + $video = str_replace('height="159"', 'height="375"', $video); + $video = str_replace('height="178"', 'height="415"', $video); + echo $video?> +
    + + has_tags()): ?> +
      +
    • Tags:
    • + get_tags() as $tag): ?> +
    • name?>
    • + +
    + +
    + +
    + Your favourite external commenting service goes here! I recommend http://www.disqus.com +
    + +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/_activity_feed.php b/system/application/views/themes/sandbox/_activity_feed.php new file mode 100644 index 0000000..1eaebaf --- /dev/null +++ b/system/application/views/themes/sandbox/_activity_feed.php @@ -0,0 +1,52 @@ +
    + + + + + + + + + + + + + +
      + + + +
    • + get_feed_domain() == $this->config->item('base_url')): ?> +

      I posted a blog entry

      + +

      I posted to get_feed_domain()?>

      + +

      get_title()?>

      + + has_content()): ?> +
      get_content()?>
      + + has_image() && !$item->has_video()): ?> +

      + + has_video()): ?> +
      get_video()?>
      + + has_tags()): ?> +
        +
      • Tags:
      • + get_tags() as $tag): ?> +
      • name?>
      • + +
      + +

      get_human_date()?> | Comments »

      +
    • + + +
    + +

    + +
    \ No newline at end of file diff --git a/system/application/views/themes/sandbox/_footer.php b/system/application/views/themes/sandbox/_footer.php new file mode 100644 index 0000000..c809a05 --- /dev/null +++ b/system/application/views/themes/sandbox/_footer.php @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/_header.php b/system/application/views/themes/sandbox/_header.php new file mode 100644 index 0000000..8e7a4e6 --- /dev/null +++ b/system/application/views/themes/sandbox/_header.php @@ -0,0 +1,33 @@ + + + + + + + + + <?php echo $page_name?> › <?php echo $this->config->item('lifestream_title')?> + + + + + + + + + + + + + +
    diff --git a/system/application/views/themes/sandbox/_sidebar.php b/system/application/views/themes/sandbox/_sidebar.php new file mode 100644 index 0000000..85a3e61 --- /dev/null +++ b/system/application/views/themes/sandbox/_sidebar.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/contact.php b/system/application/views/themes/sandbox/contact.php new file mode 100644 index 0000000..884036f --- /dev/null +++ b/system/application/views/themes/sandbox/contact.php @@ -0,0 +1,8 @@ +
    +
    + + I recommend www.wufoo.com to create a contact form and paste it here! + +
    +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/home.php b/system/application/views/themes/sandbox/home.php new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/sandbox/home.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/items.php b/system/application/views/themes/sandbox/items.php new file mode 100644 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/sandbox/items.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/sandbox/main.css b/system/application/views/themes/sandbox/main.css new file mode 100644 index 0000000..2b82bef --- /dev/null +++ b/system/application/views/themes/sandbox/main.css @@ -0,0 +1,144 @@ +/* Sweetcron Sandbox CSS - 28/08/08 + + Table of Contents: + Reset + Typography + Positioning + IE Fixes + 3rd Party + +*/ + +/* Reset +---------------------------------------------------------------------------------------- */ + +* { + margin: 0; + padding: 0; +} + +/* now I'm working with a clean slate! */ + +h2, p#pagination { + font-size: 15px; +} + +p.site_info, p.date, p.original_link { + font-size: 10px; +} + +p.original_link a { + color: #999; + text-decoration: none; +} + +/* Typography +---------------------------------------------------------------------------------------- */ + +body { + font-family: "Lucida Grande", Arial, Helvetica, sans serif; + font-size: 12px; + color: #333; + line-height: 1.7em; +} + +h1 { + font-size: 18px; +} + + +/* Positioning +---------------------------------------------------------------------------------------- */ + +body { + background: white; +} + +div.center_box { + width: 800px; + margin: 0 auto; + position: relative; +} + +div#header { + padding: 20px 0; + border: 2px solid #EEE; + border-style: none none solid none; +} + +ul#navigation { + position: absolute; + right: 0; +} + +ul#navigation li { + display: inline; + margin-left: 10px; +} + +div#main_container { + padding: 20px 20px 0 0; + width: 508px; + float: left; +} + +div#sidebar_container { + display: inline; + width: 250px; + float: left; + background: #F8F8F8; + border: 1px solid #EEE; + margin: 20px 0 0 0; + padding: 10px; +} + +p.site_info { + padding-left: 20px; +} + +ul#activity_list li.item { + margin-bottom: 20px; +} + +li.item img, div#single_container img { + display: block; + border: 1px solid #CCC; + padding: 3px; + margin: 5px 0; +} + +ul.item_tag_list li { + display: inline; +} + +p#breadcrumb, p#pagination { + background: #FFFFCC; + margin-bottom: 20px; + padding: 3px; +} + +div#sidebar_container h3 { + border: 1px solid #CCC; + border-style: none none solid none; + margin: 10px 0 5px 0; +} + +ul.tag_list li { + display: inline; + margin: 0 5px 0 0; +} + +div#comments_container { + border: 1px solid #EEE; + border-style: solid none none none; + padding: 10px 0; + margin-top: 20px; +} + +/* IE Fixes (lulz) +---------------------------------------------------------------------------------------- */ + + + +/* 3rd Party +---------------------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/system/application/views/themes/sandbox/rss_feed.php b/system/application/views/themes/sandbox/rss_feed.php new file mode 100644 index 0000000..2ba3a05 --- /dev/null +++ b/system/application/views/themes/sandbox/rss_feed.php @@ -0,0 +1,27 @@ + + + <?php echo $this->config->item('lifestream_title')?> <?php echo $page_name?> + config->item('base_url')?>feed + + en-us + http://blogs.law.harvard.edu/tech/rss + Sweetcron + config->item('admin_email')?> + + + <?php echo htmlspecialchars(htmlspecialchars_decode($item->get_title()))?> + get_permalink()?>/get_name()?> + get_content()?> + has_image() && !$item->has_video()): ?> + + + has_video()): ?> + get_video()?> + +
    ]]> + get_date())?> + get_permalink()?>/get_name()?> + + + + \ No newline at end of file diff --git a/system/application/views/themes/sandbox/single.php b/system/application/views/themes/sandbox/single.php new file mode 100644 index 0000000..8863a4f --- /dev/null +++ b/system/application/views/themes/sandbox/single.php @@ -0,0 +1,41 @@ +
    + +
    +

    I posted to get_feed_domain()?>

    +

    get_title()?>

    +

    get_original_permalink()?>

    + has_content()): ?> +
    get_content()?>
    + + has_image() && !$item->has_video()): ?> + item_data[$item->get_feed_class()]['image']['m']) && !empty($item->item_data[$item->get_feed_class()]['image']['m'])): ?> +

    + +

    + + + has_video()): ?> +
    + get_video()); + $video = str_replace('height="159"', 'height="375"', $video); + $video = str_replace('height="178"', 'height="415"', $video); + echo $video?> +
    + + has_tags()): ?> +
      +
    • Tags:
    • + get_tags() as $tag): ?> +
    • name?>
    • + +
    + +
    + +
    + Your favourite external commenting service goes here! I recommend http://www.disqus.com +
    + +
    +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php new file mode 100755 index 0000000..8802ab7 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_activity_feed.php @@ -0,0 +1,138 @@ + + + +
    + +
    + + + +
    +

    get_title()?>

    + get_human_date()?> | Comments +

    get_content()), 50)?>

    +

    Read More

    +
    + + get_feed_domain(); ?> + + + + +
    + +
    +

    ">From the blog

    + +
    +
    + + + + + + +

    Home › + + Search Results: + + Tag: + + Site: + +

    + + + + +
      + + + + + + +
    • + +

      get_feed_domain(); ?>">get_feed_domain(); ?> get_date()); ?>

      + + + get_feed_domain() == str_replace("/","",str_replace("http://","",$this->config->item('base_url')))): ?> + +
      +

      get_title()?>

      +

      get_content()), 40)?>

      +
      + + + get_feed_domain() == 'twitter.com'): ?> + + + + + get_feed_domain() == 'google.com' OR $item->get_feed_domain() == 'digg.com' OR $item->get_feed_domain() == 'stumbleupon.com'): ?> + +
      +

      get_title()?>

      +

      get_content()), 40)?>

      +
      + + + has_video()): ?> + +
      + get_video()?> +

      get_content()), 5)?>

      +
      + + + has_image() && !$item->has_video()): ?> + + get_feed_domain() == 'flickr.com' ) : ?> +
      + +
      + +

      get_title()?>
      get_content()), 20)?>

      +
      + + + + +
      +

      get_title()?>

      +

      get_content()), 40)?>

      +
      + + + +
    • + + + +
    + +

    Pages:

    \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php new file mode 100755 index 0000000..3853344 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_footer.php @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php new file mode 100755 index 0000000..b61887d --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_header.php @@ -0,0 +1,121 @@ + + + + + + + + + <?php echo $page_name?> › <?php echo $this->config->item('lifestream_title')?> + + + + + + + + + + + + + + + +
    +
    +
    +

    config->item('lifestream_title')?>

    + + +

    Subscribe by RSS | Email

    + +
    +
    + +
    +
    +
    + + + <?php echo $this->config->item('lifestream_title')?> +
    + + +

    About config->item('lifestream_title')?>

    +

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus in enim sed sapien semper venenatis. Nam tincidunt interdum ligula. Phasellus pretium lacus ut neque. Donec facilisis, dolor ac mattis congue, est pede consectetuer elit, in sodales diam augue in leo. Donec lectus erat, ultricies vitae, pretium sit amet, eleifend quis, sapien. Vestibulum diam. Quisque ullamcorper, metus sit amet pellentesque viverra, eros dui feugiat nunc, eu pretium tellus eros vel odio.

    + +
    +
    +

    Contact Me

    + + + +

    Connect on LinkedIn

    +
    +
    + +
    +
    +

    Search

    +

    + +
    +
    +
    +
    + +
    + +
    \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/_sidebar.php b/system/application/views/themes/teh_blog_ar_(not)_dead/_sidebar.php new file mode 100755 index 0000000..52cdf83 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/_sidebar.php @@ -0,0 +1,28 @@ + + + \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/home.php b/system/application/views/themes/teh_blog_ar_(not)_dead/home.php new file mode 100755 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/home.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-blog-items.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-blog-items.png new file mode 100755 index 0000000..c5f054c Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-blog-items.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen-grey.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen-grey.png new file mode 100755 index 0000000..5c3503d Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen-grey.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen.png new file mode 100755 index 0000000..dd670c3 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-gen.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-item.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-item.png new file mode 100755 index 0000000..4cfb17a Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-item.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-photo.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-photo.png new file mode 100755 index 0000000..31012f6 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-photo.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-profile.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-profile.png new file mode 100755 index 0000000..af00c97 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-profile.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-single.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-single.png new file mode 100755 index 0000000..497df0d Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-single.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-twitter.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-twitter.png new file mode 100755 index 0000000..23b58e7 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-twitter.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-video.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-video.png new file mode 100755 index 0000000..ff67657 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/bg-video.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/feed-icon-14x14.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/feed-icon-14x14.png new file mode 100755 index 0000000..b3c949d Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/feed-icon-14x14.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-less.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-less.png new file mode 100755 index 0000000..e9be4a5 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-less.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-more.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-more.png new file mode 100755 index 0000000..acb292f Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/learn-more.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/profile-blank.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/profile-blank.png new file mode 100755 index 0000000..0342e87 Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/profile-blank.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/i/twitter-blank.png b/system/application/views/themes/teh_blog_ar_(not)_dead/i/twitter-blank.png new file mode 100755 index 0000000..876c00d Binary files /dev/null and b/system/application/views/themes/teh_blog_ar_(not)_dead/i/twitter-blank.png differ diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/items.php b/system/application/views/themes/teh_blog_ar_(not)_dead/items.php new file mode 100755 index 0000000..da80f3e --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/items.php @@ -0,0 +1,2 @@ +load->view('themes/'.$this->config->item('theme').'/_activity_feed')?> +load->view('themes/'.$this->config->item('theme').'/_sidebar')?> \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/js/jquery.js b/system/application/views/themes/teh_blog_ar_(not)_dead/js/jquery.js new file mode 100755 index 0000000..d646859 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/js/jquery.js @@ -0,0 +1,11 @@ +/* + * jQuery 1.2.1 - New Wave Javascript + * + * Copyright (c) 2007 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ + * $Rev: 3353 $ + */ +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){9(1m E!="W")H w=E;H E=18.15=G(a,b){I 6 7u E?6.5N(a,b):1u E(a,b)};9(1m $!="W")H D=$;18.$=E;H u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;E.1b=E.3A={5N:G(c,a){c=c||U;9(1m c=="1M"){H m=u.2S(c);9(m&&(m[1]||!a)){9(m[1])c=E.4D([m[1]],a);J{H b=U.3S(m[3]);9(b)9(b.22!=m[3])I E().1Y(c);J{6[0]=b;6.K=1;I 6}J c=[]}}J I 1u E(a).1Y(c)}J 9(E.1n(c))I 1u E(U)[E.1b.2d?"2d":"39"](c);I 6.6v(c.1c==1B&&c||(c.4c||c.K&&c!=18&&!c.1y&&c[0]!=W&&c[0].1y)&&E.2h(c)||[c])},4c:"1.2.1",7Y:G(){I 6.K},K:0,21:G(a){I a==W?E.2h(6):6[a]},2o:G(a){H b=E(a);b.4Y=6;I b},6v:G(a){6.K=0;1B.3A.1a.16(6,a);I 6},N:G(a,b){I E.N(6,a,b)},4I:G(a){H b=-1;6.N(G(i){9(6==a)b=i});I b},1x:G(f,d,e){H c=f;9(f.1c==3X)9(d==W)I 6.K&&E[e||"1x"](6[0],f)||W;J{c={};c[f]=d}I 6.N(G(a){L(H b 1i c)E.1x(e?6.R:6,b,E.1e(6,c[b],e,a,b))})},17:G(b,a){I 6.1x(b,a,"3C")},2g:G(e){9(1m e!="5i"&&e!=S)I 6.4n().3g(U.6F(e));H t="";E.N(e||6,G(){E.N(6.3j,G(){9(6.1y!=8)t+=6.1y!=1?6.6x:E.1b.2g([6])})});I t},5m:G(b){9(6[0])E(b,6[0].3H).6u().3d(6[0]).1X(G(){H a=6;1W(a.1w)a=a.1w;I a}).3g(6);I 6},8m:G(a){I 6.N(G(){E(6).6q().5m(a)})},8d:G(a){I 6.N(G(){E(6).5m(a)})},3g:G(){I 6.3z(1q,Q,1,G(a){6.58(a)})},6j:G(){I 6.3z(1q,Q,-1,G(a){6.3d(a,6.1w)})},6g:G(){I 6.3z(1q,P,1,G(a){6.12.3d(a,6)})},50:G(){I 6.3z(1q,P,-1,G(a){6.12.3d(a,6.2q)})},2D:G(){I 6.4Y||E([])},1Y:G(t){H b=E.1X(6,G(a){I E.1Y(t,a)});I 6.2o(/[^+>] [^+>]/.14(t)||t.1g("..")>-1?E.4V(b):b)},6u:G(e){H f=6.1X(G(){I 6.67?E(6.67)[0]:6.4R(Q)});H d=f.1Y("*").4O().N(G(){9(6[F]!=W)6[F]=S});9(e===Q)6.1Y("*").4O().N(G(i){H c=E.M(6,"2P");L(H a 1i c)L(H b 1i c[a])E.1j.1f(d[i],a,c[a][b],c[a][b].M)});I f},1E:G(t){I 6.2o(E.1n(t)&&E.2W(6,G(b,a){I t.16(b,[a])})||E.3m(t,6))},5V:G(t){I 6.2o(t.1c==3X&&E.3m(t,6,Q)||E.2W(6,G(a){I(t.1c==1B||t.4c)?E.2A(a,t)<0:a!=t}))},1f:G(t){I 6.2o(E.1R(6.21(),t.1c==3X?E(t).21():t.K!=W&&(!t.11||E.11(t,"2Y"))?t:[t]))},3t:G(a){I a?E.3m(a,6).K>0:P},7c:G(a){I 6.3t("."+a)},3i:G(b){9(b==W){9(6.K){H c=6[0];9(E.11(c,"24")){H e=c.4Z,a=[],Y=c.Y,2G=c.O=="24-2G";9(e<0)I S;L(H i=2G?e:0,33=2G?e+1:Y.K;i<33;i++){H d=Y[i];9(d.26){H b=E.V.1h&&!d.9V["1Q"].9L?d.2g:d.1Q;9(2G)I b;a.1a(b)}}I a}J I 6[0].1Q.1p(/\\r/g,"")}}J I 6.N(G(){9(b.1c==1B&&/4k|5j/.14(6.O))6.2Q=(E.2A(6.1Q,b)>=0||E.2A(6.2H,b)>=0);J 9(E.11(6,"24")){H a=b.1c==1B?b:[b];E("9h",6).N(G(){6.26=(E.2A(6.1Q,a)>=0||E.2A(6.2g,a)>=0)});9(!a.K)6.4Z=-1}J 6.1Q=b})},4o:G(a){I a==W?(6.K?6[0].3O:S):6.4n().3g(a)},6H:G(a){I 6.50(a).28()},6E:G(i){I 6.2J(i,i+1)},2J:G(){I 6.2o(1B.3A.2J.16(6,1q))},1X:G(b){I 6.2o(E.1X(6,G(a,i){I b.2O(a,i,a)}))},4O:G(){I 6.1f(6.4Y)},3z:G(f,d,g,e){H c=6.K>1,a;I 6.N(G(){9(!a){a=E.4D(f,6.3H);9(g<0)a.8U()}H b=6;9(d&&E.11(6,"1I")&&E.11(a[0],"4m"))b=6.4l("1K")[0]||6.58(U.5B("1K"));E.N(a,G(){H a=c?6.4R(Q):6;9(!5A(0,a))e.2O(b,a)})})}};G 5A(i,b){H a=E.11(b,"1J");9(a){9(b.3k)E.3G({1d:b.3k,3e:P,1V:"1J"});J E.5f(b.2g||b.6s||b.3O||"");9(b.12)b.12.3b(b)}J 9(b.1y==1)E("1J",b).N(5A);I a}E.1k=E.1b.1k=G(){H c=1q[0]||{},a=1,2c=1q.K,5e=P;9(c.1c==8o){5e=c;c=1q[1]||{}}9(2c==1){c=6;a=0}H b;L(;a<2c;a++)9((b=1q[a])!=S)L(H i 1i b){9(c==b[i])6r;9(5e&&1m b[i]==\'5i\'&&c[i])E.1k(c[i],b[i]);J 9(b[i]!=W)c[i]=b[i]}I c};H F="15"+(1u 3D()).3B(),6p=0,5c={};E.1k({8a:G(a){18.$=D;9(a)18.15=w;I E},1n:G(a){I!!a&&1m a!="1M"&&!a.11&&a.1c!=1B&&/G/i.14(a+"")},4a:G(a){I a.2V&&!a.1G||a.37&&a.3H&&!a.3H.1G},5f:G(a){a=E.36(a);9(a){9(18.6l)18.6l(a);J 9(E.V.1N)18.56(a,0);J 3w.2O(18,a)}},11:G(b,a){I b.11&&b.11.27()==a.27()},1L:{},M:G(c,d,b){c=c==18?5c:c;H a=c[F];9(!a)a=c[F]=++6p;9(d&&!E.1L[a])E.1L[a]={};9(b!=W)E.1L[a][d]=b;I d?E.1L[a][d]:a},30:G(c,b){c=c==18?5c:c;H a=c[F];9(b){9(E.1L[a]){2E E.1L[a][b];b="";L(b 1i E.1L[a])1T;9(!b)E.30(c)}}J{2a{2E c[F]}29(e){9(c.53)c.53(F)}2E E.1L[a]}},N:G(a,b,c){9(c){9(a.K==W)L(H i 1i a)b.16(a[i],c);J L(H i=0,48=a.K;i<48;i++)9(b.16(a[i],c)===P)1T}J{9(a.K==W)L(H i 1i a)b.2O(a[i],i,a[i]);J L(H i=0,48=a.K,3i=a[0];i<48&&b.2O(3i,i,3i)!==P;3i=a[++i]){}}I a},1e:G(c,b,d,e,a){9(E.1n(b))b=b.2O(c,[e]);H f=/z-?4I|7T-?7Q|1r|69|7P-?1H/i;I b&&b.1c==4W&&d=="3C"&&!f.14(a)?b+"2T":b},1o:{1f:G(b,c){E.N((c||"").2l(/\\s+/),G(i,a){9(!E.1o.3K(b.1o,a))b.1o+=(b.1o?" ":"")+a})},28:G(b,c){b.1o=c!=W?E.2W(b.1o.2l(/\\s+/),G(a){I!E.1o.3K(c,a)}).66(" "):""},3K:G(t,c){I E.2A(c,(t.1o||t).3s().2l(/\\s+/))>-1}},2k:G(e,o,f){L(H i 1i o){e.R["3r"+i]=e.R[i];e.R[i]=o[i]}f.16(e,[]);L(H i 1i o)e.R[i]=e.R["3r"+i]},17:G(e,p){9(p=="1H"||p=="2N"){H b={},42,41,d=["7J","7I","7G","7F"];E.N(d,G(){b["7C"+6]=0;b["7B"+6+"5Z"]=0});E.2k(e,b,G(){9(E(e).3t(\':3R\')){42=e.7A;41=e.7w}J{e=E(e.4R(Q)).1Y(":4k").5W("2Q").2D().17({4C:"1P",2X:"4F",19:"2Z",7o:"0",1S:"0"}).5R(e.12)[0];H a=E.17(e.12,"2X")||"3V";9(a=="3V")e.12.R.2X="7g";42=e.7e;41=e.7b;9(a=="3V")e.12.R.2X="3V";e.12.3b(e)}});I p=="1H"?42:41}I E.3C(e,p)},3C:G(h,j,i){H g,2w=[],2k=[];G 3n(a){9(!E.V.1N)I P;H b=U.3o.3Z(a,S);I!b||b.4y("3n")==""}9(j=="1r"&&E.V.1h){g=E.1x(h.R,"1r");I g==""?"1":g}9(j.1t(/4u/i))j=y;9(!i&&h.R[j])g=h.R[j];J 9(U.3o&&U.3o.3Z){9(j.1t(/4u/i))j="4u";j=j.1p(/([A-Z])/g,"-$1").2p();H d=U.3o.3Z(h,S);9(d&&!3n(h))g=d.4y(j);J{L(H a=h;a&&3n(a);a=a.12)2w.4w(a);L(a=0;a<2w.K;a++)9(3n(2w[a])){2k[a]=2w[a].R.19;2w[a].R.19="2Z"}g=j=="19"&&2k[2w.K-1]!=S?"2s":U.3o.3Z(h,S).4y(j)||"";L(a=0;a<2k.K;a++)9(2k[a]!=S)2w[a].R.19=2k[a]}9(j=="1r"&&g=="")g="1"}J 9(h.3Q){H f=j.1p(/\\-(\\w)/g,G(m,c){I c.27()});g=h.3Q[j]||h.3Q[f];9(!/^\\d+(2T)?$/i.14(g)&&/^\\d/.14(g)){H k=h.R.1S;H e=h.4v.1S;h.4v.1S=h.3Q.1S;h.R.1S=g||0;g=h.R.71+"2T";h.R.1S=k;h.4v.1S=e}}I g},4D:G(a,e){H r=[];e=e||U;E.N(a,G(i,d){9(!d)I;9(d.1c==4W)d=d.3s();9(1m d=="1M"){d=d.1p(/(<(\\w+)[^>]*?)\\/>/g,G(m,a,b){I b.1t(/^(70|6Z|6Y|9Q|4t|9N|9K|3a|9G|9E)$/i)?m:a+">"});H s=E.36(d).2p(),1s=e.5B("1s"),2x=[];H c=!s.1g("<9y")&&[1,"<24>",""]||!s.1g("<9w")&&[1,"<6T>",""]||s.1t(/^<(9u|1K|9t|9r|9p)/)&&[1,"<1I>",""]||!s.1g("<4m")&&[2,"<1I><1K>",""]||(!s.1g("<9m")||!s.1g("<9k"))&&[3,"<1I><1K><4m>",""]||!s.1g("<6Y")&&[2,"<1I><1K><6L>",""]||E.V.1h&&[1,"1s<1s>",""]||[0,"",""];1s.3O=c[1]+d+c[2];1W(c[0]--)1s=1s.5p;9(E.V.1h){9(!s.1g("<1I")&&s.1g("<1K")<0)2x=1s.1w&&1s.1w.3j;J 9(c[1]=="<1I>"&&s.1g("<1K")<0)2x=1s.3j;L(H n=2x.K-1;n>=0;--n)9(E.11(2x[n],"1K")&&!2x[n].3j.K)2x[n].12.3b(2x[n]);9(/^\\s/.14(d))1s.3d(e.6F(d.1t(/^\\s*/)[0]),1s.1w)}d=E.2h(1s.3j)}9(0===d.K&&(!E.11(d,"2Y")&&!E.11(d,"24")))I;9(d[0]==W||E.11(d,"2Y")||d.Y)r.1a(d);J r=E.1R(r,d)});I r},1x:G(c,d,a){H e=E.4a(c)?{}:E.5o;9(d=="26"&&E.V.1N)c.12.4Z;9(e[d]){9(a!=W)c[e[d]]=a;I c[e[d]]}J 9(E.V.1h&&d=="R")I E.1x(c.R,"9e",a);J 9(a==W&&E.V.1h&&E.11(c,"2Y")&&(d=="9d"||d=="9a"))I c.97(d).6x;J 9(c.37){9(a!=W){9(d=="O"&&E.11(c,"4t")&&c.12)6G"O 94 93\'t 92 91";c.90(d,a)}9(E.V.1h&&/6C|3k/.14(d)&&!E.4a(c))I c.4p(d,2);I c.4p(d)}J{9(d=="1r"&&E.V.1h){9(a!=W){c.69=1;c.1E=(c.1E||"").1p(/6O\\([^)]*\\)/,"")+(3I(a).3s()=="8S"?"":"6O(1r="+a*6A+")")}I c.1E?(3I(c.1E.1t(/1r=([^)]*)/)[1])/6A).3s():""}d=d.1p(/-([a-z])/8Q,G(z,b){I b.27()});9(a!=W)c[d]=a;I c[d]}},36:G(t){I(t||"").1p(/^\\s+|\\s+$/g,"")},2h:G(a){H r=[];9(1m a!="8P")L(H i=0,2c=a.K;i<2c;i++)r.1a(a[i]);J r=a.2J(0);I r},2A:G(b,a){L(H i=0,2c=a.K;i<2c;i++)9(a[i]==b)I i;I-1},1R:G(a,b){9(E.V.1h){L(H i=0;b[i];i++)9(b[i].1y!=8)a.1a(b[i])}J L(H i=0;b[i];i++)a.1a(b[i]);I a},4V:G(b){H r=[],2f={};2a{L(H i=0,6y=b.K;i<6y;i++){H a=E.M(b[i]);9(!2f[a]){2f[a]=Q;r.1a(b[i])}}}29(e){r=b}I r},2W:G(b,a,c){9(1m a=="1M")a=3w("P||G(a,i){I "+a+"}");H d=[];L(H i=0,4g=b.K;i<4g;i++)9(!c&&a(b[i],i)||c&&!a(b[i],i))d.1a(b[i]);I d},1X:G(c,b){9(1m b=="1M")b=3w("P||G(a){I "+b+"}");H d=[];L(H i=0,4g=c.K;i<4g;i++){H a=b(c[i],i);9(a!==S&&a!=W){9(a.1c!=1B)a=[a];d=d.8M(a)}}I d}});H v=8K.8I.2p();E.V={4s:(v.1t(/.+(?:8F|8E|8C|8B)[\\/: ]([\\d.]+)/)||[])[1],1N:/6w/.14(v),34:/34/.14(v),1h:/1h/.14(v)&&!/34/.14(v),35:/35/.14(v)&&!/(8z|6w)/.14(v)};H y=E.V.1h?"4h":"5h";E.1k({5g:!E.V.1h||U.8y=="8x",4h:E.V.1h?"4h":"5h",5o:{"L":"8w","8v":"1o","4u":y,5h:y,4h:y,3O:"3O",1o:"1o",1Q:"1Q",3c:"3c",2Q:"2Q",8u:"8t",26:"26",8s:"8r"}});E.N({1D:"a.12",8q:"15.4e(a,\'12\')",8p:"15.2I(a,2,\'2q\')",8n:"15.2I(a,2,\'4d\')",8l:"15.4e(a,\'2q\')",8k:"15.4e(a,\'4d\')",8j:"15.5d(a.12.1w,a)",8i:"15.5d(a.1w)",6q:"15.11(a,\'8h\')?a.8f||a.8e.U:15.2h(a.3j)"},G(i,n){E.1b[i]=G(a){H b=E.1X(6,n);9(a&&1m a=="1M")b=E.3m(a,b);I 6.2o(E.4V(b))}});E.N({5R:"3g",8c:"6j",3d:"6g",8b:"50",89:"6H"},G(i,n){E.1b[i]=G(){H a=1q;I 6.N(G(){L(H j=0,2c=a.K;j<2c;j++)E(a[j])[n](6)})}});E.N({5W:G(a){E.1x(6,a,"");6.53(a)},88:G(c){E.1o.1f(6,c)},87:G(c){E.1o.28(6,c)},86:G(c){E.1o[E.1o.3K(6,c)?"28":"1f"](6,c)},28:G(a){9(!a||E.1E(a,[6]).r.K){E.30(6);6.12.3b(6)}},4n:G(){E("*",6).N(G(){E.30(6)});1W(6.1w)6.3b(6.1w)}},G(i,n){E.1b[i]=G(){I 6.N(n,1q)}});E.N(["85","5Z"],G(i,a){H n=a.2p();E.1b[n]=G(h){I 6[0]==18?E.V.1N&&3y["84"+a]||E.5g&&38.33(U.2V["5a"+a],U.1G["5a"+a])||U.1G["5a"+a]:6[0]==U?38.33(U.1G["6n"+a],U.1G["6m"+a]):h==W?(6.K?E.17(6[0],n):S):6.17(n,h.1c==3X?h:h+"2T")}});H C=E.V.1N&&3x(E.V.4s)<83?"(?:[\\\\w*57-]|\\\\\\\\.)":"(?:[\\\\w\\82-\\81*57-]|\\\\\\\\.)",6k=1u 47("^>\\\\s*("+C+"+)"),6i=1u 47("^("+C+"+)(#)("+C+"+)"),6h=1u 47("^([#.]?)("+C+"*)");E.1k({55:{"":"m[2]==\'*\'||15.11(a,m[2])","#":"a.4p(\'22\')==m[2]",":":{80:"im[3]-0",2I:"m[3]-0==i",6E:"m[3]-0==i",3v:"i==0",3u:"i==r.K-1",6f:"i%2==0",6e:"i%2","3v-46":"a.12.4l(\'*\')[0]==a","3u-46":"15.2I(a.12.5p,1,\'4d\')==a","7X-46":"!15.2I(a.12.5p,2,\'4d\')",1D:"a.1w",4n:"!a.1w",7W:"(a.6s||a.7V||15(a).2g()||\'\').1g(m[3])>=0",3R:\'"1P"!=a.O&&15.17(a,"19")!="2s"&&15.17(a,"4C")!="1P"\',1P:\'"1P"==a.O||15.17(a,"19")=="2s"||15.17(a,"4C")=="1P"\',7U:"!a.3c",3c:"a.3c",2Q:"a.2Q",26:"a.26||15.1x(a,\'26\')",2g:"\'2g\'==a.O",4k:"\'4k\'==a.O",5j:"\'5j\'==a.O",54:"\'54\'==a.O",52:"\'52\'==a.O",51:"\'51\'==a.O",6d:"\'6d\'==a.O",6c:"\'6c\'==a.O",2r:\'"2r"==a.O||15.11(a,"2r")\',4t:"/4t|24|6b|2r/i.14(a.11)",3K:"15.1Y(m[3],a).K",7S:"/h\\\\d/i.14(a.11)",7R:"15.2W(15.32,G(1b){I a==1b.T;}).K"}},6a:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1u 47("^([:.#]*)("+C+"+)")],3m:G(a,c,b){H d,2b=[];1W(a&&a!=d){d=a;H f=E.1E(a,c,b);a=f.t.1p(/^\\s*,\\s*/,"");2b=b?c=f.r:E.1R(2b,f.r)}I 2b},1Y:G(t,o){9(1m t!="1M")I[t];9(o&&!o.1y)o=S;o=o||U;H d=[o],2f=[],3u;1W(t&&3u!=t){H r=[];3u=t;t=E.36(t);H l=P;H g=6k;H m=g.2S(t);9(m){H p=m[1].27();L(H i=0;d[i];i++)L(H c=d[i].1w;c;c=c.2q)9(c.1y==1&&(p=="*"||c.11.27()==p.27()))r.1a(c);d=r;t=t.1p(g,"");9(t.1g(" ")==0)6r;l=Q}J{g=/^([>+~])\\s*(\\w*)/i;9((m=g.2S(t))!=S){r=[];H p=m[2],1R={};m=m[1];L(H j=0,31=d.K;j<31;j++){H n=m=="~"||m=="+"?d[j].2q:d[j].1w;L(;n;n=n.2q)9(n.1y==1){H h=E.M(n);9(m=="~"&&1R[h])1T;9(!p||n.11.27()==p.27()){9(m=="~")1R[h]=Q;r.1a(n)}9(m=="+")1T}}d=r;t=E.36(t.1p(g,""));l=Q}}9(t&&!l){9(!t.1g(",")){9(o==d[0])d.44();2f=E.1R(2f,d);r=d=[o];t=" "+t.68(1,t.K)}J{H k=6i;H m=k.2S(t);9(m){m=[0,m[2],m[3],m[1]]}J{k=6h;m=k.2S(t)}m[2]=m[2].1p(/\\\\/g,"");H f=d[d.K-1];9(m[1]=="#"&&f&&f.3S&&!E.4a(f)){H q=f.3S(m[2]);9((E.V.1h||E.V.34)&&q&&1m q.22=="1M"&&q.22!=m[2])q=E(\'[@22="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.11(q,m[3]))?[q]:[]}J{L(H i=0;d[i];i++){H a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];9(a=="*"&&d[i].11.2p()=="5i")a="3a";r=E.1R(r,d[i].4l(a))}9(m[1]==".")r=E.4X(r,m[2]);9(m[1]=="#"){H e=[];L(H i=0;r[i];i++)9(r[i].4p("22")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1p(k,"")}}9(t){H b=E.1E(t,r);d=r=b.r;t=E.36(b.t)}}9(t)d=[];9(d&&o==d[0])d.44();2f=E.1R(2f,d);I 2f},4X:G(r,m,a){m=" "+m+" ";H c=[];L(H i=0;r[i];i++){H b=(" "+r[i].1o+" ").1g(m)>=0;9(!a&&b||a&&!b)c.1a(r[i])}I c},1E:G(t,r,h){H d;1W(t&&t!=d){d=t;H p=E.6a,m;L(H i=0;p[i];i++){m=p[i].2S(t);9(m){t=t.7O(m[0].K);m[2]=m[2].1p(/\\\\/g,"");1T}}9(!m)1T;9(m[1]==":"&&m[2]=="5V")r=E.1E(m[3],r,Q).r;J 9(m[1]==".")r=E.4X(r,m[2],h);J 9(m[1]=="["){H g=[],O=m[3];L(H i=0,31=r.K;i<31;i++){H a=r[i],z=a[E.5o[m[2]]||m[2]];9(z==S||/6C|3k|26/.14(m[2]))z=E.1x(a,m[2])||\'\';9((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1g(m[5])||O=="$="&&z.68(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1g(m[5])>=0)^h)g.1a(a)}r=g}J 9(m[1]==":"&&m[2]=="2I-46"){H e={},g=[],14=/(\\d*)n\\+?(\\d*)/.2S(m[3]=="6f"&&"2n"||m[3]=="6e"&&"2n+1"||!/\\D/.14(m[3])&&"n+"+m[3]||m[3]),3v=(14[1]||1)-0,d=14[2]-0;L(H i=0,31=r.K;i<31;i++){H j=r[i],12=j.12,22=E.M(12);9(!e[22]){H c=1;L(H n=12.1w;n;n=n.2q)9(n.1y==1)n.4U=c++;e[22]=Q}H b=P;9(3v==1){9(d==0||j.4U==d)b=Q}J 9((j.4U+d)%3v==0)b=Q;9(b^h)g.1a(j)}r=g}J{H f=E.55[m[1]];9(1m f!="1M")f=E.55[m[1]][m[2]];f=3w("P||G(a,i){I "+f+"}");r=E.2W(r,f,h)}}I{r:r,t:t}},4e:G(b,c){H d=[];H a=b[c];1W(a&&a!=U){9(a.1y==1)d.1a(a);a=a[c]}I d},2I:G(a,e,c,b){e=e||1;H d=0;L(;a;a=a[c])9(a.1y==1&&++d==e)1T;I a},5d:G(n,a){H r=[];L(;n;n=n.2q){9(n.1y==1&&(!a||n!=a))r.1a(n)}I r}});E.1j={1f:G(g,e,c,h){9(E.V.1h&&g.4j!=W)g=18;9(!c.2u)c.2u=6.2u++;9(h!=W){H d=c;c=G(){I d.16(6,1q)};c.M=h;c.2u=d.2u}H i=e.2l(".");e=i[0];c.O=i[1];H b=E.M(g,"2P")||E.M(g,"2P",{});H f=E.M(g,"2t",G(){H a;9(1m E=="W"||E.1j.4T)I a;a=E.1j.2t.16(g,1q);I a});H j=b[e];9(!j){j=b[e]={};9(g.4S)g.4S(e,f,P);J g.7N("43"+e,f)}j[c.2u]=c;6.1Z[e]=Q},2u:1,1Z:{},28:G(d,c,b){H e=E.M(d,"2P"),2L,4I;9(1m c=="1M"){H a=c.2l(".");c=a[0]}9(e){9(c&&c.O){b=c.4Q;c=c.O}9(!c){L(c 1i e)6.28(d,c)}J 9(e[c]){9(b)2E e[c][b.2u];J L(b 1i e[c])9(!a[1]||e[c][b].O==a[1])2E e[c][b];L(2L 1i e[c])1T;9(!2L){9(d.4P)d.4P(c,E.M(d,"2t"),P);J d.7M("43"+c,E.M(d,"2t"));2L=S;2E e[c]}}L(2L 1i e)1T;9(!2L){E.30(d,"2P");E.30(d,"2t")}}},1F:G(d,b,e,c,f){b=E.2h(b||[]);9(!e){9(6.1Z[d])E("*").1f([18,U]).1F(d,b)}J{H a,2L,1b=E.1n(e[d]||S),4N=!b[0]||!b[0].2M;9(4N)b.4w(6.4M({O:d,2m:e}));b[0].O=d;9(E.1n(E.M(e,"2t")))a=E.M(e,"2t").16(e,b);9(!1b&&e["43"+d]&&e["43"+d].16(e,b)===P)a=P;9(4N)b.44();9(f&&f.16(e,b)===P)a=P;9(1b&&c!==P&&a!==P&&!(E.11(e,\'a\')&&d=="4L")){6.4T=Q;e[d]()}6.4T=P}I a},2t:G(d){H a;d=E.1j.4M(d||18.1j||{});H b=d.O.2l(".");d.O=b[0];H c=E.M(6,"2P")&&E.M(6,"2P")[d.O],3q=1B.3A.2J.2O(1q,1);3q.4w(d);L(H j 1i c){3q[0].4Q=c[j];3q[0].M=c[j].M;9(!b[1]||c[j].O==b[1]){H e=c[j].16(6,3q);9(a!==P)a=e;9(e===P){d.2M();d.3p()}}}9(E.V.1h)d.2m=d.2M=d.3p=d.4Q=d.M=S;I a},4M:G(c){H a=c;c=E.1k({},a);c.2M=G(){9(a.2M)a.2M();a.7L=P};c.3p=G(){9(a.3p)a.3p();a.7K=Q};9(!c.2m&&c.65)c.2m=c.65;9(E.V.1N&&c.2m.1y==3)c.2m=a.2m.12;9(!c.4K&&c.4J)c.4K=c.4J==c.2m?c.7H:c.4J;9(c.64==S&&c.63!=S){H e=U.2V,b=U.1G;c.64=c.63+(e&&e.2R||b.2R||0);c.7E=c.7D+(e&&e.2B||b.2B||0)}9(!c.3Y&&(c.61||c.60))c.3Y=c.61||c.60;9(!c.5F&&c.5D)c.5F=c.5D;9(!c.3Y&&c.2r)c.3Y=(c.2r&1?1:(c.2r&2?3:(c.2r&4?2:0)));I c}};E.1b.1k({3W:G(c,a,b){I c=="5Y"?6.2G(c,a,b):6.N(G(){E.1j.1f(6,c,b||a,b&&a)})},2G:G(d,b,c){I 6.N(G(){E.1j.1f(6,d,G(a){E(6).5X(a);I(c||b).16(6,1q)},c&&b)})},5X:G(a,b){I 6.N(G(){E.1j.28(6,a,b)})},1F:G(c,a,b){I 6.N(G(){E.1j.1F(c,a,6,Q,b)})},7x:G(c,a,b){9(6[0])I E.1j.1F(c,a,6[0],P,b)},25:G(){H a=1q;I 6.4L(G(e){6.4H=0==6.4H?1:0;e.2M();I a[6.4H].16(6,[e])||P})},7v:G(f,g){G 4G(e){H p=e.4K;1W(p&&p!=6)2a{p=p.12}29(e){p=6};9(p==6)I P;I(e.O=="4x"?f:g).16(6,[e])}I 6.4x(4G).5U(4G)},2d:G(f){5T();9(E.3T)f.16(U,[E]);J E.3l.1a(G(){I f.16(6,[E])});I 6}});E.1k({3T:P,3l:[],2d:G(){9(!E.3T){E.3T=Q;9(E.3l){E.N(E.3l,G(){6.16(U)});E.3l=S}9(E.V.35||E.V.34)U.4P("5S",E.2d,P);9(!18.7t.K)E(18).39(G(){E("#4E").28()})}}});E.N(("7s,7r,39,7q,6n,5Y,4L,7p,"+"7n,7m,7l,4x,5U,7k,24,"+"51,7j,7i,7h,3U").2l(","),G(i,o){E.1b[o]=G(f){I f?6.3W(o,f):6.1F(o)}});H x=P;G 5T(){9(x)I;x=Q;9(E.V.35||E.V.34)U.4S("5S",E.2d,P);J 9(E.V.1h){U.7f("<7d"+"7y 22=4E 7z=Q "+"3k=//:><\\/1J>");H a=U.3S("4E");9(a)a.62=G(){9(6.2C!="1l")I;E.2d()};a=S}J 9(E.V.1N)E.4B=4j(G(){9(U.2C=="5Q"||U.2C=="1l"){4A(E.4B);E.4B=S;E.2d()}},10);E.1j.1f(18,"39",E.2d)}E.1b.1k({39:G(g,d,c){9(E.1n(g))I 6.3W("39",g);H e=g.1g(" ");9(e>=0){H i=g.2J(e,g.K);g=g.2J(0,e)}c=c||G(){};H f="4z";9(d)9(E.1n(d)){c=d;d=S}J{d=E.3a(d);f="5P"}H h=6;E.3G({1d:g,O:f,M:d,1l:G(a,b){9(b=="1C"||b=="5O")h.4o(i?E("<1s/>").3g(a.40.1p(/<1J(.|\\s)*?\\/1J>/g,"")).1Y(i):a.40);56(G(){h.N(c,[a.40,b,a])},13)}});I 6},7a:G(){I E.3a(6.5M())},5M:G(){I 6.1X(G(){I E.11(6,"2Y")?E.2h(6.79):6}).1E(G(){I 6.2H&&!6.3c&&(6.2Q||/24|6b/i.14(6.11)||/2g|1P|52/i.14(6.O))}).1X(G(i,c){H b=E(6).3i();I b==S?S:b.1c==1B?E.1X(b,G(a,i){I{2H:c.2H,1Q:a}}):{2H:c.2H,1Q:b}}).21()}});E.N("5L,5K,6t,5J,5I,5H".2l(","),G(i,o){E.1b[o]=G(f){I 6.3W(o,f)}});H B=(1u 3D).3B();E.1k({21:G(d,b,a,c){9(E.1n(b)){a=b;b=S}I E.3G({O:"4z",1d:d,M:b,1C:a,1V:c})},78:G(b,a){I E.21(b,S,a,"1J")},77:G(c,b,a){I E.21(c,b,a,"45")},76:G(d,b,a,c){9(E.1n(b)){a=b;b={}}I E.3G({O:"5P",1d:d,M:b,1C:a,1V:c})},75:G(a){E.1k(E.59,a)},59:{1Z:Q,O:"4z",2z:0,5G:"74/x-73-2Y-72",6o:Q,3e:Q,M:S},49:{},3G:G(s){H f,2y=/=(\\?|%3F)/g,1v,M;s=E.1k(Q,s,E.1k(Q,{},E.59,s));9(s.M&&s.6o&&1m s.M!="1M")s.M=E.3a(s.M);9(s.1V=="4b"){9(s.O.2p()=="21"){9(!s.1d.1t(2y))s.1d+=(s.1d.1t(/\\?/)?"&":"?")+(s.4b||"5E")+"=?"}J 9(!s.M||!s.M.1t(2y))s.M=(s.M?s.M+"&":"")+(s.4b||"5E")+"=?";s.1V="45"}9(s.1V=="45"&&(s.M&&s.M.1t(2y)||s.1d.1t(2y))){f="4b"+B++;9(s.M)s.M=s.M.1p(2y,"="+f);s.1d=s.1d.1p(2y,"="+f);s.1V="1J";18[f]=G(a){M=a;1C();1l();18[f]=W;2a{2E 18[f]}29(e){}}}9(s.1V=="1J"&&s.1L==S)s.1L=P;9(s.1L===P&&s.O.2p()=="21")s.1d+=(s.1d.1t(/\\?/)?"&":"?")+"57="+(1u 3D()).3B();9(s.M&&s.O.2p()=="21"){s.1d+=(s.1d.1t(/\\?/)?"&":"?")+s.M;s.M=S}9(s.1Z&&!E.5b++)E.1j.1F("5L");9(!s.1d.1g("8g")&&s.1V=="1J"){H h=U.4l("9U")[0];H g=U.5B("1J");g.3k=s.1d;9(!f&&(s.1C||s.1l)){H j=P;g.9R=g.62=G(){9(!j&&(!6.2C||6.2C=="5Q"||6.2C=="1l")){j=Q;1C();1l();h.3b(g)}}}h.58(g);I}H k=P;H i=18.6X?1u 6X("9P.9O"):1u 6W();i.9M(s.O,s.1d,s.3e);9(s.M)i.5C("9J-9I",s.5G);9(s.5y)i.5C("9H-5x-9F",E.49[s.1d]||"9D, 9C 9B 9A 5v:5v:5v 9z");i.5C("X-9x-9v","6W");9(s.6U)s.6U(i);9(s.1Z)E.1j.1F("5H",[i,s]);H c=G(a){9(!k&&i&&(i.2C==4||a=="2z")){k=Q;9(d){4A(d);d=S}1v=a=="2z"&&"2z"||!E.6S(i)&&"3U"||s.5y&&E.6R(i,s.1d)&&"5O"||"1C";9(1v=="1C"){2a{M=E.6Q(i,s.1V)}29(e){1v="5k"}}9(1v=="1C"){H b;2a{b=i.5s("6P-5x")}29(e){}9(s.5y&&b)E.49[s.1d]=b;9(!f)1C()}J E.5r(s,i,1v);1l();9(s.3e)i=S}};9(s.3e){H d=4j(c,13);9(s.2z>0)56(G(){9(i){i.9q();9(!k)c("2z")}},s.2z)}2a{i.9o(s.M)}29(e){E.5r(s,i,S,e)}9(!s.3e)c();I i;G 1C(){9(s.1C)s.1C(M,1v);9(s.1Z)E.1j.1F("5I",[i,s])}G 1l(){9(s.1l)s.1l(i,1v);9(s.1Z)E.1j.1F("6t",[i,s]);9(s.1Z&&!--E.5b)E.1j.1F("5K")}},5r:G(s,a,b,e){9(s.3U)s.3U(a,b,e);9(s.1Z)E.1j.1F("5J",[a,s,e])},5b:0,6S:G(r){2a{I!r.1v&&9n.9l=="54:"||(r.1v>=6N&&r.1v<9j)||r.1v==6M||E.V.1N&&r.1v==W}29(e){}I P},6R:G(a,c){2a{H b=a.5s("6P-5x");I a.1v==6M||b==E.49[c]||E.V.1N&&a.1v==W}29(e){}I P},6Q:G(r,b){H c=r.5s("9i-O");H d=b=="6K"||!b&&c&&c.1g("6K")>=0;H a=d?r.9g:r.40;9(d&&a.2V.37=="5k")6G"5k";9(b=="1J")E.5f(a);9(b=="45")a=3w("("+a+")");I a},3a:G(a){H s=[];9(a.1c==1B||a.4c)E.N(a,G(){s.1a(3f(6.2H)+"="+3f(6.1Q))});J L(H j 1i a)9(a[j]&&a[j].1c==1B)E.N(a[j],G(){s.1a(3f(j)+"="+3f(6))});J s.1a(3f(j)+"="+3f(a[j]));I s.66("&").1p(/%20/g,"+")}});E.1b.1k({1A:G(b,a){I b?6.1U({1H:"1A",2N:"1A",1r:"1A"},b,a):6.1E(":1P").N(G(){6.R.19=6.3h?6.3h:"";9(E.17(6,"19")=="2s")6.R.19="2Z"}).2D()},1z:G(b,a){I b?6.1U({1H:"1z",2N:"1z",1r:"1z"},b,a):6.1E(":3R").N(G(){6.3h=6.3h||E.17(6,"19");9(6.3h=="2s")6.3h="2Z";6.R.19="2s"}).2D()},6J:E.1b.25,25:G(a,b){I E.1n(a)&&E.1n(b)?6.6J(a,b):a?6.1U({1H:"25",2N:"25",1r:"25"},a,b):6.N(G(){E(6)[E(6).3t(":1P")?"1A":"1z"]()})},9c:G(b,a){I 6.1U({1H:"1A"},b,a)},9b:G(b,a){I 6.1U({1H:"1z"},b,a)},99:G(b,a){I 6.1U({1H:"25"},b,a)},98:G(b,a){I 6.1U({1r:"1A"},b,a)},96:G(b,a){I 6.1U({1r:"1z"},b,a)},95:G(c,a,b){I 6.1U({1r:a},c,b)},1U:G(k,i,h,g){H j=E.6D(i,h,g);I 6[j.3L===P?"N":"3L"](G(){j=E.1k({},j);H f=E(6).3t(":1P"),3y=6;L(H p 1i k){9(k[p]=="1z"&&f||k[p]=="1A"&&!f)I E.1n(j.1l)&&j.1l.16(6);9(p=="1H"||p=="2N"){j.19=E.17(6,"19");j.2U=6.R.2U}}9(j.2U!=S)6.R.2U="1P";j.3M=E.1k({},k);E.N(k,G(c,a){H e=1u E.2j(3y,j,c);9(/25|1A|1z/.14(a))e[a=="25"?f?"1A":"1z":a](k);J{H b=a.3s().1t(/^([+-]=)?([\\d+-.]+)(.*)$/),1O=e.2b(Q)||0;9(b){H d=3I(b[2]),2i=b[3]||"2T";9(2i!="2T"){3y.R[c]=(d||1)+2i;1O=((d||1)/e.2b(Q))*1O;3y.R[c]=1O+2i}9(b[1])d=((b[1]=="-="?-1:1)*d)+1O;e.3N(1O,d,2i)}J e.3N(1O,a,"")}});I Q})},3L:G(a,b){9(E.1n(a)){b=a;a="2j"}9(!a||(1m a=="1M"&&!b))I A(6[0],a);I 6.N(G(){9(b.1c==1B)A(6,a,b);J{A(6,a).1a(b);9(A(6,a).K==1)b.16(6)}})},9f:G(){H a=E.32;I 6.N(G(){L(H i=0;i-8O?r:3I(E.17(6.T,6.1e))||0},3N:G(c,b,e){6.5u=(1u 3D()).3B();6.1O=c;6.2D=b;6.2i=e||6.2i||"2T";6.2v=6.1O;6.4q=6.4i=0;6.4r();H f=6;G t(){I f.2F()}t.T=6.T;E.32.1a(t);9(E.32.K==1){H d=4j(G(){H a=E.32;L(H i=0;i6.Y.2e+6.5u){6.2v=6.2D;6.4q=6.4i=1;6.4r();6.Y.3M[6.1e]=Q;H a=Q;L(H i 1i 6.Y.3M)9(6.Y.3M[i]!==Q)a=P;9(a){9(6.Y.19!=S){6.T.R.2U=6.Y.2U;6.T.R.19=6.Y.19;9(E.17(6.T,"19")=="2s")6.T.R.19="2Z"}9(6.Y.1z)6.T.R.19="2s";9(6.Y.1z||6.Y.1A)L(H p 1i 6.Y.3M)E.1x(6.T.R,p,6.Y.3P[p])}9(a&&E.1n(6.Y.1l))6.Y.1l.16(6.T);I P}J{H n=t-6.5u;6.4i=n/6.Y.2e;6.4q=E.3J[6.Y.3J||(E.3J.5q?"5q":"6B")](6.4i,n,0,1,6.Y.2e);6.2v=6.1O+((6.2D-6.1O)*6.4q);6.4r()}I Q}};E.2j.2F={2R:G(a){a.T.2R=a.2v},2B:G(a){a.T.2B=a.2v},1r:G(a){E.1x(a.T.R,"1r",a.2v)},6z:G(a){a.T.R[a.1e]=a.2v+a.2i}};E.1b.6m=G(){H c=0,3E=0,T=6[0],5t;9(T)8L(E.V){H b=E.17(T,"2X")=="4F",1D=T.12,23=T.23,2K=T.3H,4f=1N&&3x(4s)<8J;9(T.6V){5w=T.6V();1f(5w.1S+38.33(2K.2V.2R,2K.1G.2R),5w.3E+38.33(2K.2V.2B,2K.1G.2B));9(1h){H d=E("4o").17("8H");d=(d=="8G"||E.5g&&3x(4s)>=7)&&2||d;1f(-d,-d)}}J{1f(T.5l,T.5z);1W(23){1f(23.5l,23.5z);9(35&&/^t[d|h]$/i.14(1D.37)||!4f)d(23);9(4f&&!b&&E.17(23,"2X")=="4F")b=Q;23=23.23}1W(1D.37&&!/^1G|4o$/i.14(1D.37)){9(!/^8D|1I-9S.*$/i.14(E.17(1D,"19")))1f(-1D.2R,-1D.2B);9(35&&E.17(1D,"2U")!="3R")d(1D);1D=1D.12}9(4f&&b)1f(-2K.1G.5l,-2K.1G.5z)}5t={3E:3E,1S:c}}I 5t;G d(a){1f(E.17(a,"9T"),E.17(a,"8A"))}G 1f(l,t){c+=3x(l)||0;3E+=3x(t)||0}}})();',62,616,'||||||this|||if|||||||||||||||||||||||||||||||||function|var|return|else|length|for|data|each|type|false|true|style|null|elem|document|browser|undefined||options|||nodeName|parentNode||test|jQuery|apply|css|window|display|push|fn|constructor|url|prop|add|indexOf|msie|in|event|extend|complete|typeof|isFunction|className|replace|arguments|opacity|div|match|new|status|firstChild|attr|nodeType|hide|show|Array|success|parent|filter|trigger|body|height|table|script|tbody|cache|string|safari|start|hidden|value|merge|left|break|animate|dataType|while|map|find|global||get|id|offsetParent|select|toggle|selected|toUpperCase|remove|catch|try|cur|al|ready|duration|done|text|makeArray|unit|fx|swap|split|target||pushStack|toLowerCase|nextSibling|button|none|handle|guid|now|stack|tb|jsre|timeout|inArray|scrollTop|readyState|end|delete|step|one|name|nth|slice|doc|ret|preventDefault|width|call|events|checked|scrollLeft|exec|px|overflow|documentElement|grep|position|form|block|removeData|rl|timers|max|opera|mozilla|trim|tagName|Math|load|param|removeChild|disabled|insertBefore|async|encodeURIComponent|append|oldblock|val|childNodes|src|readyList|multiFilter|color|defaultView|stopPropagation|args|old|toString|is|last|first|eval|parseInt|self|domManip|prototype|getTime|curCSS|Date|top||ajax|ownerDocument|parseFloat|easing|has|queue|curAnim|custom|innerHTML|orig|currentStyle|visible|getElementById|isReady|error|static|bind|String|which|getComputedStyle|responseText|oWidth|oHeight|on|shift|json|child|RegExp|ol|lastModified|isXMLDoc|jsonp|jquery|previousSibling|dir|safari2|el|styleFloat|state|setInterval|radio|getElementsByTagName|tr|empty|html|getAttribute|pos|update|version|input|float|runtimeStyle|unshift|mouseover|getPropertyValue|GET|clearInterval|safariTimer|visibility|clean|__ie_init|absolute|handleHover|lastToggle|index|fromElement|relatedTarget|click|fix|evt|andSelf|removeEventListener|handler|cloneNode|addEventListener|triggered|nodeIndex|unique|Number|classFilter|prevObject|selectedIndex|after|submit|password|removeAttribute|file|expr|setTimeout|_|appendChild|ajaxSettings|client|active|win|sibling|deep|globalEval|boxModel|cssFloat|object|checkbox|parsererror|offsetLeft|wrapAll|dequeue|props|lastChild|swing|handleError|getResponseHeader|results|startTime|00|box|Modified|ifModified|offsetTop|evalScript|createElement|setRequestHeader|ctrlKey|callback|metaKey|contentType|ajaxSend|ajaxSuccess|ajaxError|ajaxStop|ajaxStart|serializeArray|init|notmodified|POST|loaded|appendTo|DOMContentLoaded|bindReady|mouseout|not|removeAttr|unbind|unload|Width|keyCode|charCode|onreadystatechange|clientX|pageX|srcElement|join|outerHTML|substr|zoom|parse|textarea|reset|image|odd|even|before|quickClass|quickID|prepend|quickChild|execScript|offset|scroll|processData|uuid|contents|continue|textContent|ajaxComplete|clone|setArray|webkit|nodeValue|fl|_default|100|linear|href|speed|eq|createTextNode|throw|replaceWith|splice|_toggle|xml|colgroup|304|200|alpha|Last|httpData|httpNotModified|httpSuccess|fieldset|beforeSend|getBoundingClientRect|XMLHttpRequest|ActiveXObject|col|br|abbr|pixelLeft|urlencoded|www|application|ajaxSetup|post|getJSON|getScript|elements|serialize|clientWidth|hasClass|scr|clientHeight|write|relative|keyup|keypress|keydown|change|mousemove|mouseup|mousedown|right|dblclick|resize|focus|blur|frames|instanceof|hover|offsetWidth|triggerHandler|ipt|defer|offsetHeight|border|padding|clientY|pageY|Left|Right|toElement|Bottom|Top|cancelBubble|returnValue|detachEvent|attachEvent|substring|line|weight|animated|header|font|enabled|innerText|contains|only|size|gt|lt|uFFFF|u0128|417|inner|Height|toggleClass|removeClass|addClass|replaceAll|noConflict|insertAfter|prependTo|wrap|contentWindow|contentDocument|http|iframe|children|siblings|prevAll|nextAll|wrapInner|prev|Boolean|next|parents|maxLength|maxlength|readOnly|readonly|class|htmlFor|CSS1Compat|compatMode|compatible|borderTopWidth|ie|ra|inline|it|rv|medium|borderWidth|userAgent|522|navigator|with|concat|1px|10000|array|ig|PI|NaN|400|reverse|fast|600|slow|Function|Object|setAttribute|changed|be|can|property|fadeTo|fadeOut|getAttributeNode|fadeIn|slideToggle|method|slideUp|slideDown|action|cssText|stop|responseXML|option|content|300|th|protocol|td|location|send|cap|abort|colg|cos|tfoot|thead|With|leg|Requested|opt|GMT|1970|Jan|01|Thu|area|Since|hr|If|Type|Content|meta|specified|open|link|XMLHTTP|Microsoft|img|onload|row|borderLeftWidth|head|attributes'.split('|'),0,{})) \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/js/pngfix.js b/system/application/views/themes/teh_blog_ar_(not)_dead/js/pngfix.js new file mode 100755 index 0000000..920f770 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/js/pngfix.js @@ -0,0 +1,39 @@ +/* + +Correctly handle PNG transparency in Win IE 5.5 & 6. +http://homepage.ntlworld.com/bobosola. Updated 18-Jan-2006. + +Use in with DEFER keyword wrapped in conditional comments: + + +*/ + +var arVersion = navigator.appVersion.split("MSIE") +var version = parseFloat(arVersion[1]) + +if ((version >= 5.5) && (document.body.filters)) +{ + for(var i=0; i" + img.outerHTML = strNewHTML + i = i-1 + } + } +} diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/readme.txt b/system/application/views/themes/teh_blog_ar_(not)_dead/readme.txt new file mode 100755 index 0000000..f593b38 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/readme.txt @@ -0,0 +1,62 @@ +* teh blog ar (not) dead * +========================== +Version 1.0 (tested with Sweetcron 1.08e) + +Thanks for downloading this Sweetcron theme! We know your blog posts are important to you. We also know you're probably an active internet geek much like we are. In the world of Sweetcron, this doesn't fair well for your blog posts. + +Never fear - teh blog ar (not) dead will give your blog posts the spotlight they deserve! + +Features +-------- +* Dedicated area for blog items +* Expandable profile section +* Activity items link directly to original source +* Clean customizable single column layout + +NOTE +---- +This theme was created pre-1.08c, when there was no easy way to make custom queries and isolate blog items from the rest. Version 1.08e SHOULD provide an adequate solution to this, making this theme's approach somewhat outdated (we know, our timing is impeccable). + +Download the latest version of Sweetcron: +http://code.google.com/p/sweetcron/downloads/list + +To customize this theme: +======================== + +1. Unpackage the ZIP file. +2. Edit the following files/areas: + +_header.php +----------- +* RSS links (line 71) +* Profile picture (line 85) +* Profile bio (line 90) +* Contact links (starts line 97) + +_acivity_feed.php +----------------- +* Twitter profile picture (line 91) (you might want to download a Twitter plugin that can pull this dynamically instead) + +Images +------ +* i/profile-blank.png +* i/twitter-blank.png + +To activate this theme: +======================= + +1. Copy the entire theme folder into your web server's /system/application/views/themes/ directory. +2. Login to your Sweetcron admin, click Options, and select 'Teh Blog Ar (not) Dead' from the Theme dropdown menu. +3. Celebrate your new-found awesomeness. + +Support +======= + +Unfortunately, at the moment we are unable to provide any type of support for this theme. teh blog ar (not) dead is provided *as is* and we cannot guarantee its compatibility with future versions of Sweetcron. + +All that mean stuff being said, we will do our best to listen to your feedback, comments, flames and hugs. Please leave your thoughts on our Sweetcron discussion group thread: http://mawsh.com/labs/tehblogarnotdead/discuss/. + + +***** +teh blog ar (not) dead was developed by the geeks at mawsh (mawsh.com). + diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/rss_feed.php b/system/application/views/themes/teh_blog_ar_(not)_dead/rss_feed.php new file mode 100755 index 0000000..0b5b7e6 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/rss_feed.php @@ -0,0 +1,20 @@ + + + <?php echo $this->config->item('lifestream_title')?> + config->item('base_url')?>feed + + en-us + http://blogs.law.harvard.edu/tech/rss + Sweetcron + config->item('admin_email')?> + + + <?php echo $item->get_title()?> + get_permalink()?> + get_content()?>]]> + get_date())?> + get_original_permalink()?> + + + + \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/single.php b/system/application/views/themes/teh_blog_ar_(not)_dead/single.php new file mode 100755 index 0000000..a754222 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/single.php @@ -0,0 +1,22 @@ + + +
    + + + +
    +

    get_title()?>

    + get_date()); ?> +
    get_content()?>
    + +
      +
    • Tags:
    • + get_tags() as $tag): ?> +
    • name?>
    • + +
    + + +
    + +
    \ No newline at end of file diff --git a/system/application/views/themes/teh_blog_ar_(not)_dead/style.css b/system/application/views/themes/teh_blog_ar_(not)_dead/style.css new file mode 100755 index 0000000..6509c44 --- /dev/null +++ b/system/application/views/themes/teh_blog_ar_(not)_dead/style.css @@ -0,0 +1,751 @@ +/* + +Theme Name: teh blog ar (not) dead +Theme URI: http://mawsh.com/labs/tehblogarnotdead/ +Description: A Sweetcron theme that keeps your blog posts front and center so that they don't get drowned out by your other geeky internet activities. +Version: 1.0 +Author: mawsh +Author URI: http://mawsh.com + +The CSS, XHTML and design is released under GPL: +http://www.opensource.org/licenses/gpl-license.php + +*/ + +/* Reset */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} +/* remember to define focus styles! */ +:focus { + outline: 0; +} +body { + line-height: 1; + color: black; + background: white; +} +ol, ul { + list-style: none; +} +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: separate; + border-spacing: 0; +} +caption, th, td { + text-align: left; + font-weight: normal; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ""; +} +blockquote, q { + quotes: "" ""; +} + +/* Global */ + +html {height:100%;margin-bottom:1px;} + +body { + background: #eee url('i/bg.jpg') top center repeat-x; + font-family: "lucida grande", "lucida sans unicode", helvetica, arial, sans-serif; + color: #555555; + text-align: center; + font-size: 100%; + } + +a, a:visited { + color: #0066cb; + text-decoration: none; + } + +a:hover, a:active { + color: #555; + text-decoration: none; + } + +input, textarea { + font-family: "lucida grande", "lucida sans unicode", helvetica, arial, sans-serif; + } + +input { + } + +textarea { + } + +hr { + border: 1px dotted #DADADA; + height: 1px; + clear: both; + margin: 10px 0px; + } + +code { + color: green; + background: #FAFAFA; + padding: 0 3px; + border: 1px solid #EAEAEA; + } + +/* Site Specific */ + +.container { + clear: both; + font-size: 1.0em; + line-height: 1.0em; + margin: 0 auto; + padding: 0; + position: relative; + top: 0px; + left: 0px; + text-align: left; + width: 940px; + } + + +/* Header & Profile */ + +#header, #profile { + clear: both; + float: left; + margin: 0; + position: relative; + width: 100%; + } + + #header { + background: #000; + height: 50px; + } + + #header #toggle { + cursor: pointer; + position: absolute; + left: 620px; + top: 13px; + height: 25px; + width: 80px; + } + + #header-titles { + position: absolute; + width: 100%; + top: 0px; + left: 0px; + z-index: 500; + } + + #header #learn { + background: url('i/learn-more.png') 620px 13px no-repeat; + height: 50px; + } + + #header.active #learn { + background: url('i/learn-less.png') 620px 13px no-repeat; + } + + #header-titles #site-title { + color: #fff; + font-size: 1.125em; + font-weight: bold; + left: 0px; + padding-left: 20px; + position: absolute; + top: 18px; + } + + #header-titles #site-title a { + color: #fff; + } + + #header-titles #rss-feed { + background: url('i/feed-icon-14x14.png') 0 3px no-repeat; + font-size: 0.75em; + padding-left: 20px; + padding: 1px 0 5px 20px; + position: absolute; + top: 15px; + left: 740px; + } + + #header-titles #rss-feed a { + color: #dc6022; + } + + #header-titles #rss-feed a:hover { + color: #fff; + } + + #profile { + background: url('i/bg-profile.png') 0 0; + z-index: 100; + /* Uncomment to float profile */ + /* + position: absolute; + top: 50px; left: 0px; + */ + } + + #profile .wrap { + float: left; + position: relative; + width: 940px; + } + + #profile #profile-pic { + border: 10px solid #111; + float: left; + position: relative; + left: 20px; + top: 20px; + width: 120px; + } + + #profile #profile-about { + color: #888; + float: left; + padding-left: 40px; + margin-top: 20px; + width: 520px; + } + + #profile #profile-about h2, #profile #profile-feeds h2 { + color: #fff; + font-size: 0.9em; + font-weight: bold; + padding-top: 10px; + margin-bottom: 5px; + } + + #profile #profile-about p, #profile #profile-feeds p { + font-size: 0.8em; + line-height: 1.4em; + } + + #profile #profile-feeds { + float: right; + margin-top: 20px; + width: 200px; + } + + #profile #profile-feeds p { + padding: 3px 0; + padding-left: 20px; + height: 22px; + } + + /* Add more classes as needed */ + + #profile #profile-feeds .twitter { + background: url('http://www.twitter.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds .flickr { + background: url('http://www.flickr.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds .youtube { + background: url('http://www.youtube.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds .digg { + background: url('http://www.digg.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds .facebook { + background: url('http://www.facebook.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds .linkedin { + background: url('http://www.linkedin.com/favicon.ico') 0px 5px no-repeat; + } + + #profile #profile-feeds a:hover { + color: #fff; + } + + #profile #profile-tags { + clear: both; + padding: 45px 20px 15px; + float: left; + width: 680px; + } + + #profile #profile-tags ul, #body #main_container #single_container .tag_list { + list-style-type: none; + padding: 5px 0; + } + + #profile #profile-tags li, #body #main_container #single_container .tag_list li { + color: #fff; + display: inline; + margin: 0; + font-size: 0.8em; + } + + #body #main_container #single_container .tag_list li { + color: #555; + } + + #profile #profile-tags li a { + color: #626262; + } + + #profile #profile-tags li a:hover { + color: #ddd; + } + + #profile #search_form { + padding-top: 5px; + position: absolute; + top: 240px; + left: 740px; + } + + #profile #search_form p { + color: #fff; + font-size: 0.8em; + margin-bottom: 5px; + padding-bottom: 5px; + } + + #profile #search_form input { + background: #101010; + border: 0; + border-top: 1px solid #000; + color: #fff; + font-size: 0.8em; + padding: 5px 7px; + height: 15px; + vertical-align: middle; + width: 100px; + } + + #profile #search_form #submit { + background: #000; + border: 1px solid #000; + color: #fff; + height: 26px; + margin-left: 2px; + padding: 0 2px; + width: 60px; + text-transform: uppercase; + } + + +/* Body */ + +#body, #footer { + clear: both; + float: left; + position: relative; + } + + /* Home/breakdcrumb bar */ + + #body .home { + font-size: 0.8em; + padding: 20px 0; + border-bottom: 2px solid #ddd; + } + + + /* Blog items */ + + #body #blog-items { + background: transparent url('i/bg-blog-items.png') no-repeat; + height: 231px; + margin: 20px 0 0; + padding: 30px 20px 20px; + width: 900px; + } + + #body #blog-items #latest { + float: left; + width: 680px; + } + + #body #blog-items #latest h2 { + font-size: 1.8em; + font-weight: bold; + margin: 5px 0 15px; + } + + #body #blog-items #latest small { + color: #626262; + display: block; + font-size: 0.7em; + margin-bottom: 20px; + } + + #body #blog-items #latest p { + color: #000; + font-size: 0.875em; + line-height: 1.8em; + } + + #body #blog-items #latest .readmore { + margin-top: 20px; + } + + #body #blog-items #latest .readmore a { + background: #0066cb; + color: #fff; + font-size: 0.8em; + padding: 3px 5px; + } + + #body #blog-items #latest .readmore a:hover { + background: #333; + } + + #body #blog-items #recent { + float: right; + width: 180px; + } + + #body #blog-items #recent h2 { + background: url('/favicon.ico') no-repeat; + color: #000; + font-size: 1.06em; + font-weight: bold; + padding-left: 20px; + margin-bottom: 15px; + } + + #body #blog-items #recent h2 a { + color: #000; + } + + #body #blog-items #recent li { + font-size: 0.875em; + margin-bottom: 10px; + } + + #body #blog-items #recent li h3 { + font-weight: normal; + } + + #body #blog-items #recent li h3 a { + display: block; + padding: 5px 0; + } + + #body #blog-items #recent li h3 .selected { + background: #0066cb url('i/bg-gen.png'); + border: 1px solid #fff; + color: #fff; + font-weight: normal; + padding: 4px 7px; + } + + #body #blog-items #recent li small { + color: #626262; + font-size: 0.8em; + } + + #body #blog-items #recent li .readmore { + font-size: 0.9em; + font-weight: bold; + } + + /* All items */ + + #body #items { + float: left; + margin: 20px 0 0; + } + + #body #items li { + background: url('i/bg-item.png') no-repeat; + display: inline; + float: left; + height: 300px; + padding-bottom: 1px; + margin-left: 20px; + margin-bottom: 20px; + width: 220px; + } + + #body #items li.first { + clear: left; + margin-left: 0; + } + + #body #items li .meta { + color: #b8b8b8; + font-size: 0.6875em; + height: 20px; + overflow: hidden; + padding-left: 20px; + } + + #body #items li .meta a { + color: #626262; + font-size: 1.15em; + } + + #body #items li .meta a:hover { + color: #0066cb; + } + + #body #items li .box { + cursor: pointer; + font-size: 0.8em; + line-height: 1.4em; + height: 280px; + position: relative; + } + + /* Twitter */ + + #body #items li .twitter { + background: url('i/bg-twitter.png') no-repeat; + } + + #body #items li .twitter .profile-pic { + border: 1px solid #fff; + position: absolute; + top: 20px; + left: 20px; + } + + #body #items li .twitter .content { + position: absolute; + top: 95px; + left: 40px; + width: 140px; + } + + #body #items li .twitter .content a { + color: #555; + } + + /* Video */ + + #body #items li .video { + background: url('i/bg-video.png') no-repeat; + } + + #body #items li .video .content { + color: #fff; + font-weight: bold; + left: 20px; + position: relative; + top: 15px; + width: 180px; + } + + #body #items li .video .content a { + color: #fff; + } + + /* Photo */ + + #body #items li .photo { + } + + #body #items li .photo .content { + background: url('i/bg-photo.png'); + color: #aaa; + font-size: 0.9em; + line-height: 1.3em; + height: 80px; + padding: 20px; + position: absolute; + top: 160px; + left: 0; + width: 180px; + } + + #body #items li .photo .content strong { + color: #fff; + font-size: 1.17em; + font-weight: bold; + } + + #body #items li .photo .content a { + color: #fff; + } + + /* Blog */ + + #body #items li .blog { + } + + #body #items li .blog .title { + background: #0066cb url('i/bg-gen.png'); + border: 1px solid #ececec; + color: #fff; + font-weight: bold; + padding: 10px 20px; + } + + #body #items li .blog .title a { + color: #fff; + } + + #body #items li .blog .content { + font-size: 0.85em; + padding: 10px 20px; + } + + /* Generic */ + + #body #items li .gen { + } + + #body #items li .gen .title { + background: #333 url('i/bg-gen-grey.png'); + border: 1px solid #ececec; + color: #fff; + font-weight: bold; + padding: 10px 20px; + } + + #body #items li .gen .title a { + color: #fff; + } + + #body #items li .gen .content { + font-size: 0.85em; + padding: 10px 20px; + } + + /* Pagination */ + + #body #pagination { + border-top: 2px solid #ddd; + clear: both; + font-size: 0.8em; + font-weight: bold; + float: left; + margin-top: 20px; + margin-bottom: 30px; + padding: 20px 0; + width: 940px; + } + + #body #pagination a { + background: #0066cb; + color: #fff; + font-weight: normal; + padding: 1px 5px; + } + + #body #pagination a:hover { + background: #333; + } + + /* Single Template */ + + #body #main_container { + background: #fff; + border: 1px solid #ececec; + margin: 20px 0; + padding: 20px; + width: 898px; + } + + /* Breadcrumb */ + + #body #main_container .breadcrumb { + font-size: 0.8em; + padding: 0 0 20px; + margin-bottom: 30px; + border-bottom: 2px solid #ddd; + } + + #body #main_container #single_container { + width: 900px; + } + + #body #main_container #single_container h2 { + font-size: 1.8em; + font-weight: bold; + margin: 5px 0 15px; + } + + #body #main_container #single_container small { + color: #626262; + display: block; + font-size: 0.7em; + margin-bottom: 20px; + } + + #body #main_container #single_container p { + font-size: 0.8em; + line-height: 1.8em; + margin-bottom: 15px; + } + + #body #main_container #single_container em, #body #main_container #single_container i { + font-style: italic; + } + + #body #main_container #single_container strong, #body #main_container #single_container b { + font-weight: bold; + } + + #body #main_container #single_container ul, #body #main_container #single_container ol { + margin-bottom: 15px; + } + + #body #main_container #single_container ul { + list-style-type: disc; + } + + #body #main_container #single_container ol { + list-style-type: decimal; + } + + #body #main_container #single_container li { + font-size: 0.8em; + line-height: 1.8em; + margin-left: 25px; + } + +/* Footer */ + +#footer { + background: #ddd; + font-size: 0.7em; + float: left; + width: 100%; + padding: 10px 0; + } + + /* Link love! */ + + #footer .tehblogarnotdead a { + background: #333; + border-left: 5px solid #666; + color: #ddd; + float: left; + padding: 5px 7px; + } + + #footer .sweetcron { + float: right; + padding: 5px 0; + } \ No newline at end of file diff --git a/system/cache/.svn/all-wcprops b/system/cache/.svn/all-wcprops new file mode 100644 index 0000000..df7dd7e --- /dev/null +++ b/system/cache/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 35 +/svn/!svn/ver/18/trunk/system/cache +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/!svn/ver/18/trunk/system/cache/index.html +END diff --git a/system/cache/.svn/entries b/system/cache/.svn/entries new file mode 100644 index 0000000..3f1ad05 --- /dev/null +++ b/system/cache/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/cache +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:18:04.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/cache/.svn/prop-base/index.html.svn-base b/system/cache/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/cache/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/cache/.svn/text-base/index.html.svn-base b/system/cache/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/cache/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/cache/index.html b/system/cache/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/cache/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/codeigniter/.svn/all-wcprops b/system/codeigniter/.svn/all-wcprops new file mode 100644 index 0000000..873a52d --- /dev/null +++ b/system/codeigniter/.svn/all-wcprops @@ -0,0 +1,41 @@ +K 25 +svn:wc:ra_dav:version-url +V 41 +/svn/!svn/ver/18/trunk/system/codeigniter +END +CodeIgniter.php +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/codeigniter/CodeIgniter.php +END +Base4.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/codeigniter/Base4.php +END +Base5.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/codeigniter/Base5.php +END +Compat.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/codeigniter/Compat.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/codeigniter/index.html +END +Common.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/codeigniter/Common.php +END diff --git a/system/codeigniter/.svn/entries b/system/codeigniter/.svn/entries new file mode 100644 index 0000000..5f427d4 --- /dev/null +++ b/system/codeigniter/.svn/entries @@ -0,0 +1,232 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/codeigniter +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +CodeIgniter.php +file + + + + +2009-09-15T00:18:19.000000Z +2513d006ba799108d1bba5845de48a36 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7348 + +Base4.php +file + + + + +2009-09-15T00:18:19.000000Z +4bc28ba2e9466573429c37005e4ad640 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1865 + +Base5.php +file + + + + +2009-09-15T00:18:19.000000Z +5d6a54382fc049c11034540b019fa9a6 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1189 + +Compat.php +file + + + + +2009-09-15T00:18:19.000000Z +26b516b947ebf37654f137cf3c39b67b +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2179 + +index.html +file + + + + +2009-09-15T00:18:19.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +Common.php +file + + + + +2009-09-15T00:18:19.000000Z +7c9fc2392e09880f7b33aa03622f44a7 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +6809 + diff --git a/system/codeigniter/.svn/prop-base/Base4.php.svn-base b/system/codeigniter/.svn/prop-base/Base4.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/Base4.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/prop-base/Base5.php.svn-base b/system/codeigniter/.svn/prop-base/Base5.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/Base5.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base b/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/CodeIgniter.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/prop-base/Common.php.svn-base b/system/codeigniter/.svn/prop-base/Common.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/Common.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/prop-base/Compat.php.svn-base b/system/codeigniter/.svn/prop-base/Compat.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/Compat.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/prop-base/index.html.svn-base b/system/codeigniter/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/codeigniter/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/codeigniter/.svn/text-base/Base4.php.svn-base b/system/codeigniter/.svn/text-base/Base4.php.svn-base new file mode 100644 index 0000000..577977c --- /dev/null +++ b/system/codeigniter/.svn/text-base/Base4.php.svn-base @@ -0,0 +1,67 @@ +load->library('email') to instantiate + * classes that can then be used within controllers as $this->email->send() + * + * PHP 4 also has trouble referencing the CI super object within application + * constructors since objects do not exist until the class is fully + * instantiated. Basically PHP 4 sucks... + * + * Since PHP 5 doesn't suffer from this problem so we load one of + * two files based on the version of PHP being run. + * + * @package CodeIgniter + * @subpackage codeigniter + * @category front-controller + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/ + */ + class CI_Base extends CI_Loader { + + function CI_Base() + { + // This allows syntax like $this->load->foo() to work + parent::CI_Loader(); + $this->load =& $this; + + // This allows resources used within controller constructors to work + global $OBJ; + $OBJ = $this->load; // Do NOT use a reference. + } +} + +function &get_instance() +{ + global $CI, $OBJ; + + if (is_object($CI)) + { + return $CI; + } + + return $OBJ->load; +} + +?> \ No newline at end of file diff --git a/system/codeigniter/.svn/text-base/Base5.php.svn-base b/system/codeigniter/.svn/text-base/Base5.php.svn-base new file mode 100644 index 0000000..c731a00 --- /dev/null +++ b/system/codeigniter/.svn/text-base/Base5.php.svn-base @@ -0,0 +1,54 @@ + \ No newline at end of file diff --git a/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base b/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base new file mode 100644 index 0000000..8f9dbdf --- /dev/null +++ b/system/codeigniter/.svn/text-base/CodeIgniter.php.svn-base @@ -0,0 +1,267 @@ +mark('total_execution_time_start'); +$BM->mark('loading_time_base_classes_start'); + +/* + * ------------------------------------------------------ + * Instantiate the hooks class + * ------------------------------------------------------ + */ + +$EXT =& load_class('Hooks'); + +/* + * ------------------------------------------------------ + * Is there a "pre_system" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('pre_system'); + +/* + * ------------------------------------------------------ + * Instantiate the base classes + * ------------------------------------------------------ + */ + +$CFG =& load_class('Config'); +$URI =& load_class('URI'); +$RTR =& load_class('Router'); +$OUT =& load_class('Output'); + +/* + * ------------------------------------------------------ + * Is there a valid cache file? If so, we're done... + * ------------------------------------------------------ + */ + +if ($EXT->_call_hook('cache_override') === FALSE) +{ + if ($OUT->_display_cache($CFG, $RTR) == TRUE) + { + exit; + } +} + +/* + * ------------------------------------------------------ + * Load the remaining base classes + * ------------------------------------------------------ + */ + +$IN =& load_class('Input'); +$LANG =& load_class('Language'); + +/* + * ------------------------------------------------------ + * Load the app controller and local controller + * ------------------------------------------------------ + * + * Note: Due to the poor object handling in PHP 4 we'll + * conditionally load different versions of the base + * class. Retaining PHP 4 compatibility requires a bit of a hack. + * + * Note: The Loader class needs to be included first + * + */ +if (floor(phpversion()) < 5) +{ + load_class('Loader', FALSE); + require(BASEPATH.'codeigniter/Base4'.EXT); +} +else +{ + require(BASEPATH.'codeigniter/Base5'.EXT); +} + +// Load the base controller class +load_class('Controller', FALSE); + +// Load the local application controller +// Note: The Router class automatically validates the controller path. If this include fails it +// means that the default controller in the Routes.php file is not resolving to something valid. +if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT)) +{ + show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); +} + +include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT); + +// Set a mark point for benchmarking +$BM->mark('loading_time_base_classes_end'); + + +/* + * ------------------------------------------------------ + * Security check + * ------------------------------------------------------ + * + * None of the functions in the app controller or the + * loader class can be called via the URI, nor can + * controller functions that begin with an underscore + */ +$class = $RTR->fetch_class(); +$method = $RTR->fetch_method(); + + +if ( ! class_exists($class) + OR $method == 'controller' + OR substr($method, 0, 1) == '_' + OR in_array($method, get_class_methods('Controller'), TRUE) + ) +{ + show_404(); +} + +/* + * ------------------------------------------------------ + * Is there a "pre_controller" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('pre_controller'); + +/* + * ------------------------------------------------------ + * Instantiate the controller and call requested method + * ------------------------------------------------------ + */ + +// Mark a start point so we can benchmark the controller +$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start'); + +$CI = new $class(); + +// Is this a scaffolding request? +if ($RTR->scaffolding_request === TRUE) +{ + if ($EXT->_call_hook('scaffolding_override') === FALSE) + { + $CI->_ci_scaffolding(); + } +} +else +{ + /* + * ------------------------------------------------------ + * Is there a "post_controller_constructor" hook? + * ------------------------------------------------------ + */ + $EXT->_call_hook('post_controller_constructor'); + + // Is there a "remap" function? + if (method_exists($CI, '_remap')) + { + $CI->_remap($method); + } + else + { + if ( ! method_exists($CI, $method)) + { + show_404(); + } + + // Call the requested method. + // Any URI segments present (besides the class/function) will be passed to the method for convenience + call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); + } +} + +// Mark a benchmark end point +$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); + +/* + * ------------------------------------------------------ + * Is there a "post_controller" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('post_controller'); + +/* + * ------------------------------------------------------ + * Send the final rendered output to the browser + * ------------------------------------------------------ + */ + +if ($EXT->_call_hook('display_override') === FALSE) +{ + $OUT->_display(); +} + +/* + * ------------------------------------------------------ + * Is there a "post_system" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('post_system'); + +/* + * ------------------------------------------------------ + * Close the DB connection if one exists + * ------------------------------------------------------ + */ +if (class_exists('CI_DB') AND isset($CI->db)) +{ + $CI->db->close(); +} + + +?> \ No newline at end of file diff --git a/system/codeigniter/.svn/text-base/Common.php.svn-base b/system/codeigniter/.svn/text-base/Common.php.svn-base new file mode 100644 index 0000000..d9ddf80 --- /dev/null +++ b/system/codeigniter/.svn/text-base/Common.php.svn-base @@ -0,0 +1,298 @@ +show_error('An Error Was Encountered', $message); + exit; +} + + +/** +* 404 Page Handler +* +* This function is similar to the show_error() function above +* However, instead of the standard error template it displays +* 404 errors. +* +* @access public +* @return void +*/ +function show_404($page = '') +{ + $error =& load_class('Exceptions'); + $error->show_404($page); + exit; +} + + +/** +* Error Logging Interface +* +* We use this as a simple mechanism to access the logging +* class and send messages to be logged. +* +* @access public +* @return void +*/ +function log_message($level = 'error', $message, $php_error = FALSE) +{ + static $LOG; + + $config =& get_config(); + if ($config['log_threshold'] == 0) + { + return; + } + + $LOG =& load_class('Log'); + $LOG->write_log($level, $message, $php_error); +} + +/** +* Exception Handler +* +* This is the custom exception handler that is declaired at the top +* of Codeigniter.php. The main reason we use this is permit +* PHP errors to be logged in our own log files since we may +* not have access to server logs. Since this function +* effectively intercepts PHP errors, however, we also need +* to display errors based on the current error_reporting level. +* We do that with the use of a PHP error template. +* +* @access private +* @return void +*/ +function _exception_handler($severity, $message, $filepath, $line) +{ + // We don't bother with "strict" notices since they will fill up + // the log file with information that isn't normally very + // helpful. For example, if you are running PHP 5 and you + // use version 4 style class functions (without prefixes + // like "public", "private", etc.) you'll get notices telling + // you that these have been deprecated. + + if ($severity == E_STRICT) + { + return; + } + + $error =& load_class('Exceptions'); + + // Should we display the error? + // We'll get the current error_reporting level and add its bits + // with the severity bits to find out. + + if (($severity & error_reporting()) == $severity) + { + $error->show_php_error($severity, $message, $filepath, $line); + } + + // Should we log the error? No? We're done... + $config =& get_config(); + if ($config['log_threshold'] == 0) + { + return; + } + + $error->log_exception($severity, $message, $filepath, $line); +} + + +?> \ No newline at end of file diff --git a/system/codeigniter/.svn/text-base/Compat.php.svn-base b/system/codeigniter/.svn/text-base/Compat.php.svn-base new file mode 100644 index 0000000..56ebbf4 --- /dev/null +++ b/system/codeigniter/.svn/text-base/Compat.php.svn-base @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/system/codeigniter/.svn/text-base/index.html.svn-base b/system/codeigniter/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/codeigniter/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/codeigniter/Base4.php b/system/codeigniter/Base4.php new file mode 100755 index 0000000..577977c --- /dev/null +++ b/system/codeigniter/Base4.php @@ -0,0 +1,67 @@ +load->library('email') to instantiate + * classes that can then be used within controllers as $this->email->send() + * + * PHP 4 also has trouble referencing the CI super object within application + * constructors since objects do not exist until the class is fully + * instantiated. Basically PHP 4 sucks... + * + * Since PHP 5 doesn't suffer from this problem so we load one of + * two files based on the version of PHP being run. + * + * @package CodeIgniter + * @subpackage codeigniter + * @category front-controller + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/ + */ + class CI_Base extends CI_Loader { + + function CI_Base() + { + // This allows syntax like $this->load->foo() to work + parent::CI_Loader(); + $this->load =& $this; + + // This allows resources used within controller constructors to work + global $OBJ; + $OBJ = $this->load; // Do NOT use a reference. + } +} + +function &get_instance() +{ + global $CI, $OBJ; + + if (is_object($CI)) + { + return $CI; + } + + return $OBJ->load; +} + +?> \ No newline at end of file diff --git a/system/codeigniter/Base5.php b/system/codeigniter/Base5.php new file mode 100755 index 0000000..c731a00 --- /dev/null +++ b/system/codeigniter/Base5.php @@ -0,0 +1,54 @@ + \ No newline at end of file diff --git a/system/codeigniter/CodeIgniter.php b/system/codeigniter/CodeIgniter.php new file mode 100755 index 0000000..8f9dbdf --- /dev/null +++ b/system/codeigniter/CodeIgniter.php @@ -0,0 +1,267 @@ +mark('total_execution_time_start'); +$BM->mark('loading_time_base_classes_start'); + +/* + * ------------------------------------------------------ + * Instantiate the hooks class + * ------------------------------------------------------ + */ + +$EXT =& load_class('Hooks'); + +/* + * ------------------------------------------------------ + * Is there a "pre_system" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('pre_system'); + +/* + * ------------------------------------------------------ + * Instantiate the base classes + * ------------------------------------------------------ + */ + +$CFG =& load_class('Config'); +$URI =& load_class('URI'); +$RTR =& load_class('Router'); +$OUT =& load_class('Output'); + +/* + * ------------------------------------------------------ + * Is there a valid cache file? If so, we're done... + * ------------------------------------------------------ + */ + +if ($EXT->_call_hook('cache_override') === FALSE) +{ + if ($OUT->_display_cache($CFG, $RTR) == TRUE) + { + exit; + } +} + +/* + * ------------------------------------------------------ + * Load the remaining base classes + * ------------------------------------------------------ + */ + +$IN =& load_class('Input'); +$LANG =& load_class('Language'); + +/* + * ------------------------------------------------------ + * Load the app controller and local controller + * ------------------------------------------------------ + * + * Note: Due to the poor object handling in PHP 4 we'll + * conditionally load different versions of the base + * class. Retaining PHP 4 compatibility requires a bit of a hack. + * + * Note: The Loader class needs to be included first + * + */ +if (floor(phpversion()) < 5) +{ + load_class('Loader', FALSE); + require(BASEPATH.'codeigniter/Base4'.EXT); +} +else +{ + require(BASEPATH.'codeigniter/Base5'.EXT); +} + +// Load the base controller class +load_class('Controller', FALSE); + +// Load the local application controller +// Note: The Router class automatically validates the controller path. If this include fails it +// means that the default controller in the Routes.php file is not resolving to something valid. +if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT)) +{ + show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); +} + +include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT); + +// Set a mark point for benchmarking +$BM->mark('loading_time_base_classes_end'); + + +/* + * ------------------------------------------------------ + * Security check + * ------------------------------------------------------ + * + * None of the functions in the app controller or the + * loader class can be called via the URI, nor can + * controller functions that begin with an underscore + */ +$class = $RTR->fetch_class(); +$method = $RTR->fetch_method(); + + +if ( ! class_exists($class) + OR $method == 'controller' + OR substr($method, 0, 1) == '_' + OR in_array($method, get_class_methods('Controller'), TRUE) + ) +{ + show_404(); +} + +/* + * ------------------------------------------------------ + * Is there a "pre_controller" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('pre_controller'); + +/* + * ------------------------------------------------------ + * Instantiate the controller and call requested method + * ------------------------------------------------------ + */ + +// Mark a start point so we can benchmark the controller +$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start'); + +$CI = new $class(); + +// Is this a scaffolding request? +if ($RTR->scaffolding_request === TRUE) +{ + if ($EXT->_call_hook('scaffolding_override') === FALSE) + { + $CI->_ci_scaffolding(); + } +} +else +{ + /* + * ------------------------------------------------------ + * Is there a "post_controller_constructor" hook? + * ------------------------------------------------------ + */ + $EXT->_call_hook('post_controller_constructor'); + + // Is there a "remap" function? + if (method_exists($CI, '_remap')) + { + $CI->_remap($method); + } + else + { + if ( ! method_exists($CI, $method)) + { + show_404(); + } + + // Call the requested method. + // Any URI segments present (besides the class/function) will be passed to the method for convenience + call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); + } +} + +// Mark a benchmark end point +$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); + +/* + * ------------------------------------------------------ + * Is there a "post_controller" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('post_controller'); + +/* + * ------------------------------------------------------ + * Send the final rendered output to the browser + * ------------------------------------------------------ + */ + +if ($EXT->_call_hook('display_override') === FALSE) +{ + $OUT->_display(); +} + +/* + * ------------------------------------------------------ + * Is there a "post_system" hook? + * ------------------------------------------------------ + */ +$EXT->_call_hook('post_system'); + +/* + * ------------------------------------------------------ + * Close the DB connection if one exists + * ------------------------------------------------------ + */ +if (class_exists('CI_DB') AND isset($CI->db)) +{ + $CI->db->close(); +} + + +?> \ No newline at end of file diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php new file mode 100755 index 0000000..d9ddf80 --- /dev/null +++ b/system/codeigniter/Common.php @@ -0,0 +1,298 @@ +show_error('An Error Was Encountered', $message); + exit; +} + + +/** +* 404 Page Handler +* +* This function is similar to the show_error() function above +* However, instead of the standard error template it displays +* 404 errors. +* +* @access public +* @return void +*/ +function show_404($page = '') +{ + $error =& load_class('Exceptions'); + $error->show_404($page); + exit; +} + + +/** +* Error Logging Interface +* +* We use this as a simple mechanism to access the logging +* class and send messages to be logged. +* +* @access public +* @return void +*/ +function log_message($level = 'error', $message, $php_error = FALSE) +{ + static $LOG; + + $config =& get_config(); + if ($config['log_threshold'] == 0) + { + return; + } + + $LOG =& load_class('Log'); + $LOG->write_log($level, $message, $php_error); +} + +/** +* Exception Handler +* +* This is the custom exception handler that is declaired at the top +* of Codeigniter.php. The main reason we use this is permit +* PHP errors to be logged in our own log files since we may +* not have access to server logs. Since this function +* effectively intercepts PHP errors, however, we also need +* to display errors based on the current error_reporting level. +* We do that with the use of a PHP error template. +* +* @access private +* @return void +*/ +function _exception_handler($severity, $message, $filepath, $line) +{ + // We don't bother with "strict" notices since they will fill up + // the log file with information that isn't normally very + // helpful. For example, if you are running PHP 5 and you + // use version 4 style class functions (without prefixes + // like "public", "private", etc.) you'll get notices telling + // you that these have been deprecated. + + if ($severity == E_STRICT) + { + return; + } + + $error =& load_class('Exceptions'); + + // Should we display the error? + // We'll get the current error_reporting level and add its bits + // with the severity bits to find out. + + if (($severity & error_reporting()) == $severity) + { + $error->show_php_error($severity, $message, $filepath, $line); + } + + // Should we log the error? No? We're done... + $config =& get_config(); + if ($config['log_threshold'] == 0) + { + return; + } + + $error->log_exception($severity, $message, $filepath, $line); +} + + +?> \ No newline at end of file diff --git a/system/codeigniter/Compat.php b/system/codeigniter/Compat.php new file mode 100755 index 0000000..56ebbf4 --- /dev/null +++ b/system/codeigniter/Compat.php @@ -0,0 +1,94 @@ + \ No newline at end of file diff --git a/system/codeigniter/index.html b/system/codeigniter/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/codeigniter/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/.svn/all-wcprops b/system/database/.svn/all-wcprops new file mode 100644 index 0000000..f0d3515 --- /dev/null +++ b/system/database/.svn/all-wcprops @@ -0,0 +1,53 @@ +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/!svn/ver/18/trunk/system/database +END +DB_active_rec.php +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/!svn/ver/18/trunk/system/database/DB_active_rec.php +END +DB_driver.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/database/DB_driver.php +END +DB_result.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/database/DB_result.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/database/index.html +END +DB.php +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/!svn/ver/18/trunk/system/database/DB.php +END +DB_forge.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/database/DB_forge.php +END +DB_utility.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/database/DB_utility.php +END +DB_cache.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/database/DB_cache.php +END diff --git a/system/database/.svn/entries b/system/database/.svn/entries new file mode 100644 index 0000000..d1100dc --- /dev/null +++ b/system/database/.svn/entries @@ -0,0 +1,303 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +DB_active_rec.php +file + + + + +2009-09-15T00:18:12.000000Z +b97c0a58f575ac4b7e9b0c2231c63495 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +37746 + +DB_driver.php +file + + + + +2009-09-15T00:18:12.000000Z +55c956490502d6b6d29d84b235161430 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +26183 + +DB_result.php +file + + + + +2009-09-15T00:18:12.000000Z +2b5ad33038af076b66ab926c4b5b3681 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7680 + +index.html +file + + + + +2009-09-15T00:18:12.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +DB.php +file + + + + +2009-09-15T00:18:12.000000Z +19444e375528319537ace1defee86523 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3362 + +DB_forge.php +file + + + + +2009-09-15T00:18:12.000000Z +120d33d09edfebd7f24c92ff7d3b55f1 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +6835 + +drivers +dir + +DB_utility.php +file + + + + +2009-09-15T00:18:12.000000Z +61562f8ee290f310ac9807fbdc3316be +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9560 + +DB_cache.php +file + + + + +2009-09-15T00:18:12.000000Z +2a0862afd5a08091a9d717bb4edad6da +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4326 + diff --git a/system/database/.svn/prop-base/DB.php.svn-base b/system/database/.svn/prop-base/DB.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_active_rec.php.svn-base b/system/database/.svn/prop-base/DB_active_rec.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_active_rec.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_cache.php.svn-base b/system/database/.svn/prop-base/DB_cache.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_cache.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_driver.php.svn-base b/system/database/.svn/prop-base/DB_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_forge.php.svn-base b/system/database/.svn/prop-base/DB_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_result.php.svn-base b/system/database/.svn/prop-base/DB_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/DB_utility.php.svn-base b/system/database/.svn/prop-base/DB_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/DB_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/prop-base/index.html.svn-base b/system/database/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/.svn/text-base/DB.php.svn-base b/system/database/.svn/text-base/DB.php.svn-base new file mode 100644 index 0000000..c3e7722 --- /dev/null +++ b/system/database/.svn/text-base/DB.php.svn-base @@ -0,0 +1,123 @@ + $dns['scheme'], + 'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '', + 'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '', + 'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '', + 'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['host'], 1)) : '' + ); + } + + // No DB specified yet? Beat them senseless... + if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '') + { + show_error('You have not selected a database type to connect to.'); + } + + // Load the DB classes. Note: Since the active record class is optional + // we need to dynamically create a class that extends proper parent class + // based on whether we're using the active record class or not. + // Kudos to Paul for discovering this clever use of eval() + + if ($active_record_override == TRUE) + { + $active_record = TRUE; + } + + require_once(BASEPATH.'database/DB_driver'.EXT); + + if (! isset($active_record) OR $active_record == TRUE) + { + require_once(BASEPATH.'database/DB_active_rec'.EXT); + + if ( ! class_exists('CI_DB')) + { + eval('class CI_DB extends CI_DB_active_record { }'); + } + } + else + { + if ( ! class_exists('CI_DB')) + { + eval('class CI_DB extends CI_DB_driver { }'); + } + } + + require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT); + + // Instantiate the DB adapter + $driver = 'CI_DB_'.$params['dbdriver'].'_driver'; + $DB =& new $driver($params); + + if ($DB->autoinit == TRUE) + { + $DB->initialize(); + } + + return $DB; +} + + +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_active_rec.php.svn-base b/system/database/.svn/text-base/DB_active_rec.php.svn-base new file mode 100644 index 0000000..263172a --- /dev/null +++ b/system/database/.svn/text-base/DB_active_rec.php.svn-base @@ -0,0 +1,1733 @@ +display_error('db_table_name_required'); + } + + return $this->dbprefix.$table; + } + + // -------------------------------------------------------------------- + + /** + * Select + * + * Generates the SELECT portion of the query + * + * @access public + * @param string + * @return object + */ + function select($select = '*', $protect_identifiers = TRUE) + { + if (is_string($select)) + { + $select = explode(',', $select); + } + + foreach ($select as $val) + { + $val = trim($val); + + if ($val != '*' && $protect_identifiers !== FALSE) + { + if (strpos($val, '.') !== FALSE) + { + $val = $this->dbprefix.$val; + } + else + { + $val = $this->_protect_identifiers($val); + } + } + + if ($val != '') + { + $this->ar_select[] = $val; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $val; + } + } + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Max + * + * Generates a SELECT MAX(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_max($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'MAX('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Min + * + * Generates a SELECT MIN(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_min($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'MIN('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Average + * + * Generates a SELECT AVG(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_avg($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'AVG('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Sum + * + * Generates a SELECT SUM(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_sum($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'SUM('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * DISTINCT + * + * Sets a flag which tells the query string compiler to add DISTINCT + * + * @access public + * @param bool + * @return object + */ + function distinct($val = TRUE) + { + $this->ar_distinct = (is_bool($val)) ? $val : TRUE; + return $this; + } + + // -------------------------------------------------------------------- + + /** + * From + * + * Generates the FROM portion of the query + * + * @access public + * @param mixed can be a string or array + * @return object + */ + function from($from) + { + foreach ((array)$from as $val) + { + $this->ar_from[] = $this->_protect_identifiers($this->_track_aliases($val)); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_from[] = $this->_protect_identifiers($val); + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Join + * + * Generates the JOIN portion of the query + * + * @access public + * @param string + * @param string the join condition + * @param string the type of join + * @return object + */ + function join($table, $cond, $type = '') + { + if ($type != '') + { + $type = strtoupper(trim($type)); + + if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) + { + $type = ''; + } + else + { + $type .= ' '; + } + } + + // If a DB prefix is used we might need to add it to the column names + if ($this->dbprefix) + { + $this->_track_aliases($table); + + // First we remove any existing prefixes in the condition to avoid duplicates + $cond = preg_replace('|('.$this->dbprefix.')([\w\.]+)([\W\s]+)|', "$2$3", $cond); + + // Next we add the prefixes to the condition + $cond = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $cond); + } + + $join = $type.'JOIN '.$this->_protect_identifiers($this->dbprefix.$table, TRUE).' ON '.$cond; + + $this->ar_join[] = $join; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_join[] = $join; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Where + * + * Generates the WHERE portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function where($key, $value = NULL, $escape = TRUE) + { + return $this->_where($key, $value, 'AND ', $escape); + } + + // -------------------------------------------------------------------- + + /** + * OR Where + * + * Generates the WHERE portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_where($key, $value = NULL, $escape = TRUE) + { + return $this->_where($key, $value, 'OR ', $escape); + } + + // -------------------------------------------------------------------- + + /** + * orwhere() is an alias of or_where() + * this function is here for backwards compatibility, as + * orwhere() has been deprecated + */ + function orwhere($key, $value = NULL, $escape = TRUE) + { + return $this->or_where($key, $value, $escape); + } + + // -------------------------------------------------------------------- + + /** + * Where + * + * Called by where() or orwhere() + * + * @access private + * @param mixed + * @param mixed + * @param string + * @return object + */ + function _where($key, $value = NULL, $type = 'AND ', $escape = TRUE) + { + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_where) == 0) ? '' : $type; + + if ( ! $this->_has_operator($k) && is_null($key[$k])) + { + // value appears not to have been set, assign the test to IS NULL + $k .= ' IS NULL'; + } + + if ( ! is_null($v)) + { + + if ($escape === TRUE) + { + // exception for "field<=" keys + if ($this->_has_operator($k)) + { + $k = preg_replace("/([A-Za-z_0-9]+)/", $this->_protect_identifiers('$1'), $k); + } + else + { + $k = $this->_protect_identifiers($k); + } + } + + if ( ! $this->_has_operator($k)) + { + $k .= ' ='; + } + + $v = ' '.$this->escape($v); + } + else + { + $k = $this->_protect_identifiers($k, TRUE); + } + + $this->ar_where[] = $prefix.$k.$v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_where[] = $prefix.$k.$v; + } + + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Where_in + * + * Generates a WHERE field IN ('item', 'item') SQL query joined with + * AND if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function where_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values); + } + + // -------------------------------------------------------------------- + + /** + * Where_in_or + * + * Generates a WHERE field IN ('item', 'item') SQL query joined with + * OR if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function or_where_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, FALSE, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Where_not_in + * + * Generates a WHERE field NOT IN ('item', 'item') SQL query joined + * with AND if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function where_not_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Where_not_in_or + * + * Generates a WHERE field NOT IN ('item', 'item') SQL query joined + * with OR if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function or_where_not_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, FALSE, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Where_in + * + * Called by where_in, where_in_or, where_not_in, where_not_in_or + * + * @access public + * @param string The field to search + * @param array The values searched on + * @param boolean If the statement whould be IN or NOT IN + * @param string + * @return object + */ + function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ') + { + if ($key === NULL || !is_array($values)) + { + return; + } + + $not = ($not) ? ' NOT ' : ''; + + foreach ($values as $value) + { + $this->ar_wherein[] = $this->escape($value); + } + + $prefix = (count($this->ar_where) == 0) ? '' : $type; + + $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") "; + + $this->ar_where[] = $where_in; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_where[] = $where_in; + } + + // reset the array for multiple calls + $this->ar_wherein = array(); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Like + * + * Generates a %LIKE% portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'AND ', $side); + } + + // -------------------------------------------------------------------- + + /** + * Not Like + * + * Generates a NOT LIKE portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function not_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'AND ', $side, ' NOT'); + } + + // -------------------------------------------------------------------- + + /** + * OR Like + * + * Generates a %LIKE% portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'OR ', $side); + } + + // -------------------------------------------------------------------- + + /** + * OR Not Like + * + * Generates a NOT LIKE portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_not_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'OR ', $side, 'NOT '); + } + + // -------------------------------------------------------------------- + + /** + * orlike() is an alias of or_like() + * this function is here for backwards compatibility, as + * orlike() has been deprecated + */ + function orlike($field, $match = '', $side = 'both') + { + return $this->or_like($field, $match, $side); + } + + // -------------------------------------------------------------------- + + /** + * Like + * + * Called by like() or orlike() + * + * @access private + * @param mixed + * @param mixed + * @param string + * @return object + */ + function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '') + { + if ( ! is_array($field)) + { + $field = array($field => $match); + } + + foreach ($field as $k => $v) + { + + $k = $this->_protect_identifiers($k); + + $prefix = (count($this->ar_like) == 0) ? '' : $type; + + $v = $this->escape_str($v); + + if ($side == 'before') + { + $like_statement = $prefix." $k $not LIKE '%{$v}'"; + } + elseif ($side == 'after') + { + $like_statement = $prefix." $k $not LIKE '{$v}%'"; + } + else + { + $like_statement = $prefix." $k $not LIKE '%{$v}%'"; + } + + $this->ar_like[] = $like_statement; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_like[] = $like_statement; + } + + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * GROUP BY + * + * @access public + * @param string + * @return object + */ + function group_by($by) + { + if (is_string($by)) + { + $by = explode(',', $by); + } + + foreach ($by as $val) + { + $val = trim($val); + + if ($val != '') + { + $this->ar_groupby[] = $this->_protect_identifiers($val); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_groupby[] = $this->_protect_identifiers($val); + } + } + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * groupby() is an alias of group_by() + * this function is here for backwards compatibility, as + * groupby() has been deprecated + */ + function groupby($by) + { + return $this->group_by($by); + } + + // -------------------------------------------------------------------- + + /** + * Sets the HAVING value + * + * Separates multiple calls with AND + * + * @access public + * @param string + * @param string + * @return object + */ + function having($key, $value = '') + { + return $this->_having($key, $value, 'AND '); + } + + // -------------------------------------------------------------------- + + /** + * Sets the OR HAVING value + * + * Separates multiple calls with OR + * + * @access public + * @param string + * @param string + * @return object + */ + function orhaving($key, $value = '') + { + return $this->_having($key, $value, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Sets the HAVING values + * + * Called by having() or orhaving() + * + * @access private + * @param string + + * @param string + * @return object + */ + function _having($key, $value = '', $type = 'AND ') + { + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_having) == 0) ? '' : $type; + $k = $this->_protect_identifiers($k); + + if ($v != '') + { + $v = ' '.$this->escape_str($v); + } + + $this->ar_having[] = $prefix.$k.$v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_having[] = $prefix.$k.$v; + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Sets the ORDER BY value + * + * @access public + * @param string + * @param string direction: asc or desc + * @return object + */ + function order_by($orderby, $direction = '') + { + if (strtolower($direction) == 'random') + { + $orderby = ''; // Random results want or don't need a field name + $direction = $this->_random_keyword; + } + elseif (trim($direction) != '') + { + $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC'; + } + + $orderby_statement = $this->_protect_identifiers($orderby, TRUE).$direction; + + $this->ar_orderby[] = $orderby_statement; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_orderby[] = $orderby_statement; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * orderby() is an alias of order_by() + * this function is here for backwards compatibility, as + * orderby() has been deprecated + */ + function orderby($orderby, $direction = '') + { + return $this->order_by($orderby, $direction); + } + + // -------------------------------------------------------------------- + + /** + * Sets the LIMIT value + * + * @access public + * @param integer the limit value + * @param integer the offset value + * @return object + */ + function limit($value, $offset = '') + { + $this->ar_limit = $value; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_limit[] = $value; + } + + if ($offset != '') + { + $this->ar_offset = $offset; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[] = $offset; + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Sets the OFFSET value + * + * @access public + * @param integer the offset value + * @return object + */ + function offset($offset) + { + $this->ar_offset = $offset; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[] = $offset; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * The "set" function. Allows key/value pairs to be set for inserting or updating + * + * @access public + * @param mixed + * @param string + * @param boolean + * @return object + */ + function set($key, $value = '', $escape = TRUE) + { + $key = $this->_object_to_array($key); + + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + if ($escape === FALSE) + { + $this->ar_set[$this->_protect_identifiers($k)] = $v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[$this->_protect_identifiers($k)] = $v; + } + } + else + { + $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[$this->_protect_identifiers($k)] = $this->escape($v); + } + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get + * + * Compiles the select statement based on the other functions called + * and runs the query + * + * @access public + * @param string the table + * @param string the limit clause + * @param string the offset clause + * @return object + */ + function get($table = '', $limit = null, $offset = null) + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->_compile_select(); + + $result = $this->query($sql); + $this->_reset_select(); + return $result; + } + + /** + * "Count All Results" query + * + * Generates a platform-specific query string that counts all records + * returned by an Active Record query. + * + * @access public + * @param string + * @return string + */ + function count_all_results($table = '') + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows')); + + $query = $this->query($sql); + $this->_reset_select(); + + if ($query->num_rows() == 0) + { + return '0'; + } + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Get_Where + * + * Allows the where clause, limit and offset to be added directly + * + * @access public + * @param string the where clause + * @param string the limit clause + * @param string the offset clause + * @return object + */ + function get_where($table = '', $where = null, $limit = null, $offset = null) + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + if ( ! is_null($where)) + { + $this->where($where); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->_compile_select(); + + $result = $this->query($sql); + $this->_reset_select(); + return $result; + } + + // -------------------------------------------------------------------- + + /** + * getwhere() is an alias of get_where() + * this function is here for backwards compatibility, as + * getwhere() has been deprecated + */ + function getwhere($table = '', $where = null, $limit = null, $offset = null) + { + return $this->get_where($table, $where, $limit, $offset); + } + + // -------------------------------------------------------------------- + + /** + * Insert + * + * Compiles an insert string and runs the query + * + * @access public + * @param string the table to retrieve the results from + * @param array an associative array of insert values + * @return object + */ + function insert($table = '', $set = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_must_use_set'); + } + return FALSE; + } + + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + + $sql = $this->_insert($this->_protect_identifiers($this->dbprefix.$table), array_keys($this->ar_set), array_values($this->ar_set)); + + $this->_reset_write(); + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Update + * + * Compiles an update string and runs the query + * + * @access public + * @param string the table to retrieve the results from + * @param array an associative array of update values + * @param mixed the where clause + * @return object + */ + function update($table = '', $set = NULL, $where = NULL, $limit = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_must_use_set'); + } + return FALSE; + } + + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + + if ($where != NULL) + { + $this->where($where); + } + + if ($limit != NULL) + { + $this->limit($limit); + } + + $sql = $this->_update($this->_protect_identifiers($this->dbprefix.$table), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit); + + $this->_reset_write(); + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Empty Table + * + * Compiles a delete string and runs "DELETE FROM table" + * + * @access public + * @param string the table to empty + * @return object + */ + function empty_table($table = '') + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + + $sql = $this->_delete($table); + + $this->_reset_write(); + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Truncate + * + * Compiles a truncate string and runs the query + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table to truncate + * @return object + */ + function truncate($table = '') + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + + $sql = $this->_truncate($table); + + $this->_reset_write(); + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Delete + * + * Compiles a delete string and runs the query + * + * @access public + * @param mixed the table(s) to delete from. String or array + * @param mixed the where clause + * @param mixed the limit clause + * @param boolean + * @return object + */ + function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + elseif (is_array($table)) + { + foreach($table as $single_table) + { + $this->delete($single_table, $where, $limit, FALSE); + } + + $this->_reset_write(); + return; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + if ($where != '') + { + $this->where($where); + } + + if ($limit != NULL) + { + $this->limit($limit); + } + + if (count($this->ar_where) == 0 && count($this->ar_like) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_del_must_use_where'); + } + + return FALSE; + } + + $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit); + + if ($reset_data) + { + $this->_reset_write(); + } + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Use Table - DEPRECATED + * + * @deprecated use $this->db->from instead + */ + function use_table($table) + { + return $this->from($table); + } + + // -------------------------------------------------------------------- + + /** + * Tests whether the string has an SQL operator + * + * @access private + * @param string + * @return bool + */ + function _has_operator($str) + { + $str = trim($str); + if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str)) + { + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Track Aliases + * + * Used to track SQL statements written with aliased tables. + * + * @access private + * @param string The table to inspect + * @return string + */ + function _track_aliases($table) + { + // if a table alias is used we can recognize it by a space + if (strpos($table, " ") !== FALSE) + { + // if the alias is written with the AS keyowrd, get it out + $table = preg_replace('/ AS /i', ' ', $table); + + $this->ar_aliased_tables[] = trim(strrchr($table, " ")); + } + + return $this->dbprefix.$table; + } + + // -------------------------------------------------------------------- + + /** + * Filter Table Aliases + * + * Intelligently removes database prefixes from aliased tables + * + * @access private + * @param array An array of compiled SQL + * @return array Cleaned up statement with aliases accounted for + */ + function _filter_table_aliases($statements) + { + foreach ($statements as $k => $v) + { + foreach ($this->ar_aliased_tables as $table) + { + $statement = preg_replace('/(\w+\.\w+)/', $this->_protect_identifiers('$0'), $v); // makes `table.field` + $statement = str_replace(array($this->dbprefix.$table, '.'), array($table, $this->_protect_identifiers('.')), $statement); + } + + $statements[$k] = $statement; + } + + return $statements; + } + + // -------------------------------------------------------------------- + + /** + * Compile the SELECT statement + * + * Generates a query string based on which functions were used. + * Should not be called directly. The get() function calls it. + * + * @access private + * @return string + */ + function _compile_select($select_override = FALSE) + { + $this->_merge_cache(); + + $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT '; + + $sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select); + + if ($select_override !== FALSE) + { + $sql = $select_override; + } + + if (count($this->ar_from) > 0) + { + $sql .= "\nFROM "; + $sql .= $this->_from_tables($this->ar_from); + } + + if (count($this->ar_join) > 0) + { + $sql .= "\n"; + + // special consideration for table aliases + if (count($this->ar_aliased_tables) > 0 && $this->dbprefix) + { + $sql .= implode("\n", $this->_filter_table_aliases($this->ar_join)); + } + else + { + $sql .= implode("\n", $this->ar_join); + } + + } + + if (count($this->ar_where) > 0 OR count($this->ar_like) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $this->ar_where); + + if (count($this->ar_like) > 0) + { + if (count($this->ar_where) > 0) + { + $sql .= " AND "; + } + + $sql .= implode("\n", $this->ar_like); + } + + if (count($this->ar_groupby) > 0) + { + + $sql .= "\nGROUP BY "; + + // special consideration for table aliases + if (count($this->ar_aliased_tables) > 0 && $this->dbprefix) + { + $sql .= implode(", ", $this->_filter_table_aliases($this->ar_groupby)); + } + else + { + $sql .= implode(', ', $this->ar_groupby); + } + } + + if (count($this->ar_having) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $this->ar_having); + } + + if (count($this->ar_orderby) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $this->ar_orderby); + + if ($this->ar_order !== FALSE) + { + $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC'; + } + } + + if (is_numeric($this->ar_limit)) + { + $sql .= "\n"; + $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset); + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @access public + * @param object + * @return array + */ + function _object_to_array($object) + { + if ( ! is_object($object)) + { + return $object; + } + + $array = array(); + foreach (get_object_vars($object) as $key => $val) + { + // There are some built in keys we need to ignore for this conversion + if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table') + + { + $array[$key] = $val; + } + } + + return $array; + } + + // -------------------------------------------------------------------- + + /** + * Start Cache + * + * Starts AR caching + * + * @access public + * @return void + */ + function start_cache() + { + $this->ar_caching = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Stop Cache + * + * Stops AR caching + * + * @access public + * @return void + */ + function stop_cache() + { + $this->ar_caching = FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Flush Cache + * + * Empties the AR cache + * + * @access public + * @return void + */ + function flush_cache() + { + $ar_reset_items = array( + 'ar_cache_select' => array(), + 'ar_cache_from' => array(), + 'ar_cache_join' => array(), + 'ar_cache_where' => array(), + 'ar_cache_like' => array(), + 'ar_cache_groupby' => array(), + 'ar_cache_having' =>array(), + 'ar_cache_orderby' => array(), + 'ar_cache_set' => array() + ); + + $this->_reset_run($ar_reset_items); + } + + // -------------------------------------------------------------------- + + /** + * Merge Cache + * + * When called, this function merges any cached AR arrays with + * locally called ones. + * + * @access private + * @return void + */ + function _merge_cache() + { + $ar_items = array('select', 'from', 'join', 'where', 'like', 'groupby', 'having', 'orderby', 'set'); + + foreach ($ar_items as $ar_item) + { + $ar_cache_item = 'ar_cache_'.$ar_item; + $ar_item = 'ar_'.$ar_item; + $this->$ar_item = array_unique(array_merge($this->$ar_item, $this->$ar_cache_item)); + } + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record values. Called by the get() function + * + * @access private + * @param array An array of fields to reset + * @return void + */ + function _reset_run($ar_reset_items) + { + foreach ($ar_reset_items as $item => $default_value) + { + if (!in_array($item, $this->ar_store_array)) + { + $this->$item = $default_value; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record values. Called by the get() function + * + * @access private + * @return void + */ + function _reset_select() + { + $ar_reset_items = array( + 'ar_select' => array(), + 'ar_from' => array(), + 'ar_join' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_groupby' => array(), + 'ar_having' => array(), + 'ar_orderby' => array(), + 'ar_wherein' => array(), + 'ar_aliased_tables' => array(), + 'ar_distinct' => FALSE, + 'ar_limit' => FALSE, + 'ar_offset' => FALSE, + 'ar_order' => FALSE, + ); + + $this->_reset_run($ar_reset_items); + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record "write" values. + * + * Called by the insert() update() and delete() functions + * + * @access private + * @return void + */ + function _reset_write() + { + $ar_reset_items = array( + 'ar_set' => array(), + 'ar_from' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_orderby' => array(), + 'ar_limit' => FALSE, + 'ar_order' => FALSE + ); + + $this->_reset_run($ar_reset_items); + } + +} +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_cache.php.svn-base b/system/database/.svn/text-base/DB_cache.php.svn-base new file mode 100644 index 0000000..ad54fc3 --- /dev/null +++ b/system/database/.svn/text-base/DB_cache.php.svn-base @@ -0,0 +1,189 @@ +CI + // and load the file helper since we use it a lot + $this->CI =& get_instance(); + $this->CI->load->helper('file'); + } + + // -------------------------------------------------------------------- + + /** + * Set Cache Directory Path + * + * @access public + * @param string the path to the cache directory + * @return bool + */ + function check_path($path = '') + { + if ($path == '') + { + if ($this->CI->db->cachedir == '') + { + return $this->CI->db->cache_off(); + } + + $path = $this->CI->db->cachedir; + } + + // Add a trailing slash to the path if needed + $path = preg_replace("/(.+?)\/*$/", "\\1/", $path); + + if ( ! is_dir($path) OR ! is_really_writable($path)) + { + // If the path is wrong we'll turn off caching + return $this->CI->db->cache_off(); + } + + $this->CI->db->cachedir = $path; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Retrieve a cached query + * + * The URI being requested will become the name of the cache sub-folder. + * An MD5 hash of the SQL statement will become the cache file name + * + * @access public + * @return string + */ + function read($sql) + { + if ( ! $this->check_path()) + { + return $this->CI->db->cache_off(); + } + + $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+'; + $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + + $filepath = $uri.'/'.md5($sql); + + if (FALSE === ($cachedata = read_file($this->CI->db->cachedir.$filepath))) + { + return FALSE; + } + + return unserialize($cachedata); + } + + // -------------------------------------------------------------------- + + /** + * Write a query to a cache file + * + * @access public + * @return bool + */ + function write($sql, $object) + { + if ( ! $this->check_path()) + { + return $this->CI->db->cache_off(); + } + + $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+'; + $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + + $dir_path = $this->CI->db->cachedir.$uri.'/'; + + $filename = md5($sql); + + if ( ! @is_dir($dir_path)) + { + if ( ! @mkdir($dir_path, 0777)) + { + return FALSE; + } + + @chmod($dir_path, 0777); + } + + if (write_file($dir_path.$filename, serialize($object)) === FALSE) + { + return FALSE; + } + + @chmod($dir_path.$filename, 0777); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Delete cache files within a particular directory + * + * @access public + * @return bool + */ + function delete($segment_one = '', $segment_two = '') + { + if ($segment_one == '') + { + $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1); + } + + if ($segment_two == '') + { + $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + } + + $dir_path = $this->CI->db->cachedir.$segment_one.'+'.$segment_two.'/'; + + delete_files($dir_path, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Delete all existing cache files + * + * @access public + * @return bool + */ + function delete_all() + { + delete_files($this->CI->db->cachedir, TRUE); + } + +} + +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_driver.php.svn-base b/system/database/.svn/text-base/DB_driver.php.svn-base new file mode 100644 index 0000000..b101317 --- /dev/null +++ b/system/database/.svn/text-base/DB_driver.php.svn-base @@ -0,0 +1,1148 @@ + $val) + { + $this->$key = $val; + } + } + + log_message('debug', 'Database Driver Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Database Settings + * + * @access private Called by the constructor + * @param mixed + * @return void + */ + function initialize($create_db = FALSE) + { + // If an existing DB connection resource is supplied + // there is no need to connect and select the database + if (is_resource($this->conn_id)) + { + return TRUE; + } + + // Connect to the database + $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect(); + + // No connection? Throw an error + if ( ! $this->conn_id) + { + log_message('error', 'Unable to connect to the database'); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_connect'); + } + return FALSE; + } + + // Select the database + if ($this->database != '') + { + if ( ! $this->db_select()) + { + // Should we attempt to create the database? + if ($create_db == TRUE) + { + // Load the DB utility class + $CI =& get_instance(); + $CI->load->dbutil(); + + // Create the DB + if ( ! $CI->dbutil->create_database($this->database)) + { + log_message('error', 'Unable to create database: '.$this->database); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_create', $this->database); + } + return FALSE; + } + else + { + // In the event the DB was created we need to select it + if ($this->db_select()) + { + if (! $this->db_set_charset($this->char_set, $this->dbcollat)) + { + log_message('error', 'Unable to set database connection charset: '.$this->char_set); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_set_charset', $this->char_set); + } + + return FALSE; + } + + return TRUE; + } + } + } + + log_message('error', 'Unable to select database: '.$this->database); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_select', $this->database); + } + return FALSE; + } + + if (! $this->db_set_charset($this->char_set, $this->dbcollat)) + { + log_message('error', 'Unable to set database connection charset: '.$this->char_set); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_set_charset', $this->char_set); + } + + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * The name of the platform in use (mysql, mssql, etc...) + * + * @access public + * @return string + */ + function platform() + { + return $this->dbdriver; + } + + // -------------------------------------------------------------------- + + /** + * Database Version Number. Returns a string containing the + * version of the database being used + * + * @access public + * @return string + */ + function version() + { + if (FALSE === ($sql = $this->_version())) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + if ($this->dbdriver == 'oci8') + { + return $sql; + } + + $query = $this->query($sql); + return $query->row('ver'); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * Accepts an SQL string as input and returns a result object upon + * successful execution of a "read" type query. Returns boolean TRUE + * upon successful execution of a "write" type query. Returns boolean + * FALSE upon failure, and if the $db_debug variable is set to TRUE + * will raise an error. + * + * @access public + * @param string An SQL query string + * @param array An array of binding data + * @return mixed + */ + function query($sql, $binds = FALSE, $return_object = TRUE) + { + if ($sql == '') + { + if ($this->db_debug) + { + log_message('error', 'Invalid query: '.$sql); + return $this->display_error('db_invalid_query'); + } + return FALSE; + } + + // Verify table prefix and replace if necessary + if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) ) + { + $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql); + } + + // Is query caching enabled? If the query is a "read type" + // we will load the caching class and return the previously + // cached query if it exists + if ($this->cache_on == TRUE AND stristr($sql, 'SELECT')) + { + if ($this->_cache_init()) + { + $this->load_rdriver(); + if (FALSE !== ($cache = $this->CACHE->read($sql))) + { + return $cache; + } + } + } + + // Compile binds if needed + if ($binds !== FALSE) + { + $sql = $this->compile_binds($sql, $binds); + } + + // Save the query for debugging + if ($this->save_queries == TRUE) + { + $this->queries[] = $sql; + } + + // Start the Query Timer + $time_start = list($sm, $ss) = explode(' ', microtime()); + + // Run the Query + if (FALSE === ($this->result_id = $this->simple_query($sql))) + { + // This will trigger a rollback if transactions are being used + $this->_trans_status = FALSE; + + if ($this->db_debug) + { + log_message('error', 'Query error: '.$this->_error_message()); + return $this->display_error( + array( + 'Error Number: '.$this->_error_number(), + $this->_error_message(), + $sql + ) + ); + } + + return FALSE; + } + + // Stop and aggregate the query time results + $time_end = list($em, $es) = explode(' ', microtime()); + $this->benchmark += ($em + $es) - ($sm + $ss); + + if ($this->save_queries == TRUE) + { + $this->query_times[] = ($em + $es) - ($sm + $ss); + } + + // Increment the query counter + $this->query_count++; + + // Was the query a "write" type? + // If so we'll simply return true + if ($this->is_write_type($sql) === TRUE) + { + // If caching is enabled we'll auto-cleanup any + // existing files related to this particular URI + if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init()) + { + $this->CACHE->delete(); + } + + return TRUE; + } + + // Return TRUE if we don't need to create a result object + // Currently only the Oracle driver uses this when stored + // procedures are used + if ($return_object !== TRUE) + { + return TRUE; + } + + // Load and instantiate the result driver + + $driver = $this->load_rdriver(); + $RES = new $driver(); + $RES->conn_id = $this->conn_id; + $RES->result_id = $this->result_id; + $RES->num_rows = $RES->num_rows(); + + if ($this->dbdriver == 'oci8') + { + $RES->stmt_id = $this->stmt_id; + $RES->curs_id = NULL; + $RES->limit_used = $this->limit_used; + } + + // Is query caching enabled? If so, we'll serialize the + // result object and save it to a cache file. + if ($this->cache_on == TRUE AND $this->_cache_init()) + { + // We'll create a new instance of the result object + // only without the platform specific driver since + // we can't use it with cached data (the query result + // resource ID won't be any good once we've cached the + // result object, so we'll have to compile the data + // and save it) + $CR = new CI_DB_result(); + $CR->num_rows = $RES->num_rows(); + $CR->result_object = $RES->result_object(); + $CR->result_array = $RES->result_array(); + + // Reset these since cached objects can not utilize resource IDs. + $CR->conn_id = NULL; + $CR->result_id = NULL; + + $this->CACHE->write($sql, $CR); + } + + return $RES; + } + + // -------------------------------------------------------------------- + + /** + * Load the result drivers + * + * @access public + * @return string the name of the result class + */ + function load_rdriver() + { + $driver = 'CI_DB_'.$this->dbdriver.'_result'; + + if ( ! class_exists($driver)) + { + include_once(BASEPATH.'database/DB_result'.EXT); + include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT); + } + + return $driver; + } + + // -------------------------------------------------------------------- + + /** + * Simple Query + * This is a simplified version of the query() function. Internally + * we only use it when running transaction commands since they do + * not require all the features of the main query() function. + * + * @access public + * @param string the sql query + * @return mixed + */ + function simple_query($sql) + { + if ( ! $this->conn_id) + { + $this->initialize(); + } + + return $this->_execute($sql); + } + + // -------------------------------------------------------------------- + + /** + * Disable Transactions + * This permits transactions to be disabled at run-time. + * + * @access public + * @return void + */ + function trans_off() + { + $this->trans_enabled = FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Start Transaction + * + * @access public + * @return void + */ + function trans_start($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return FALSE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + $this->_trans_depth += 1; + return; + } + + $this->trans_begin($test_mode); + } + + // -------------------------------------------------------------------- + + /** + * Complete Transaction + * + * @access public + * @return bool + */ + function trans_complete() + { + if ( ! $this->trans_enabled) + { + return FALSE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 1) + { + $this->_trans_depth -= 1; + return TRUE; + } + + // The query() function will set this flag to TRUE in the event that a query failed + if ($this->_trans_status === FALSE) + { + $this->trans_rollback(); + + if ($this->db_debug) + { + return $this->display_error('db_transaction_failure'); + } + return FALSE; + } + + $this->trans_commit(); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Lets you retrieve the transaction flag to determine if it has failed + * + * @access public + * @return bool + */ + function trans_status() + { + return $this->_trans_status; + } + + // -------------------------------------------------------------------- + + /** + * Compile Bindings + * + * @access public + * @param string the sql statement + * @param array an array of bind data + * @return string + */ + function compile_binds($sql, $binds) + { + if (strpos($sql, $this->bind_marker) === FALSE) + { + return $sql; + } + + if ( ! is_array($binds)) + { + $binds = array($binds); + } + + // Get the sql segments around the bind markers + $segments = explode($this->bind_marker, $sql); + + // The count of bind should be 1 less then the count of segments + // If there are more bind arguments trim it down + if (count($binds) >= count($segments)) { + $binds = array_slice($binds, 0, count($segments)-1); + } + + // Construct the binded query + $result = $segments[0]; + $i = 0; + foreach ($binds as $bind) + { + $result .= $this->escape($bind); + $result .= $segments[++$i]; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Determines if a query is a "write" type. + * + * @access public + * @param string An SQL query string + * @return boolean + */ + function is_write_type($sql) + { + if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) + { + return FALSE; + } + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Calculate the aggregate query elapsed time + * + * @access public + * @param integer The number of decimal places + * @return integer + */ + function elapsed_time($decimals = 6) + { + return number_format($this->benchmark, $decimals); + } + + // -------------------------------------------------------------------- + + /** + * Returns the total number of queries + * + * @access public + * @return integer + */ + function total_queries() + { + return $this->query_count; + } + + // -------------------------------------------------------------------- + + /** + * Returns the last query that was executed + * + * @access public + * @return void + */ + function last_query() + { + return end($this->queries); + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function protect_identifiers($item, $first_word_only = FALSE) + { + return $this->_protect_identifiers($item, $first_word_only); + } + + // -------------------------------------------------------------------- + + /** + * "Smart" Escape String + * + * Escapes data based on type + * Sets boolean and null types + * + * @access public + * @param string + * @return integer + */ + function escape($str) + { + switch (gettype($str)) + { + case 'string' : $str = "'".$this->escape_str($str)."'"; + break; + case 'boolean' : $str = ($str === FALSE) ? 0 : 1; + break; + default : $str = ($str === NULL) ? 'NULL' : $str; + break; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Primary + * + * Retrieves the primary key. It assumes that the row in the first + * position is the primary key + * + * @access public + * @param string the table name + * @return string + */ + function primary($table = '') + { + $fields = $this->list_fields($table); + + if ( ! is_array($fields)) + { + return FALSE; + } + + return current($fields); + } + + // -------------------------------------------------------------------- + + /** + * Returns an array of table names + * + * @access public + * @return array + */ + function list_tables($constrain_by_prefix = FALSE) + { + // Is there a cached result? + if (isset($this->data_cache['table_names'])) + { + return $this->data_cache['table_names']; + } + + if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix))) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + $retval = array(); + $query = $this->query($sql); + + if ($query->num_rows() > 0) + { + foreach($query->result_array() as $row) + { + if (isset($row['TABLE_NAME'])) + { + $retval[] = $row['TABLE_NAME']; + } + else + { + $retval[] = array_shift($row); + } + } + } + + $this->data_cache['table_names'] = $retval; + return $this->data_cache['table_names']; + } + + // -------------------------------------------------------------------- + + /** + * Determine if a particular table exists + * @access public + * @return boolean + */ + function table_exists($table_name) + { + return ( ! in_array($this->prep_tablename($table_name), $this->list_tables())) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch MySQL Field Names + * + * @access public + * @param string the table name + * @return array + */ + function list_fields($table = '') + { + // Is there a cached result? + if (isset($this->data_cache['field_names'][$table])) + { + return $this->data_cache['field_names'][$table]; + } + + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('db_field_param_missing'); + } + return FALSE; + } + + if (FALSE === ($sql = $this->_list_columns($this->prep_tablename($table)))) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + $query = $this->query($sql); + + $retval = array(); + foreach($query->result_array() as $row) + { + if (isset($row['COLUMN_NAME'])) + { + $retval[] = $row['COLUMN_NAME']; + } + else + { + $retval[] = current($row); + } + } + + $this->data_cache['field_names'][$table] = $retval; + return $this->data_cache['field_names'][$table]; + } + + // -------------------------------------------------------------------- + + /** + * Determine if a particular field exists + * @access public + * @param string + * @param string + * @return boolean + */ + function field_exists($field_name, $table_name) + { + return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * DEPRECATED - use list_fields() + */ + function field_names($table = '') + { + return $this->list_fields($table); + } + + // -------------------------------------------------------------------- + + /** + * Returns an object with field data + * + * @access public + * @param string the table name + * @return object + */ + function field_data($table = '') + { + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('db_field_param_missing'); + } + return FALSE; + } + + $query = $this->query($this->_field_data($this->prep_tablename($table))); + return $query->field_data(); + } + + // -------------------------------------------------------------------- + + /** + * Generate an insert string + * + * @access public + * @param string the table upon which the query will be performed + * @param array an associative array data of key/values + * @return string + */ + function insert_string($table, $data) + { + $fields = array(); + $values = array(); + + foreach($data as $key => $val) + { + $fields[] = $key; + $values[] = $this->escape($val); + } + + + return $this->_insert($this->prep_tablename($table), $fields, $values); + } + + // -------------------------------------------------------------------- + + /** + * Generate an update string + * + * @access public + * @param string the table upon which the query will be performed + * @param array an associative array data of key/values + * @param mixed the "where" statement + * @return string + */ + function update_string($table, $data, $where) + { + if ($where == '') + return false; + + $fields = array(); + foreach($data as $key => $val) + { + $fields[$key] = $this->escape($val); + } + + if ( ! is_array($where)) + { + $dest = array($where); + } + else + { + $dest = array(); + foreach ($where as $key => $val) + { + $prefix = (count($dest) == 0) ? '' : ' AND '; + + if ($val !== '') + { + if ( ! $this->_has_operator($key)) + { + $key .= ' ='; + } + + $val = ' '.$this->escape($val); + } + + $dest[] = $prefix.$key.$val; + } + } + + return $this->_update($this->prep_tablename($table), $fields, $dest); + } + + // -------------------------------------------------------------------- + + /** + * Prep the table name - simply adds the table prefix if needed + * + * @access public + * @param string the table name + * @return string + */ + function prep_tablename($table = '') + { + // Do we need to add the table prefix? + if ($this->dbprefix != '') + { + if (substr($table, 0, strlen($this->dbprefix)) != $this->dbprefix) + { + $table = $this->dbprefix.$table; + } + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Enables a native PHP function to be run, using a platform agnostic wrapper. + * + * @access public + * @param string the function name + * @param mixed any parameters needed by the function + * @return mixed + */ + function call_function($function) + { + $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_'; + + if (FALSE === strpos($driver, $function)) + { + $function = $driver.$function; + } + + if ( ! function_exists($function)) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + else + { + $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null; + + return call_user_func_array($function, $args); + } + } + + // -------------------------------------------------------------------- + + /** + * Set Cache Directory Path + * + * @access public + * @param string the path to the cache directory + * @return void + */ + function cache_set_path($path = '') + { + $this->cachedir = $path; + } + + // -------------------------------------------------------------------- + + /** + * Enable Query Caching + * + * @access public + * @return void + */ + function cache_on() + { + $this->cache_on = TRUE; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Disable Query Caching + * + * @access public + * @return void + */ + function cache_off() + { + $this->cache_on = FALSE; + return FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Delete the cache files associated with a particular URI + * + * @access public + * @return void + */ + function cache_delete($segment_one = '', $segment_two = '') + { + if ( ! $this->_cache_init()) + { + return FALSE; + } + return $this->CACHE->delete($segment_one, $segment_two); + } + + // -------------------------------------------------------------------- + + /** + * Delete All cache files + * + * @access public + * @return void + */ + function cache_delete_all() + { + if ( ! $this->_cache_init()) + { + return FALSE; + } + + return $this->CACHE->delete_all(); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Cache Class + * + * @access private + * @return void + */ + function _cache_init() + { + if (is_object($this->CACHE) AND class_exists('CI_DB_Cache')) + { + return TRUE; + } + + if ( ! @include(BASEPATH.'database/DB_cache'.EXT)) + { + return $this->cache_off(); + } + + $this->CACHE = new CI_DB_Cache; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @return void + */ + function close() + { + if (is_resource($this->conn_id)) + { + $this->_close($this->conn_id); + } + $this->conn_id = FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Display an error message + * + * @access public + * @param string the error message + * @param string any "swap" values + * @param boolean whether to localize the message + * @return string sends the application/error_db.php template + */ + function display_error($error = '', $swap = '', $native = FALSE) + { +// $LANG = new CI_Lang(); + $LANG = new CI_Language(); + $LANG->load('db'); + + $heading = 'Database Error'; + + if ($native == TRUE) + { + $message = $error; + } + else + { + $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error; + } + + if ( ! class_exists('CI_Exceptions')) + { +// include(BASEPATH.'core/Exceptions'.EXT); + include(BASEPATH.'libraries/Exceptions'.EXT); + } + + $error = new CI_Exceptions(); + echo $error->show_error('An Error Was Encountered', $message, 'error_db'); + exit; + } + +} + +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_forge.php.svn-base b/system/database/.svn/text-base/DB_forge.php.svn-base new file mode 100644 index 0000000..cd468bc --- /dev/null +++ b/system/database/.svn/text-base/DB_forge.php.svn-base @@ -0,0 +1,322 @@ +db + $CI =& get_instance(); + $this->db =& $CI->db; + log_message('debug', "Database Forge Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function create_database($db_name) + { + $sql = $this->_create_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access public + * @param string the database name + * @return bool + */ + function drop_database($db_name) + { + $sql = $this->_drop_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Add Key + * + * @access public + * @param string key + * @param string type + * @return void + */ + function add_key($key = '', $primary = FALSE) + { + if ($key == '') + { + show_error('Key information is required for that operation.'); + } + + if ($primary === TRUE) + { + $this->primary_keys[] = $key; + } + else + { + $this->keys[] = $key; + } + } + + // -------------------------------------------------------------------- + + /** + * Add Field + * + * @access public + * @param string collation + * @return void + */ + function add_field($field = '') + { + if ($field == '') + { + show_error('Field information is required.'); + } + + if (is_string($field)) + { + if ($field == 'id') + { + $this->fields[] = array('id' => array( + 'type' => 'INT', + 'constraint' => 9, + 'auto_increment' => TRUE + ) + ); + $this->add_key('id', TRUE); + } + else + { + if (strpos($field, ' ') === FALSE) + { + show_error('Field information is required for that operation.'); + } + + $this->fields[] = $field; + } + } + + if (is_array($field)) + { + $this->fields = array_merge($this->fields, $field); + } + + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access public + * @param string the table name + * @return bool + */ + function create_table($table = '', $if_not_exists = FALSE) + { + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access public + * @param string the table name + * @return bool + */ + function drop_table($table_name) + { + $sql = $this->_drop_table($this->db->dbprefix.$table_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Add + * + * @access public + * @param string the table name + * @param string the column name + * @param string the column definition + * @return bool + */ + function add_column($table = '', $field = array(), $after_field = '') + { + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + // add field info into field array, but we can only do one at a time + // so only grab the first field in the event there are more then one + $this->add_field(array_slice($field, 0, 1)); + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Drop + * + * @access public + * @param string the table name + * @param string the column name + * @return bool + */ + function drop_column($table = '', $column_name = '') + { + + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + if ($column_name == '') + { + show_error('A column name is required for that operation.'); + } + + $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name); + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Modify + * + * @access public + * @param string the table name + * @param string the column name + * @param string the column definition + * @return bool + */ + function modify_column($table = '', $field = array()) + { + + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + // add field info into field array, but we can only do one at a time + // so only grab the first field in the event there are more then one + $this->add_field(array_slice($field, 0, 1)); + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Reset + * + * Resets table creation vars + * + * @access private + * @return void + */ + function _reset() + { + $this->fields = array(); + $this->keys = array(); + $this->primary_keys = array(); + } + +} +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_result.php.svn-base b/system/database/.svn/text-base/DB_result.php.svn-base new file mode 100644 index 0000000..7d50979 --- /dev/null +++ b/system/database/.svn/text-base/DB_result.php.svn-base @@ -0,0 +1,340 @@ +result_object() : $this->result_array(); + } + + // -------------------------------------------------------------------- + + /** + * Query result. "object" version. + * + * @access public + * @return object + */ + function result_object() + { + if (count($this->result_object) > 0) + { + return $this->result_object; + } + + // In the event that query caching is on the result_id variable + // will return FALSE since there isn't a valid SQL resource so + // we'll simply return an empty array. + if ($this->result_id === FALSE OR $this->num_rows() == 0) + { + return array(); + } + + $this->_data_seek(0); + while ($row = $this->_fetch_object()) + { + $this->result_object[] = $row; + } + + return $this->result_object; + } + + // -------------------------------------------------------------------- + + /** + * Query result. "array" version. + * + * @access public + * @return array + */ + function result_array() + { + if (count($this->result_array) > 0) + { + return $this->result_array; + } + + // In the event that query caching is on the result_id variable + // will return FALSE since there isn't a valid SQL resource so + // we'll simply return an empty array. + if ($this->result_id === FALSE OR $this->num_rows() == 0) + { + return array(); + } + + $this->_data_seek(0); + while ($row = $this->_fetch_assoc()) + { + $this->result_array[] = $row; + } + + return $this->result_array; + } + + // -------------------------------------------------------------------- + + /** + * Query result. Acts as a wrapper function for the following functions. + * + * @access public + * @param string + * @param string can be "object" or "array" + * @return mixed either a result object or array + */ + function row($n = 0, $type = 'object') + { + if ( ! is_numeric($n)) + { + // We cache the row data for subsequent uses + if ( ! is_array($this->row_data)) + { + $this->row_data = $this->row_array(0); + } + + if (isset($this->row_data[$n])) + { + return $this->row_data[$n]; + } + // reset the $n variable if the result was not achieved + $n = 0; + } + + return ($type == 'object') ? $this->row_object($n) : $this->row_array($n); + } + + // -------------------------------------------------------------------- + + /** + * Assigns an item into a particular column slot + * + * @access public + * @return object + */ + function set_row($key, $value = NULL) + { + // We cache the row data for subsequent uses + if ( ! is_array($this->row_data)) + { + $this->row_data = $this->row_array(0); + } + + if (is_array($key)) + { + foreach ($key as $k => $v) + { + $this->row_data[$k] = $v; + } + + return; + } + + if ($key != '' AND ! is_null($value)) + { + $this->row_data[$key] = $value; + } + } + + // -------------------------------------------------------------------- + + /** + * Returns a single result row - object version + * + * @access public + * @return object + */ + function row_object($n = 0) + { + $result = $this->result_object(); + + if (count($result) == 0) + { + return $result; + } + + if ($n != $this->current_row AND isset($result[$n])) + { + $this->current_row = $n; + } + + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * Returns a single result row - array version + * + * @access public + * @return array + */ + function row_array($n = 0) + { + $result = $this->result_array(); + + if (count($result) == 0) + { + return $result; + } + + if ($n != $this->current_row AND isset($result[$n])) + { + $this->current_row = $n; + } + + return $result[$this->current_row]; + } + + + // -------------------------------------------------------------------- + + /** + * Returns the "first" row + * + * @access public + * @return object + */ + function first_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + return $result[0]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "last" row + * + * @access public + * @return object + */ + function last_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + return $result[count($result) -1]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "next" row + * + * @access public + * @return object + */ + function next_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row + 1])) + { + ++$this->current_row; + } + + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "previous" row + * + * @access public + * @return object + */ + function previous_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row - 1])) + { + --$this->current_row; + } + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * The following functions are normally overloaded by the identically named + * methods in the platform-specific driver -- except when query caching + * is used. When caching is enabled we do not load the other driver. + * These functions are primarily here to prevent undefined function errors + * when a cached result object is in use. They are not otherwise fully + * operational due to the unavailability of the database resource IDs with + * cached results. + */ + function num_rows() { return $this->num_rows; } + function num_fields() { return 0; } + function list_fields() { return array(); } + function field_names() { return array(); } // Deprecated + function field_data() { return array(); } + function free_result() { return TRUE; } + function _data_seek() { return TRUE; } + function _fetch_assoc() { return array(); } + function _fetch_object() { return array(); } + +} +// END DB_result class +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/DB_utility.php.svn-base b/system/database/.svn/text-base/DB_utility.php.svn-base new file mode 100644 index 0000000..d9b8fed --- /dev/null +++ b/system/database/.svn/text-base/DB_utility.php.svn-base @@ -0,0 +1,387 @@ +db + $CI =& get_instance(); + $this->db =& $CI->db; + + log_message('debug', "Database Utility Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * List databases + * + * @access public + * @return bool + */ + function list_databases() + { + // Is there a cached result? + if (isset($this->data_cache['db_names'])) + { + return $this->data_cache['db_names']; + } + + $query = $this->db->query($this->_list_databases()); + $dbs = array(); + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $dbs[] = current($row); + } + } + + $this->data_cache['db_names'] = $dbs; + return $this->data_cache['db_names']; + } + + // -------------------------------------------------------------------- + + /** + * Optimize Table + * + * @access public + * @param string the table name + * @return bool + */ + function optimize_table($table_name) + { + $sql = $this->_optimize_table($table_name); + + if (is_bool($sql)) + { + show_error('db_must_use_set'); + } + + $query = $this->db->query($sql); + $res = $query->result_array(); + + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + return current($res); + } + + // -------------------------------------------------------------------- + + /** + * Optimize Database + * + * @access public + * @return array + */ + function optimize_database() + { + $result = array(); + foreach ($this->db->list_tables() as $table_name) + { + $sql = $this->_optimize_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + + // Build the result array... + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + $res = $query->result_array(); + $res = current($res); + $key = str_replace($this->db->database.'.', '', current($res)); + $keys = array_keys($res); + unset($res[$keys[0]]); + + $result[$key] = $res; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Repair Table + * + * @access public + * @param string the table name + * @return bool + */ + function repair_table($table_name) + { + $sql = $this->_repair_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + $res = $query->result_array(); + return current($res); + } + + // -------------------------------------------------------------------- + + /** + * Generate CSV from a query result object + * + * @access public + * @param object The query result object + * @param string The delimiter - comma by default + * @param string The newline character - \n by default + * @param string The enclosure - double quote by default + * @return string + */ + function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"') + { + if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + { + show_error('You must submit a valid result object'); + } + + $out = ''; + + // First generate the headings from the table column names + foreach ($query->list_fields() as $name) + { + $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim; + } + + $out = rtrim($out); + $out .= $newline; + + // Next blast through the result array and build out the rows + foreach ($query->result_array() as $row) + { + foreach ($row as $item) + { + $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim; + } + $out = rtrim($out); + $out .= $newline; + } + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Generate XML data from a query result object + * + * @access public + * @param object The query result object + * @param array Any preferences + * @return string + */ + function xml_from_result($query, $params = array()) + { + if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + { + show_error('You must submit a valid result object'); + } + + // Set our default values + foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val) + { + if ( ! isset($params[$key])) + { + $params[$key] = $val; + } + } + + // Create variables for convenience + extract($params); + + // Load the xml helper + $CI =& get_instance(); + $CI->load->helper('xml'); + + // Generate the result + $xml = "<{$root}>".$newline; + foreach ($query->result_array() as $row) + { + $xml .= $tab."<{$element}>".$newline; + + foreach ($row as $key => $val) + { + $xml .= $tab.$tab."<{$key}>".xml_convert($val)."".$newline; + } + $xml .= $tab."".$newline; + } + $xml .= "".$newline; + + return $xml; + } + + // -------------------------------------------------------------------- + + /** + * Database Backup + * + * @access public + * @return void + */ + function backup($params = array()) + { + // If the parameters have not been submitted as an + // array then we know that it is simply the table + // name, which is a valid short cut. + if (is_string($params)) + { + $params = array('tables' => $params); + } + + // ------------------------------------------------------ + + // Set up our default preferences + $prefs = array( + 'tables' => array(), + 'ignore' => array(), + 'filename' => '', + 'format' => 'gzip', // gzip, zip, txt + 'add_drop' => TRUE, + 'add_insert' => TRUE, + 'newline' => "\n" + ); + + // Did the user submit any preferences? If so set them.... + if (count($params) > 0) + { + foreach ($prefs as $key => $val) + { + if (isset($params[$key])) + { + $prefs[$key] = $params[$key]; + } + } + } + + // ------------------------------------------------------ + + // Are we backing up a complete database or individual tables? + // If no table names were submitted we'll fetch the entire table list + if (count($prefs['tables']) == 0) + { + $prefs['tables'] = $this->db->list_tables(); + } + + // ------------------------------------------------------ + + // Validate the format + if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE)) + { + $prefs['format'] = 'txt'; + } + + // ------------------------------------------------------ + + // Is the encoder supported? If not, we'll either issue an + // error or use plain text depending on the debug settings + if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode')) + OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress'))) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_compression'); + } + + $prefs['format'] = 'txt'; + } + + // ------------------------------------------------------ + + // Set the filename if not provided - Only needed with Zip files + if ($prefs['filename'] == '' AND $prefs['format'] == 'zip') + { + $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database; + $prefs['filename'] .= '_'.date('Y-m-d_H-i', time()); + } + + // ------------------------------------------------------ + + // Was a Gzip file requested? + if ($prefs['format'] == 'gzip') + { + return gzencode($this->_backup($prefs)); + } + + // ------------------------------------------------------ + + // Was a text file requested? + if ($prefs['format'] == 'txt') + { + return $this->_backup($prefs); + } + + // ------------------------------------------------------ + + // Was a Zip file requested? + if ($prefs['format'] == 'zip') + { + // If they included the .zip file extension we'll remove it + if (preg_match("|.+?\.zip$|", $prefs['filename'])) + { + $prefs['filename'] = str_replace('.zip', '', $prefs['filename']); + } + + // Tack on the ".sql" file extension if needed + if ( ! preg_match("|.+?\.sql$|", $prefs['filename'])) + { + $prefs['filename'] .= '.sql'; + } + + // Load the Zip class and output it + + $CI =& get_instance(); + $CI->load->library('zip'); + $CI->zip->add_data($prefs['filename'], $this->_backup($prefs)); + return $CI->zip->get_zip(); + } + + } + +} + +?> \ No newline at end of file diff --git a/system/database/.svn/text-base/index.html.svn-base b/system/database/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/DB.php b/system/database/DB.php new file mode 100755 index 0000000..c3e7722 --- /dev/null +++ b/system/database/DB.php @@ -0,0 +1,123 @@ + $dns['scheme'], + 'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '', + 'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '', + 'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '', + 'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['host'], 1)) : '' + ); + } + + // No DB specified yet? Beat them senseless... + if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '') + { + show_error('You have not selected a database type to connect to.'); + } + + // Load the DB classes. Note: Since the active record class is optional + // we need to dynamically create a class that extends proper parent class + // based on whether we're using the active record class or not. + // Kudos to Paul for discovering this clever use of eval() + + if ($active_record_override == TRUE) + { + $active_record = TRUE; + } + + require_once(BASEPATH.'database/DB_driver'.EXT); + + if (! isset($active_record) OR $active_record == TRUE) + { + require_once(BASEPATH.'database/DB_active_rec'.EXT); + + if ( ! class_exists('CI_DB')) + { + eval('class CI_DB extends CI_DB_active_record { }'); + } + } + else + { + if ( ! class_exists('CI_DB')) + { + eval('class CI_DB extends CI_DB_driver { }'); + } + } + + require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT); + + // Instantiate the DB adapter + $driver = 'CI_DB_'.$params['dbdriver'].'_driver'; + $DB =& new $driver($params); + + if ($DB->autoinit == TRUE) + { + $DB->initialize(); + } + + return $DB; +} + + +?> \ No newline at end of file diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php new file mode 100755 index 0000000..263172a --- /dev/null +++ b/system/database/DB_active_rec.php @@ -0,0 +1,1733 @@ +display_error('db_table_name_required'); + } + + return $this->dbprefix.$table; + } + + // -------------------------------------------------------------------- + + /** + * Select + * + * Generates the SELECT portion of the query + * + * @access public + * @param string + * @return object + */ + function select($select = '*', $protect_identifiers = TRUE) + { + if (is_string($select)) + { + $select = explode(',', $select); + } + + foreach ($select as $val) + { + $val = trim($val); + + if ($val != '*' && $protect_identifiers !== FALSE) + { + if (strpos($val, '.') !== FALSE) + { + $val = $this->dbprefix.$val; + } + else + { + $val = $this->_protect_identifiers($val); + } + } + + if ($val != '') + { + $this->ar_select[] = $val; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $val; + } + } + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Max + * + * Generates a SELECT MAX(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_max($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'MAX('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Min + * + * Generates a SELECT MIN(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_min($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'MIN('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Average + * + * Generates a SELECT AVG(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_avg($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'AVG('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Select Sum + * + * Generates a SELECT SUM(field) portion of a query + * + * @access public + * @param string the field + * @param string an alias + * @return object + */ + function select_sum($select = '', $alias='') + { + if (!is_string($select) || $select == '') + { + $this->display_error('db_invalid_query'); + } + + $alias = ($alias != '') ? $alias : $select; + + $sql = 'SUM('.$this->_protect_identifiers(trim($select)).') AS '.$this->_protect_identifiers(trim($alias)); + + $this->ar_select[] = $sql; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_select[] = $sql; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * DISTINCT + * + * Sets a flag which tells the query string compiler to add DISTINCT + * + * @access public + * @param bool + * @return object + */ + function distinct($val = TRUE) + { + $this->ar_distinct = (is_bool($val)) ? $val : TRUE; + return $this; + } + + // -------------------------------------------------------------------- + + /** + * From + * + * Generates the FROM portion of the query + * + * @access public + * @param mixed can be a string or array + * @return object + */ + function from($from) + { + foreach ((array)$from as $val) + { + $this->ar_from[] = $this->_protect_identifiers($this->_track_aliases($val)); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_from[] = $this->_protect_identifiers($val); + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Join + * + * Generates the JOIN portion of the query + * + * @access public + * @param string + * @param string the join condition + * @param string the type of join + * @return object + */ + function join($table, $cond, $type = '') + { + if ($type != '') + { + $type = strtoupper(trim($type)); + + if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) + { + $type = ''; + } + else + { + $type .= ' '; + } + } + + // If a DB prefix is used we might need to add it to the column names + if ($this->dbprefix) + { + $this->_track_aliases($table); + + // First we remove any existing prefixes in the condition to avoid duplicates + $cond = preg_replace('|('.$this->dbprefix.')([\w\.]+)([\W\s]+)|', "$2$3", $cond); + + // Next we add the prefixes to the condition + $cond = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $cond); + } + + $join = $type.'JOIN '.$this->_protect_identifiers($this->dbprefix.$table, TRUE).' ON '.$cond; + + $this->ar_join[] = $join; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_join[] = $join; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Where + * + * Generates the WHERE portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function where($key, $value = NULL, $escape = TRUE) + { + return $this->_where($key, $value, 'AND ', $escape); + } + + // -------------------------------------------------------------------- + + /** + * OR Where + * + * Generates the WHERE portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_where($key, $value = NULL, $escape = TRUE) + { + return $this->_where($key, $value, 'OR ', $escape); + } + + // -------------------------------------------------------------------- + + /** + * orwhere() is an alias of or_where() + * this function is here for backwards compatibility, as + * orwhere() has been deprecated + */ + function orwhere($key, $value = NULL, $escape = TRUE) + { + return $this->or_where($key, $value, $escape); + } + + // -------------------------------------------------------------------- + + /** + * Where + * + * Called by where() or orwhere() + * + * @access private + * @param mixed + * @param mixed + * @param string + * @return object + */ + function _where($key, $value = NULL, $type = 'AND ', $escape = TRUE) + { + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_where) == 0) ? '' : $type; + + if ( ! $this->_has_operator($k) && is_null($key[$k])) + { + // value appears not to have been set, assign the test to IS NULL + $k .= ' IS NULL'; + } + + if ( ! is_null($v)) + { + + if ($escape === TRUE) + { + // exception for "field<=" keys + if ($this->_has_operator($k)) + { + $k = preg_replace("/([A-Za-z_0-9]+)/", $this->_protect_identifiers('$1'), $k); + } + else + { + $k = $this->_protect_identifiers($k); + } + } + + if ( ! $this->_has_operator($k)) + { + $k .= ' ='; + } + + $v = ' '.$this->escape($v); + } + else + { + $k = $this->_protect_identifiers($k, TRUE); + } + + $this->ar_where[] = $prefix.$k.$v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_where[] = $prefix.$k.$v; + } + + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Where_in + * + * Generates a WHERE field IN ('item', 'item') SQL query joined with + * AND if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function where_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values); + } + + // -------------------------------------------------------------------- + + /** + * Where_in_or + * + * Generates a WHERE field IN ('item', 'item') SQL query joined with + * OR if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function or_where_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, FALSE, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Where_not_in + * + * Generates a WHERE field NOT IN ('item', 'item') SQL query joined + * with AND if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function where_not_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Where_not_in_or + * + * Generates a WHERE field NOT IN ('item', 'item') SQL query joined + * with OR if appropriate + * + * @access public + * @param string The field to search + * @param array The values searched on + + * @return object + */ + function or_where_not_in($key = NULL, $values = NULL) + { + return $this->_where_in($key, $values, FALSE, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Where_in + * + * Called by where_in, where_in_or, where_not_in, where_not_in_or + * + * @access public + * @param string The field to search + * @param array The values searched on + * @param boolean If the statement whould be IN or NOT IN + * @param string + * @return object + */ + function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ') + { + if ($key === NULL || !is_array($values)) + { + return; + } + + $not = ($not) ? ' NOT ' : ''; + + foreach ($values as $value) + { + $this->ar_wherein[] = $this->escape($value); + } + + $prefix = (count($this->ar_where) == 0) ? '' : $type; + + $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") "; + + $this->ar_where[] = $where_in; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_where[] = $where_in; + } + + // reset the array for multiple calls + $this->ar_wherein = array(); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Like + * + * Generates a %LIKE% portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'AND ', $side); + } + + // -------------------------------------------------------------------- + + /** + * Not Like + * + * Generates a NOT LIKE portion of the query. Separates + * multiple calls with AND + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function not_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'AND ', $side, ' NOT'); + } + + // -------------------------------------------------------------------- + + /** + * OR Like + * + * Generates a %LIKE% portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'OR ', $side); + } + + // -------------------------------------------------------------------- + + /** + * OR Not Like + * + * Generates a NOT LIKE portion of the query. Separates + * multiple calls with OR + * + * @access public + * @param mixed + * @param mixed + * @return object + */ + function or_not_like($field, $match = '', $side = 'both') + { + return $this->_like($field, $match, 'OR ', $side, 'NOT '); + } + + // -------------------------------------------------------------------- + + /** + * orlike() is an alias of or_like() + * this function is here for backwards compatibility, as + * orlike() has been deprecated + */ + function orlike($field, $match = '', $side = 'both') + { + return $this->or_like($field, $match, $side); + } + + // -------------------------------------------------------------------- + + /** + * Like + * + * Called by like() or orlike() + * + * @access private + * @param mixed + * @param mixed + * @param string + * @return object + */ + function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '') + { + if ( ! is_array($field)) + { + $field = array($field => $match); + } + + foreach ($field as $k => $v) + { + + $k = $this->_protect_identifiers($k); + + $prefix = (count($this->ar_like) == 0) ? '' : $type; + + $v = $this->escape_str($v); + + if ($side == 'before') + { + $like_statement = $prefix." $k $not LIKE '%{$v}'"; + } + elseif ($side == 'after') + { + $like_statement = $prefix." $k $not LIKE '{$v}%'"; + } + else + { + $like_statement = $prefix." $k $not LIKE '%{$v}%'"; + } + + $this->ar_like[] = $like_statement; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_like[] = $like_statement; + } + + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * GROUP BY + * + * @access public + * @param string + * @return object + */ + function group_by($by) + { + if (is_string($by)) + { + $by = explode(',', $by); + } + + foreach ($by as $val) + { + $val = trim($val); + + if ($val != '') + { + $this->ar_groupby[] = $this->_protect_identifiers($val); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_groupby[] = $this->_protect_identifiers($val); + } + } + } + return $this; + } + + // -------------------------------------------------------------------- + + /** + * groupby() is an alias of group_by() + * this function is here for backwards compatibility, as + * groupby() has been deprecated + */ + function groupby($by) + { + return $this->group_by($by); + } + + // -------------------------------------------------------------------- + + /** + * Sets the HAVING value + * + * Separates multiple calls with AND + * + * @access public + * @param string + * @param string + * @return object + */ + function having($key, $value = '') + { + return $this->_having($key, $value, 'AND '); + } + + // -------------------------------------------------------------------- + + /** + * Sets the OR HAVING value + * + * Separates multiple calls with OR + * + * @access public + * @param string + * @param string + * @return object + */ + function orhaving($key, $value = '') + { + return $this->_having($key, $value, 'OR '); + } + + // -------------------------------------------------------------------- + + /** + * Sets the HAVING values + * + * Called by having() or orhaving() + * + * @access private + * @param string + + * @param string + * @return object + */ + function _having($key, $value = '', $type = 'AND ') + { + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_having) == 0) ? '' : $type; + $k = $this->_protect_identifiers($k); + + if ($v != '') + { + $v = ' '.$this->escape_str($v); + } + + $this->ar_having[] = $prefix.$k.$v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_having[] = $prefix.$k.$v; + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Sets the ORDER BY value + * + * @access public + * @param string + * @param string direction: asc or desc + * @return object + */ + function order_by($orderby, $direction = '') + { + if (strtolower($direction) == 'random') + { + $orderby = ''; // Random results want or don't need a field name + $direction = $this->_random_keyword; + } + elseif (trim($direction) != '') + { + $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC'; + } + + $orderby_statement = $this->_protect_identifiers($orderby, TRUE).$direction; + + $this->ar_orderby[] = $orderby_statement; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_orderby[] = $orderby_statement; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * orderby() is an alias of order_by() + * this function is here for backwards compatibility, as + * orderby() has been deprecated + */ + function orderby($orderby, $direction = '') + { + return $this->order_by($orderby, $direction); + } + + // -------------------------------------------------------------------- + + /** + * Sets the LIMIT value + * + * @access public + * @param integer the limit value + * @param integer the offset value + * @return object + */ + function limit($value, $offset = '') + { + $this->ar_limit = $value; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_limit[] = $value; + } + + if ($offset != '') + { + $this->ar_offset = $offset; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[] = $offset; + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Sets the OFFSET value + * + * @access public + * @param integer the offset value + * @return object + */ + function offset($offset) + { + $this->ar_offset = $offset; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[] = $offset; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * The "set" function. Allows key/value pairs to be set for inserting or updating + * + * @access public + * @param mixed + * @param string + * @param boolean + * @return object + */ + function set($key, $value = '', $escape = TRUE) + { + $key = $this->_object_to_array($key); + + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + if ($escape === FALSE) + { + $this->ar_set[$this->_protect_identifiers($k)] = $v; + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[$this->_protect_identifiers($k)] = $v; + } + } + else + { + $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v); + if ($this->ar_caching === TRUE) + { + $this->ar_cache_offset[$this->_protect_identifiers($k)] = $this->escape($v); + } + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get + * + * Compiles the select statement based on the other functions called + * and runs the query + * + * @access public + * @param string the table + * @param string the limit clause + * @param string the offset clause + * @return object + */ + function get($table = '', $limit = null, $offset = null) + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->_compile_select(); + + $result = $this->query($sql); + $this->_reset_select(); + return $result; + } + + /** + * "Count All Results" query + * + * Generates a platform-specific query string that counts all records + * returned by an Active Record query. + * + * @access public + * @param string + * @return string + */ + function count_all_results($table = '') + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows')); + + $query = $this->query($sql); + $this->_reset_select(); + + if ($query->num_rows() == 0) + { + return '0'; + } + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Get_Where + * + * Allows the where clause, limit and offset to be added directly + * + * @access public + * @param string the where clause + * @param string the limit clause + * @param string the offset clause + * @return object + */ + function get_where($table = '', $where = null, $limit = null, $offset = null) + { + if ($table != '') + { + $this->_track_aliases($table); + $this->from($table); + } + + if ( ! is_null($where)) + { + $this->where($where); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->_compile_select(); + + $result = $this->query($sql); + $this->_reset_select(); + return $result; + } + + // -------------------------------------------------------------------- + + /** + * getwhere() is an alias of get_where() + * this function is here for backwards compatibility, as + * getwhere() has been deprecated + */ + function getwhere($table = '', $where = null, $limit = null, $offset = null) + { + return $this->get_where($table, $where, $limit, $offset); + } + + // -------------------------------------------------------------------- + + /** + * Insert + * + * Compiles an insert string and runs the query + * + * @access public + * @param string the table to retrieve the results from + * @param array an associative array of insert values + * @return object + */ + function insert($table = '', $set = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_must_use_set'); + } + return FALSE; + } + + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + + $sql = $this->_insert($this->_protect_identifiers($this->dbprefix.$table), array_keys($this->ar_set), array_values($this->ar_set)); + + $this->_reset_write(); + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Update + * + * Compiles an update string and runs the query + * + * @access public + * @param string the table to retrieve the results from + * @param array an associative array of update values + * @param mixed the where clause + * @return object + */ + function update($table = '', $set = NULL, $where = NULL, $limit = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_must_use_set'); + } + return FALSE; + } + + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + + if ($where != NULL) + { + $this->where($where); + } + + if ($limit != NULL) + { + $this->limit($limit); + } + + $sql = $this->_update($this->_protect_identifiers($this->dbprefix.$table), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit); + + $this->_reset_write(); + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Empty Table + * + * Compiles a delete string and runs "DELETE FROM table" + * + * @access public + * @param string the table to empty + * @return object + */ + function empty_table($table = '') + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + + $sql = $this->_delete($table); + + $this->_reset_write(); + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Truncate + * + * Compiles a truncate string and runs the query + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table to truncate + * @return object + */ + function truncate($table = '') + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + + $sql = $this->_truncate($table); + + $this->_reset_write(); + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Delete + * + * Compiles a delete string and runs the query + * + * @access public + * @param mixed the table(s) to delete from. String or array + * @param mixed the where clause + * @param mixed the limit clause + * @param boolean + * @return object + */ + function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) + { + if ($table == '') + { + if ( ! isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('db_must_set_table'); + } + return FALSE; + } + + $table = $this->ar_from[0]; + } + elseif (is_array($table)) + { + foreach($table as $single_table) + { + $this->delete($single_table, $where, $limit, FALSE); + } + + $this->_reset_write(); + return; + } + else + { + $table = $this->_protect_identifiers($this->dbprefix.$table); + } + + if ($where != '') + { + $this->where($where); + } + + if ($limit != NULL) + { + $this->limit($limit); + } + + if (count($this->ar_where) == 0 && count($this->ar_like) == 0) + { + if ($this->db_debug) + { + return $this->display_error('db_del_must_use_where'); + } + + return FALSE; + } + + $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit); + + if ($reset_data) + { + $this->_reset_write(); + } + + return $this->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Use Table - DEPRECATED + * + * @deprecated use $this->db->from instead + */ + function use_table($table) + { + return $this->from($table); + } + + // -------------------------------------------------------------------- + + /** + * Tests whether the string has an SQL operator + * + * @access private + * @param string + * @return bool + */ + function _has_operator($str) + { + $str = trim($str); + if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str)) + { + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Track Aliases + * + * Used to track SQL statements written with aliased tables. + * + * @access private + * @param string The table to inspect + * @return string + */ + function _track_aliases($table) + { + // if a table alias is used we can recognize it by a space + if (strpos($table, " ") !== FALSE) + { + // if the alias is written with the AS keyowrd, get it out + $table = preg_replace('/ AS /i', ' ', $table); + + $this->ar_aliased_tables[] = trim(strrchr($table, " ")); + } + + return $this->dbprefix.$table; + } + + // -------------------------------------------------------------------- + + /** + * Filter Table Aliases + * + * Intelligently removes database prefixes from aliased tables + * + * @access private + * @param array An array of compiled SQL + * @return array Cleaned up statement with aliases accounted for + */ + function _filter_table_aliases($statements) + { + foreach ($statements as $k => $v) + { + foreach ($this->ar_aliased_tables as $table) + { + $statement = preg_replace('/(\w+\.\w+)/', $this->_protect_identifiers('$0'), $v); // makes `table.field` + $statement = str_replace(array($this->dbprefix.$table, '.'), array($table, $this->_protect_identifiers('.')), $statement); + } + + $statements[$k] = $statement; + } + + return $statements; + } + + // -------------------------------------------------------------------- + + /** + * Compile the SELECT statement + * + * Generates a query string based on which functions were used. + * Should not be called directly. The get() function calls it. + * + * @access private + * @return string + */ + function _compile_select($select_override = FALSE) + { + $this->_merge_cache(); + + $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT '; + + $sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select); + + if ($select_override !== FALSE) + { + $sql = $select_override; + } + + if (count($this->ar_from) > 0) + { + $sql .= "\nFROM "; + $sql .= $this->_from_tables($this->ar_from); + } + + if (count($this->ar_join) > 0) + { + $sql .= "\n"; + + // special consideration for table aliases + if (count($this->ar_aliased_tables) > 0 && $this->dbprefix) + { + $sql .= implode("\n", $this->_filter_table_aliases($this->ar_join)); + } + else + { + $sql .= implode("\n", $this->ar_join); + } + + } + + if (count($this->ar_where) > 0 OR count($this->ar_like) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $this->ar_where); + + if (count($this->ar_like) > 0) + { + if (count($this->ar_where) > 0) + { + $sql .= " AND "; + } + + $sql .= implode("\n", $this->ar_like); + } + + if (count($this->ar_groupby) > 0) + { + + $sql .= "\nGROUP BY "; + + // special consideration for table aliases + if (count($this->ar_aliased_tables) > 0 && $this->dbprefix) + { + $sql .= implode(", ", $this->_filter_table_aliases($this->ar_groupby)); + } + else + { + $sql .= implode(', ', $this->ar_groupby); + } + } + + if (count($this->ar_having) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $this->ar_having); + } + + if (count($this->ar_orderby) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $this->ar_orderby); + + if ($this->ar_order !== FALSE) + { + $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC'; + } + } + + if (is_numeric($this->ar_limit)) + { + $sql .= "\n"; + $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset); + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @access public + * @param object + * @return array + */ + function _object_to_array($object) + { + if ( ! is_object($object)) + { + return $object; + } + + $array = array(); + foreach (get_object_vars($object) as $key => $val) + { + // There are some built in keys we need to ignore for this conversion + if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table') + + { + $array[$key] = $val; + } + } + + return $array; + } + + // -------------------------------------------------------------------- + + /** + * Start Cache + * + * Starts AR caching + * + * @access public + * @return void + */ + function start_cache() + { + $this->ar_caching = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Stop Cache + * + * Stops AR caching + * + * @access public + * @return void + */ + function stop_cache() + { + $this->ar_caching = FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Flush Cache + * + * Empties the AR cache + * + * @access public + * @return void + */ + function flush_cache() + { + $ar_reset_items = array( + 'ar_cache_select' => array(), + 'ar_cache_from' => array(), + 'ar_cache_join' => array(), + 'ar_cache_where' => array(), + 'ar_cache_like' => array(), + 'ar_cache_groupby' => array(), + 'ar_cache_having' =>array(), + 'ar_cache_orderby' => array(), + 'ar_cache_set' => array() + ); + + $this->_reset_run($ar_reset_items); + } + + // -------------------------------------------------------------------- + + /** + * Merge Cache + * + * When called, this function merges any cached AR arrays with + * locally called ones. + * + * @access private + * @return void + */ + function _merge_cache() + { + $ar_items = array('select', 'from', 'join', 'where', 'like', 'groupby', 'having', 'orderby', 'set'); + + foreach ($ar_items as $ar_item) + { + $ar_cache_item = 'ar_cache_'.$ar_item; + $ar_item = 'ar_'.$ar_item; + $this->$ar_item = array_unique(array_merge($this->$ar_item, $this->$ar_cache_item)); + } + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record values. Called by the get() function + * + * @access private + * @param array An array of fields to reset + * @return void + */ + function _reset_run($ar_reset_items) + { + foreach ($ar_reset_items as $item => $default_value) + { + if (!in_array($item, $this->ar_store_array)) + { + $this->$item = $default_value; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record values. Called by the get() function + * + * @access private + * @return void + */ + function _reset_select() + { + $ar_reset_items = array( + 'ar_select' => array(), + 'ar_from' => array(), + 'ar_join' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_groupby' => array(), + 'ar_having' => array(), + 'ar_orderby' => array(), + 'ar_wherein' => array(), + 'ar_aliased_tables' => array(), + 'ar_distinct' => FALSE, + 'ar_limit' => FALSE, + 'ar_offset' => FALSE, + 'ar_order' => FALSE, + ); + + $this->_reset_run($ar_reset_items); + } + + // -------------------------------------------------------------------- + + /** + * Resets the active record "write" values. + * + * Called by the insert() update() and delete() functions + * + * @access private + * @return void + */ + function _reset_write() + { + $ar_reset_items = array( + 'ar_set' => array(), + 'ar_from' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_orderby' => array(), + 'ar_limit' => FALSE, + 'ar_order' => FALSE + ); + + $this->_reset_run($ar_reset_items); + } + +} +?> \ No newline at end of file diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php new file mode 100755 index 0000000..ad54fc3 --- /dev/null +++ b/system/database/DB_cache.php @@ -0,0 +1,189 @@ +CI + // and load the file helper since we use it a lot + $this->CI =& get_instance(); + $this->CI->load->helper('file'); + } + + // -------------------------------------------------------------------- + + /** + * Set Cache Directory Path + * + * @access public + * @param string the path to the cache directory + * @return bool + */ + function check_path($path = '') + { + if ($path == '') + { + if ($this->CI->db->cachedir == '') + { + return $this->CI->db->cache_off(); + } + + $path = $this->CI->db->cachedir; + } + + // Add a trailing slash to the path if needed + $path = preg_replace("/(.+?)\/*$/", "\\1/", $path); + + if ( ! is_dir($path) OR ! is_really_writable($path)) + { + // If the path is wrong we'll turn off caching + return $this->CI->db->cache_off(); + } + + $this->CI->db->cachedir = $path; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Retrieve a cached query + * + * The URI being requested will become the name of the cache sub-folder. + * An MD5 hash of the SQL statement will become the cache file name + * + * @access public + * @return string + */ + function read($sql) + { + if ( ! $this->check_path()) + { + return $this->CI->db->cache_off(); + } + + $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+'; + $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + + $filepath = $uri.'/'.md5($sql); + + if (FALSE === ($cachedata = read_file($this->CI->db->cachedir.$filepath))) + { + return FALSE; + } + + return unserialize($cachedata); + } + + // -------------------------------------------------------------------- + + /** + * Write a query to a cache file + * + * @access public + * @return bool + */ + function write($sql, $object) + { + if ( ! $this->check_path()) + { + return $this->CI->db->cache_off(); + } + + $uri = ($this->CI->uri->segment(1) == FALSE) ? 'default.' : $this->CI->uri->segment(1).'+'; + $uri .= ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + + $dir_path = $this->CI->db->cachedir.$uri.'/'; + + $filename = md5($sql); + + if ( ! @is_dir($dir_path)) + { + if ( ! @mkdir($dir_path, 0777)) + { + return FALSE; + } + + @chmod($dir_path, 0777); + } + + if (write_file($dir_path.$filename, serialize($object)) === FALSE) + { + return FALSE; + } + + @chmod($dir_path.$filename, 0777); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Delete cache files within a particular directory + * + * @access public + * @return bool + */ + function delete($segment_one = '', $segment_two = '') + { + if ($segment_one == '') + { + $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1); + } + + if ($segment_two == '') + { + $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2); + } + + $dir_path = $this->CI->db->cachedir.$segment_one.'+'.$segment_two.'/'; + + delete_files($dir_path, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Delete all existing cache files + * + * @access public + * @return bool + */ + function delete_all() + { + delete_files($this->CI->db->cachedir, TRUE); + } + +} + +?> \ No newline at end of file diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php new file mode 100755 index 0000000..b101317 --- /dev/null +++ b/system/database/DB_driver.php @@ -0,0 +1,1148 @@ + $val) + { + $this->$key = $val; + } + } + + log_message('debug', 'Database Driver Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Database Settings + * + * @access private Called by the constructor + * @param mixed + * @return void + */ + function initialize($create_db = FALSE) + { + // If an existing DB connection resource is supplied + // there is no need to connect and select the database + if (is_resource($this->conn_id)) + { + return TRUE; + } + + // Connect to the database + $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect(); + + // No connection? Throw an error + if ( ! $this->conn_id) + { + log_message('error', 'Unable to connect to the database'); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_connect'); + } + return FALSE; + } + + // Select the database + if ($this->database != '') + { + if ( ! $this->db_select()) + { + // Should we attempt to create the database? + if ($create_db == TRUE) + { + // Load the DB utility class + $CI =& get_instance(); + $CI->load->dbutil(); + + // Create the DB + if ( ! $CI->dbutil->create_database($this->database)) + { + log_message('error', 'Unable to create database: '.$this->database); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_create', $this->database); + } + return FALSE; + } + else + { + // In the event the DB was created we need to select it + if ($this->db_select()) + { + if (! $this->db_set_charset($this->char_set, $this->dbcollat)) + { + log_message('error', 'Unable to set database connection charset: '.$this->char_set); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_set_charset', $this->char_set); + } + + return FALSE; + } + + return TRUE; + } + } + } + + log_message('error', 'Unable to select database: '.$this->database); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_select', $this->database); + } + return FALSE; + } + + if (! $this->db_set_charset($this->char_set, $this->dbcollat)) + { + log_message('error', 'Unable to set database connection charset: '.$this->char_set); + + if ($this->db_debug) + { + $this->display_error('db_unable_to_set_charset', $this->char_set); + } + + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * The name of the platform in use (mysql, mssql, etc...) + * + * @access public + * @return string + */ + function platform() + { + return $this->dbdriver; + } + + // -------------------------------------------------------------------- + + /** + * Database Version Number. Returns a string containing the + * version of the database being used + * + * @access public + * @return string + */ + function version() + { + if (FALSE === ($sql = $this->_version())) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + if ($this->dbdriver == 'oci8') + { + return $sql; + } + + $query = $this->query($sql); + return $query->row('ver'); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * Accepts an SQL string as input and returns a result object upon + * successful execution of a "read" type query. Returns boolean TRUE + * upon successful execution of a "write" type query. Returns boolean + * FALSE upon failure, and if the $db_debug variable is set to TRUE + * will raise an error. + * + * @access public + * @param string An SQL query string + * @param array An array of binding data + * @return mixed + */ + function query($sql, $binds = FALSE, $return_object = TRUE) + { + if ($sql == '') + { + if ($this->db_debug) + { + log_message('error', 'Invalid query: '.$sql); + return $this->display_error('db_invalid_query'); + } + return FALSE; + } + + // Verify table prefix and replace if necessary + if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) ) + { + $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql); + } + + // Is query caching enabled? If the query is a "read type" + // we will load the caching class and return the previously + // cached query if it exists + if ($this->cache_on == TRUE AND stristr($sql, 'SELECT')) + { + if ($this->_cache_init()) + { + $this->load_rdriver(); + if (FALSE !== ($cache = $this->CACHE->read($sql))) + { + return $cache; + } + } + } + + // Compile binds if needed + if ($binds !== FALSE) + { + $sql = $this->compile_binds($sql, $binds); + } + + // Save the query for debugging + if ($this->save_queries == TRUE) + { + $this->queries[] = $sql; + } + + // Start the Query Timer + $time_start = list($sm, $ss) = explode(' ', microtime()); + + // Run the Query + if (FALSE === ($this->result_id = $this->simple_query($sql))) + { + // This will trigger a rollback if transactions are being used + $this->_trans_status = FALSE; + + if ($this->db_debug) + { + log_message('error', 'Query error: '.$this->_error_message()); + return $this->display_error( + array( + 'Error Number: '.$this->_error_number(), + $this->_error_message(), + $sql + ) + ); + } + + return FALSE; + } + + // Stop and aggregate the query time results + $time_end = list($em, $es) = explode(' ', microtime()); + $this->benchmark += ($em + $es) - ($sm + $ss); + + if ($this->save_queries == TRUE) + { + $this->query_times[] = ($em + $es) - ($sm + $ss); + } + + // Increment the query counter + $this->query_count++; + + // Was the query a "write" type? + // If so we'll simply return true + if ($this->is_write_type($sql) === TRUE) + { + // If caching is enabled we'll auto-cleanup any + // existing files related to this particular URI + if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init()) + { + $this->CACHE->delete(); + } + + return TRUE; + } + + // Return TRUE if we don't need to create a result object + // Currently only the Oracle driver uses this when stored + // procedures are used + if ($return_object !== TRUE) + { + return TRUE; + } + + // Load and instantiate the result driver + + $driver = $this->load_rdriver(); + $RES = new $driver(); + $RES->conn_id = $this->conn_id; + $RES->result_id = $this->result_id; + $RES->num_rows = $RES->num_rows(); + + if ($this->dbdriver == 'oci8') + { + $RES->stmt_id = $this->stmt_id; + $RES->curs_id = NULL; + $RES->limit_used = $this->limit_used; + } + + // Is query caching enabled? If so, we'll serialize the + // result object and save it to a cache file. + if ($this->cache_on == TRUE AND $this->_cache_init()) + { + // We'll create a new instance of the result object + // only without the platform specific driver since + // we can't use it with cached data (the query result + // resource ID won't be any good once we've cached the + // result object, so we'll have to compile the data + // and save it) + $CR = new CI_DB_result(); + $CR->num_rows = $RES->num_rows(); + $CR->result_object = $RES->result_object(); + $CR->result_array = $RES->result_array(); + + // Reset these since cached objects can not utilize resource IDs. + $CR->conn_id = NULL; + $CR->result_id = NULL; + + $this->CACHE->write($sql, $CR); + } + + return $RES; + } + + // -------------------------------------------------------------------- + + /** + * Load the result drivers + * + * @access public + * @return string the name of the result class + */ + function load_rdriver() + { + $driver = 'CI_DB_'.$this->dbdriver.'_result'; + + if ( ! class_exists($driver)) + { + include_once(BASEPATH.'database/DB_result'.EXT); + include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT); + } + + return $driver; + } + + // -------------------------------------------------------------------- + + /** + * Simple Query + * This is a simplified version of the query() function. Internally + * we only use it when running transaction commands since they do + * not require all the features of the main query() function. + * + * @access public + * @param string the sql query + * @return mixed + */ + function simple_query($sql) + { + if ( ! $this->conn_id) + { + $this->initialize(); + } + + return $this->_execute($sql); + } + + // -------------------------------------------------------------------- + + /** + * Disable Transactions + * This permits transactions to be disabled at run-time. + * + * @access public + * @return void + */ + function trans_off() + { + $this->trans_enabled = FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Start Transaction + * + * @access public + * @return void + */ + function trans_start($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return FALSE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + $this->_trans_depth += 1; + return; + } + + $this->trans_begin($test_mode); + } + + // -------------------------------------------------------------------- + + /** + * Complete Transaction + * + * @access public + * @return bool + */ + function trans_complete() + { + if ( ! $this->trans_enabled) + { + return FALSE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 1) + { + $this->_trans_depth -= 1; + return TRUE; + } + + // The query() function will set this flag to TRUE in the event that a query failed + if ($this->_trans_status === FALSE) + { + $this->trans_rollback(); + + if ($this->db_debug) + { + return $this->display_error('db_transaction_failure'); + } + return FALSE; + } + + $this->trans_commit(); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Lets you retrieve the transaction flag to determine if it has failed + * + * @access public + * @return bool + */ + function trans_status() + { + return $this->_trans_status; + } + + // -------------------------------------------------------------------- + + /** + * Compile Bindings + * + * @access public + * @param string the sql statement + * @param array an array of bind data + * @return string + */ + function compile_binds($sql, $binds) + { + if (strpos($sql, $this->bind_marker) === FALSE) + { + return $sql; + } + + if ( ! is_array($binds)) + { + $binds = array($binds); + } + + // Get the sql segments around the bind markers + $segments = explode($this->bind_marker, $sql); + + // The count of bind should be 1 less then the count of segments + // If there are more bind arguments trim it down + if (count($binds) >= count($segments)) { + $binds = array_slice($binds, 0, count($segments)-1); + } + + // Construct the binded query + $result = $segments[0]; + $i = 0; + foreach ($binds as $bind) + { + $result .= $this->escape($bind); + $result .= $segments[++$i]; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Determines if a query is a "write" type. + * + * @access public + * @param string An SQL query string + * @return boolean + */ + function is_write_type($sql) + { + if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) + { + return FALSE; + } + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Calculate the aggregate query elapsed time + * + * @access public + * @param integer The number of decimal places + * @return integer + */ + function elapsed_time($decimals = 6) + { + return number_format($this->benchmark, $decimals); + } + + // -------------------------------------------------------------------- + + /** + * Returns the total number of queries + * + * @access public + * @return integer + */ + function total_queries() + { + return $this->query_count; + } + + // -------------------------------------------------------------------- + + /** + * Returns the last query that was executed + * + * @access public + * @return void + */ + function last_query() + { + return end($this->queries); + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function protect_identifiers($item, $first_word_only = FALSE) + { + return $this->_protect_identifiers($item, $first_word_only); + } + + // -------------------------------------------------------------------- + + /** + * "Smart" Escape String + * + * Escapes data based on type + * Sets boolean and null types + * + * @access public + * @param string + * @return integer + */ + function escape($str) + { + switch (gettype($str)) + { + case 'string' : $str = "'".$this->escape_str($str)."'"; + break; + case 'boolean' : $str = ($str === FALSE) ? 0 : 1; + break; + default : $str = ($str === NULL) ? 'NULL' : $str; + break; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Primary + * + * Retrieves the primary key. It assumes that the row in the first + * position is the primary key + * + * @access public + * @param string the table name + * @return string + */ + function primary($table = '') + { + $fields = $this->list_fields($table); + + if ( ! is_array($fields)) + { + return FALSE; + } + + return current($fields); + } + + // -------------------------------------------------------------------- + + /** + * Returns an array of table names + * + * @access public + * @return array + */ + function list_tables($constrain_by_prefix = FALSE) + { + // Is there a cached result? + if (isset($this->data_cache['table_names'])) + { + return $this->data_cache['table_names']; + } + + if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix))) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + $retval = array(); + $query = $this->query($sql); + + if ($query->num_rows() > 0) + { + foreach($query->result_array() as $row) + { + if (isset($row['TABLE_NAME'])) + { + $retval[] = $row['TABLE_NAME']; + } + else + { + $retval[] = array_shift($row); + } + } + } + + $this->data_cache['table_names'] = $retval; + return $this->data_cache['table_names']; + } + + // -------------------------------------------------------------------- + + /** + * Determine if a particular table exists + * @access public + * @return boolean + */ + function table_exists($table_name) + { + return ( ! in_array($this->prep_tablename($table_name), $this->list_tables())) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch MySQL Field Names + * + * @access public + * @param string the table name + * @return array + */ + function list_fields($table = '') + { + // Is there a cached result? + if (isset($this->data_cache['field_names'][$table])) + { + return $this->data_cache['field_names'][$table]; + } + + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('db_field_param_missing'); + } + return FALSE; + } + + if (FALSE === ($sql = $this->_list_columns($this->prep_tablename($table)))) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + + $query = $this->query($sql); + + $retval = array(); + foreach($query->result_array() as $row) + { + if (isset($row['COLUMN_NAME'])) + { + $retval[] = $row['COLUMN_NAME']; + } + else + { + $retval[] = current($row); + } + } + + $this->data_cache['field_names'][$table] = $retval; + return $this->data_cache['field_names'][$table]; + } + + // -------------------------------------------------------------------- + + /** + * Determine if a particular field exists + * @access public + * @param string + * @param string + * @return boolean + */ + function field_exists($field_name, $table_name) + { + return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * DEPRECATED - use list_fields() + */ + function field_names($table = '') + { + return $this->list_fields($table); + } + + // -------------------------------------------------------------------- + + /** + * Returns an object with field data + * + * @access public + * @param string the table name + * @return object + */ + function field_data($table = '') + { + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('db_field_param_missing'); + } + return FALSE; + } + + $query = $this->query($this->_field_data($this->prep_tablename($table))); + return $query->field_data(); + } + + // -------------------------------------------------------------------- + + /** + * Generate an insert string + * + * @access public + * @param string the table upon which the query will be performed + * @param array an associative array data of key/values + * @return string + */ + function insert_string($table, $data) + { + $fields = array(); + $values = array(); + + foreach($data as $key => $val) + { + $fields[] = $key; + $values[] = $this->escape($val); + } + + + return $this->_insert($this->prep_tablename($table), $fields, $values); + } + + // -------------------------------------------------------------------- + + /** + * Generate an update string + * + * @access public + * @param string the table upon which the query will be performed + * @param array an associative array data of key/values + * @param mixed the "where" statement + * @return string + */ + function update_string($table, $data, $where) + { + if ($where == '') + return false; + + $fields = array(); + foreach($data as $key => $val) + { + $fields[$key] = $this->escape($val); + } + + if ( ! is_array($where)) + { + $dest = array($where); + } + else + { + $dest = array(); + foreach ($where as $key => $val) + { + $prefix = (count($dest) == 0) ? '' : ' AND '; + + if ($val !== '') + { + if ( ! $this->_has_operator($key)) + { + $key .= ' ='; + } + + $val = ' '.$this->escape($val); + } + + $dest[] = $prefix.$key.$val; + } + } + + return $this->_update($this->prep_tablename($table), $fields, $dest); + } + + // -------------------------------------------------------------------- + + /** + * Prep the table name - simply adds the table prefix if needed + * + * @access public + * @param string the table name + * @return string + */ + function prep_tablename($table = '') + { + // Do we need to add the table prefix? + if ($this->dbprefix != '') + { + if (substr($table, 0, strlen($this->dbprefix)) != $this->dbprefix) + { + $table = $this->dbprefix.$table; + } + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Enables a native PHP function to be run, using a platform agnostic wrapper. + * + * @access public + * @param string the function name + * @param mixed any parameters needed by the function + * @return mixed + */ + function call_function($function) + { + $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_'; + + if (FALSE === strpos($driver, $function)) + { + $function = $driver.$function; + } + + if ( ! function_exists($function)) + { + if ($this->db_debug) + { + return $this->display_error('db_unsupported_function'); + } + return FALSE; + } + else + { + $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null; + + return call_user_func_array($function, $args); + } + } + + // -------------------------------------------------------------------- + + /** + * Set Cache Directory Path + * + * @access public + * @param string the path to the cache directory + * @return void + */ + function cache_set_path($path = '') + { + $this->cachedir = $path; + } + + // -------------------------------------------------------------------- + + /** + * Enable Query Caching + * + * @access public + * @return void + */ + function cache_on() + { + $this->cache_on = TRUE; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Disable Query Caching + * + * @access public + * @return void + */ + function cache_off() + { + $this->cache_on = FALSE; + return FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Delete the cache files associated with a particular URI + * + * @access public + * @return void + */ + function cache_delete($segment_one = '', $segment_two = '') + { + if ( ! $this->_cache_init()) + { + return FALSE; + } + return $this->CACHE->delete($segment_one, $segment_two); + } + + // -------------------------------------------------------------------- + + /** + * Delete All cache files + * + * @access public + * @return void + */ + function cache_delete_all() + { + if ( ! $this->_cache_init()) + { + return FALSE; + } + + return $this->CACHE->delete_all(); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Cache Class + * + * @access private + * @return void + */ + function _cache_init() + { + if (is_object($this->CACHE) AND class_exists('CI_DB_Cache')) + { + return TRUE; + } + + if ( ! @include(BASEPATH.'database/DB_cache'.EXT)) + { + return $this->cache_off(); + } + + $this->CACHE = new CI_DB_Cache; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @return void + */ + function close() + { + if (is_resource($this->conn_id)) + { + $this->_close($this->conn_id); + } + $this->conn_id = FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Display an error message + * + * @access public + * @param string the error message + * @param string any "swap" values + * @param boolean whether to localize the message + * @return string sends the application/error_db.php template + */ + function display_error($error = '', $swap = '', $native = FALSE) + { +// $LANG = new CI_Lang(); + $LANG = new CI_Language(); + $LANG->load('db'); + + $heading = 'Database Error'; + + if ($native == TRUE) + { + $message = $error; + } + else + { + $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error; + } + + if ( ! class_exists('CI_Exceptions')) + { +// include(BASEPATH.'core/Exceptions'.EXT); + include(BASEPATH.'libraries/Exceptions'.EXT); + } + + $error = new CI_Exceptions(); + echo $error->show_error('An Error Was Encountered', $message, 'error_db'); + exit; + } + +} + +?> \ No newline at end of file diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php new file mode 100755 index 0000000..cd468bc --- /dev/null +++ b/system/database/DB_forge.php @@ -0,0 +1,322 @@ +db + $CI =& get_instance(); + $this->db =& $CI->db; + log_message('debug', "Database Forge Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function create_database($db_name) + { + $sql = $this->_create_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access public + * @param string the database name + * @return bool + */ + function drop_database($db_name) + { + $sql = $this->_drop_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Add Key + * + * @access public + * @param string key + * @param string type + * @return void + */ + function add_key($key = '', $primary = FALSE) + { + if ($key == '') + { + show_error('Key information is required for that operation.'); + } + + if ($primary === TRUE) + { + $this->primary_keys[] = $key; + } + else + { + $this->keys[] = $key; + } + } + + // -------------------------------------------------------------------- + + /** + * Add Field + * + * @access public + * @param string collation + * @return void + */ + function add_field($field = '') + { + if ($field == '') + { + show_error('Field information is required.'); + } + + if (is_string($field)) + { + if ($field == 'id') + { + $this->fields[] = array('id' => array( + 'type' => 'INT', + 'constraint' => 9, + 'auto_increment' => TRUE + ) + ); + $this->add_key('id', TRUE); + } + else + { + if (strpos($field, ' ') === FALSE) + { + show_error('Field information is required for that operation.'); + } + + $this->fields[] = $field; + } + } + + if (is_array($field)) + { + $this->fields = array_merge($this->fields, $field); + } + + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access public + * @param string the table name + * @return bool + */ + function create_table($table = '', $if_not_exists = FALSE) + { + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access public + * @param string the table name + * @return bool + */ + function drop_table($table_name) + { + $sql = $this->_drop_table($this->db->dbprefix.$table_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Add + * + * @access public + * @param string the table name + * @param string the column name + * @param string the column definition + * @return bool + */ + function add_column($table = '', $field = array(), $after_field = '') + { + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + // add field info into field array, but we can only do one at a time + // so only grab the first field in the event there are more then one + $this->add_field(array_slice($field, 0, 1)); + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Drop + * + * @access public + * @param string the table name + * @param string the column name + * @return bool + */ + function drop_column($table = '', $column_name = '') + { + + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + if ($column_name == '') + { + show_error('A column name is required for that operation.'); + } + + $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name); + + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Column Modify + * + * @access public + * @param string the table name + * @param string the column name + * @param string the column definition + * @return bool + */ + function modify_column($table = '', $field = array()) + { + + if ($table == '') + { + show_error('A table name is required for that operation.'); + } + + // add field info into field array, but we can only do one at a time + // so only grab the first field in the event there are more then one + $this->add_field(array_slice($field, 0, 1)); + + if (count($this->fields) == 0) + { + show_error('Field information is required.'); + } + + $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields); + + $this->_reset(); + return $this->db->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Reset + * + * Resets table creation vars + * + * @access private + * @return void + */ + function _reset() + { + $this->fields = array(); + $this->keys = array(); + $this->primary_keys = array(); + } + +} +?> \ No newline at end of file diff --git a/system/database/DB_result.php b/system/database/DB_result.php new file mode 100755 index 0000000..7d50979 --- /dev/null +++ b/system/database/DB_result.php @@ -0,0 +1,340 @@ +result_object() : $this->result_array(); + } + + // -------------------------------------------------------------------- + + /** + * Query result. "object" version. + * + * @access public + * @return object + */ + function result_object() + { + if (count($this->result_object) > 0) + { + return $this->result_object; + } + + // In the event that query caching is on the result_id variable + // will return FALSE since there isn't a valid SQL resource so + // we'll simply return an empty array. + if ($this->result_id === FALSE OR $this->num_rows() == 0) + { + return array(); + } + + $this->_data_seek(0); + while ($row = $this->_fetch_object()) + { + $this->result_object[] = $row; + } + + return $this->result_object; + } + + // -------------------------------------------------------------------- + + /** + * Query result. "array" version. + * + * @access public + * @return array + */ + function result_array() + { + if (count($this->result_array) > 0) + { + return $this->result_array; + } + + // In the event that query caching is on the result_id variable + // will return FALSE since there isn't a valid SQL resource so + // we'll simply return an empty array. + if ($this->result_id === FALSE OR $this->num_rows() == 0) + { + return array(); + } + + $this->_data_seek(0); + while ($row = $this->_fetch_assoc()) + { + $this->result_array[] = $row; + } + + return $this->result_array; + } + + // -------------------------------------------------------------------- + + /** + * Query result. Acts as a wrapper function for the following functions. + * + * @access public + * @param string + * @param string can be "object" or "array" + * @return mixed either a result object or array + */ + function row($n = 0, $type = 'object') + { + if ( ! is_numeric($n)) + { + // We cache the row data for subsequent uses + if ( ! is_array($this->row_data)) + { + $this->row_data = $this->row_array(0); + } + + if (isset($this->row_data[$n])) + { + return $this->row_data[$n]; + } + // reset the $n variable if the result was not achieved + $n = 0; + } + + return ($type == 'object') ? $this->row_object($n) : $this->row_array($n); + } + + // -------------------------------------------------------------------- + + /** + * Assigns an item into a particular column slot + * + * @access public + * @return object + */ + function set_row($key, $value = NULL) + { + // We cache the row data for subsequent uses + if ( ! is_array($this->row_data)) + { + $this->row_data = $this->row_array(0); + } + + if (is_array($key)) + { + foreach ($key as $k => $v) + { + $this->row_data[$k] = $v; + } + + return; + } + + if ($key != '' AND ! is_null($value)) + { + $this->row_data[$key] = $value; + } + } + + // -------------------------------------------------------------------- + + /** + * Returns a single result row - object version + * + * @access public + * @return object + */ + function row_object($n = 0) + { + $result = $this->result_object(); + + if (count($result) == 0) + { + return $result; + } + + if ($n != $this->current_row AND isset($result[$n])) + { + $this->current_row = $n; + } + + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * Returns a single result row - array version + * + * @access public + * @return array + */ + function row_array($n = 0) + { + $result = $this->result_array(); + + if (count($result) == 0) + { + return $result; + } + + if ($n != $this->current_row AND isset($result[$n])) + { + $this->current_row = $n; + } + + return $result[$this->current_row]; + } + + + // -------------------------------------------------------------------- + + /** + * Returns the "first" row + * + * @access public + * @return object + */ + function first_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + return $result[0]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "last" row + * + * @access public + * @return object + */ + function last_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + return $result[count($result) -1]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "next" row + * + * @access public + * @return object + */ + function next_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row + 1])) + { + ++$this->current_row; + } + + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * Returns the "previous" row + * + * @access public + * @return object + */ + function previous_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row - 1])) + { + --$this->current_row; + } + return $result[$this->current_row]; + } + + // -------------------------------------------------------------------- + + /** + * The following functions are normally overloaded by the identically named + * methods in the platform-specific driver -- except when query caching + * is used. When caching is enabled we do not load the other driver. + * These functions are primarily here to prevent undefined function errors + * when a cached result object is in use. They are not otherwise fully + * operational due to the unavailability of the database resource IDs with + * cached results. + */ + function num_rows() { return $this->num_rows; } + function num_fields() { return 0; } + function list_fields() { return array(); } + function field_names() { return array(); } // Deprecated + function field_data() { return array(); } + function free_result() { return TRUE; } + function _data_seek() { return TRUE; } + function _fetch_assoc() { return array(); } + function _fetch_object() { return array(); } + +} +// END DB_result class +?> \ No newline at end of file diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php new file mode 100755 index 0000000..d9b8fed --- /dev/null +++ b/system/database/DB_utility.php @@ -0,0 +1,387 @@ +db + $CI =& get_instance(); + $this->db =& $CI->db; + + log_message('debug', "Database Utility Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * List databases + * + * @access public + * @return bool + */ + function list_databases() + { + // Is there a cached result? + if (isset($this->data_cache['db_names'])) + { + return $this->data_cache['db_names']; + } + + $query = $this->db->query($this->_list_databases()); + $dbs = array(); + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $dbs[] = current($row); + } + } + + $this->data_cache['db_names'] = $dbs; + return $this->data_cache['db_names']; + } + + // -------------------------------------------------------------------- + + /** + * Optimize Table + * + * @access public + * @param string the table name + * @return bool + */ + function optimize_table($table_name) + { + $sql = $this->_optimize_table($table_name); + + if (is_bool($sql)) + { + show_error('db_must_use_set'); + } + + $query = $this->db->query($sql); + $res = $query->result_array(); + + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + return current($res); + } + + // -------------------------------------------------------------------- + + /** + * Optimize Database + * + * @access public + * @return array + */ + function optimize_database() + { + $result = array(); + foreach ($this->db->list_tables() as $table_name) + { + $sql = $this->_optimize_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + + // Build the result array... + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + $res = $query->result_array(); + $res = current($res); + $key = str_replace($this->db->database.'.', '', current($res)); + $keys = array_keys($res); + unset($res[$keys[0]]); + + $result[$key] = $res; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Repair Table + * + * @access public + * @param string the table name + * @return bool + */ + function repair_table($table_name) + { + $sql = $this->_repair_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + + // Note: Due to a bug in current() that affects some versions + // of PHP we can not pass function call directly into it + $res = $query->result_array(); + return current($res); + } + + // -------------------------------------------------------------------- + + /** + * Generate CSV from a query result object + * + * @access public + * @param object The query result object + * @param string The delimiter - comma by default + * @param string The newline character - \n by default + * @param string The enclosure - double quote by default + * @return string + */ + function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"') + { + if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + { + show_error('You must submit a valid result object'); + } + + $out = ''; + + // First generate the headings from the table column names + foreach ($query->list_fields() as $name) + { + $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim; + } + + $out = rtrim($out); + $out .= $newline; + + // Next blast through the result array and build out the rows + foreach ($query->result_array() as $row) + { + foreach ($row as $item) + { + $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim; + } + $out = rtrim($out); + $out .= $newline; + } + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Generate XML data from a query result object + * + * @access public + * @param object The query result object + * @param array Any preferences + * @return string + */ + function xml_from_result($query, $params = array()) + { + if ( ! is_object($query) OR ! method_exists($query, 'field_names')) + { + show_error('You must submit a valid result object'); + } + + // Set our default values + foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val) + { + if ( ! isset($params[$key])) + { + $params[$key] = $val; + } + } + + // Create variables for convenience + extract($params); + + // Load the xml helper + $CI =& get_instance(); + $CI->load->helper('xml'); + + // Generate the result + $xml = "<{$root}>".$newline; + foreach ($query->result_array() as $row) + { + $xml .= $tab."<{$element}>".$newline; + + foreach ($row as $key => $val) + { + $xml .= $tab.$tab."<{$key}>".xml_convert($val)."".$newline; + } + $xml .= $tab."".$newline; + } + $xml .= "".$newline; + + return $xml; + } + + // -------------------------------------------------------------------- + + /** + * Database Backup + * + * @access public + * @return void + */ + function backup($params = array()) + { + // If the parameters have not been submitted as an + // array then we know that it is simply the table + // name, which is a valid short cut. + if (is_string($params)) + { + $params = array('tables' => $params); + } + + // ------------------------------------------------------ + + // Set up our default preferences + $prefs = array( + 'tables' => array(), + 'ignore' => array(), + 'filename' => '', + 'format' => 'gzip', // gzip, zip, txt + 'add_drop' => TRUE, + 'add_insert' => TRUE, + 'newline' => "\n" + ); + + // Did the user submit any preferences? If so set them.... + if (count($params) > 0) + { + foreach ($prefs as $key => $val) + { + if (isset($params[$key])) + { + $prefs[$key] = $params[$key]; + } + } + } + + // ------------------------------------------------------ + + // Are we backing up a complete database or individual tables? + // If no table names were submitted we'll fetch the entire table list + if (count($prefs['tables']) == 0) + { + $prefs['tables'] = $this->db->list_tables(); + } + + // ------------------------------------------------------ + + // Validate the format + if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE)) + { + $prefs['format'] = 'txt'; + } + + // ------------------------------------------------------ + + // Is the encoder supported? If not, we'll either issue an + // error or use plain text depending on the debug settings + if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode')) + OR ($prefs['format'] == 'zip' AND ! @function_exists('gzcompress'))) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_compression'); + } + + $prefs['format'] = 'txt'; + } + + // ------------------------------------------------------ + + // Set the filename if not provided - Only needed with Zip files + if ($prefs['filename'] == '' AND $prefs['format'] == 'zip') + { + $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database; + $prefs['filename'] .= '_'.date('Y-m-d_H-i', time()); + } + + // ------------------------------------------------------ + + // Was a Gzip file requested? + if ($prefs['format'] == 'gzip') + { + return gzencode($this->_backup($prefs)); + } + + // ------------------------------------------------------ + + // Was a text file requested? + if ($prefs['format'] == 'txt') + { + return $this->_backup($prefs); + } + + // ------------------------------------------------------ + + // Was a Zip file requested? + if ($prefs['format'] == 'zip') + { + // If they included the .zip file extension we'll remove it + if (preg_match("|.+?\.zip$|", $prefs['filename'])) + { + $prefs['filename'] = str_replace('.zip', '', $prefs['filename']); + } + + // Tack on the ".sql" file extension if needed + if ( ! preg_match("|.+?\.sql$|", $prefs['filename'])) + { + $prefs['filename'] .= '.sql'; + } + + // Load the Zip class and output it + + $CI =& get_instance(); + $CI->load->library('zip'); + $CI->zip->add_data($prefs['filename'], $this->_backup($prefs)); + return $CI->zip->get_zip(); + } + + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/.svn/all-wcprops b/system/database/drivers/.svn/all-wcprops new file mode 100644 index 0000000..fa266be --- /dev/null +++ b/system/database/drivers/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/!svn/ver/18/trunk/system/database/drivers +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/database/drivers/index.html +END diff --git a/system/database/drivers/.svn/entries b/system/database/drivers/.svn/entries new file mode 100644 index 0000000..3a2a439 --- /dev/null +++ b/system/database/drivers/.svn/entries @@ -0,0 +1,83 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +mssql +dir + +sqlite +dir + +oci8 +dir + +postgre +dir + +mysql +dir + +odbc +dir + +index.html +file + + + + +2009-09-15T00:18:11.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +mysqli +dir + diff --git a/system/database/drivers/.svn/prop-base/index.html.svn-base b/system/database/drivers/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/.svn/text-base/index.html.svn-base b/system/database/drivers/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/index.html b/system/database/drivers/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mssql/.svn/all-wcprops b/system/database/drivers/mssql/.svn/all-wcprops new file mode 100644 index 0000000..8599969 --- /dev/null +++ b/system/database/drivers/mssql/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql +END +mssql_driver.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql/mssql_driver.php +END +mssql_result.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql/mssql_result.php +END +mssql_forge.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql/mssql_forge.php +END +mssql_utility.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql/mssql_utility.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/18/trunk/system/database/drivers/mssql/index.html +END diff --git a/system/database/drivers/mssql/.svn/entries b/system/database/drivers/mssql/.svn/entries new file mode 100644 index 0000000..88987d6 --- /dev/null +++ b/system/database/drivers/mssql/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/mssql +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +mssql_driver.php +file + + + + +2009-09-15T00:18:07.000000Z +a145f756afc3630f5e11a1ead7ff38d9 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15227 + +mssql_result.php +file + + + + +2009-09-15T00:18:07.000000Z +38f33adc5a2ac080a129eabc9b3bb571 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3533 + +mssql_forge.php +file + + + + +2009-09-15T00:18:07.000000Z +2db637266e158f3c8021282ba4f294a6 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5179 + +mssql_utility.php +file + + + + +2009-09-15T00:18:07.000000Z +2e8ea51ba4c544f3bc6d5c9515fb37de +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2684 + +index.html +file + + + + +2009-09-15T00:18:07.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/database/drivers/mssql/.svn/prop-base/index.html.svn-base b/system/database/drivers/mssql/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mssql/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mssql/.svn/prop-base/mssql_driver.php.svn-base b/system/database/drivers/mssql/.svn/prop-base/mssql_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mssql/.svn/prop-base/mssql_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mssql/.svn/prop-base/mssql_forge.php.svn-base b/system/database/drivers/mssql/.svn/prop-base/mssql_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mssql/.svn/prop-base/mssql_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mssql/.svn/prop-base/mssql_result.php.svn-base b/system/database/drivers/mssql/.svn/prop-base/mssql_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mssql/.svn/prop-base/mssql_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mssql/.svn/prop-base/mssql_utility.php.svn-base b/system/database/drivers/mssql/.svn/prop-base/mssql_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mssql/.svn/prop-base/mssql_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mssql/.svn/text-base/index.html.svn-base b/system/database/drivers/mssql/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mssql/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mssql/.svn/text-base/mssql_driver.php.svn-base b/system/database/drivers/mssql/.svn/text-base/mssql_driver.php.svn-base new file mode 100644 index 0000000..7b024d4 --- /dev/null +++ b/system/database/drivers/mssql/.svn/text-base/mssql_driver.php.svn-base @@ -0,0 +1,644 @@ +hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @mssql_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mssql_select_db($this->database, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @mssql_query($sql, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('BEGIN TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + // Escape single quotes + return str_replace("'", "''", $str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mssql_rows_affected($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * Returns the last id created in the Identity column. + * + * @access public + * @return integer + */ + function insert_id() + { + $ver = self::_parse_major_version($this->version()); + $sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id"); + $query = $this->query($sql); + $row = $query->row(); + return $row->last_id; + } + + // -------------------------------------------------------------------- + + /** + * Parse major version + * + * Grabs the major version number from the + * database server version string passed in. + * + * @access private + * @param string $version + * @return int16 major version number + */ + function _parse_major_version($version) + { + preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info); + return $ver_info[1]; // return the major version b/c that's all we're interested in. + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT @@VERSION AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name"; + + // for future compatibility + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + //$sql .= " LIKE '".$this->dbprefix."%'"; + return FALSE; // not currently supported + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * List column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access private + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 * FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + // Are errros even supported in MS SQL? + return ''; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + // Are error numbers supported? + return ''; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + // I don't believe this is necessary with MS SQL. Not sure, though. - Rick + + /* + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + */ + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item(s) + * @param boolean should spaces be backticked + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $i = $limit + $offset; + + return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql); + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mssql_close($conn_id); + } + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/.svn/text-base/mssql_forge.php.svn-base b/system/database/drivers/mssql/.svn/text-base/mssql_forge.php.svn-base new file mode 100644 index 0000000..baf776c --- /dev/null +++ b/system/database/drivers/mssql/.svn/text-base/mssql_forge.php.svn-base @@ -0,0 +1,219 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/.svn/text-base/mssql_result.php.svn-base b/system/database/drivers/mssql/.svn/text-base/mssql_result.php.svn-base new file mode 100644 index 0000000..c95fd91 --- /dev/null +++ b/system/database/drivers/mssql/.svn/text-base/mssql_result.php.svn-base @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mssql_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mssql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mssql_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->max_length = $field->max_length; + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mssql_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mssql_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mssql_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mssql_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/.svn/text-base/mssql_utility.php.svn-base b/system/database/drivers/mssql/.svn/text-base/mssql_utility.php.svn-base new file mode 100644 index 0000000..87f8196 --- /dev/null +++ b/system/database/drivers/mssql/.svn/text-base/mssql_utility.php.svn-base @@ -0,0 +1,121 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/index.html b/system/database/drivers/mssql/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mssql/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php new file mode 100755 index 0000000..7b024d4 --- /dev/null +++ b/system/database/drivers/mssql/mssql_driver.php @@ -0,0 +1,644 @@ +hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @mssql_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mssql_select_db($this->database, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @mssql_query($sql, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('BEGIN TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK TRAN'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + // Escape single quotes + return str_replace("'", "''", $str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mssql_rows_affected($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * Returns the last id created in the Identity column. + * + * @access public + * @return integer + */ + function insert_id() + { + $ver = self::_parse_major_version($this->version()); + $sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id"); + $query = $this->query($sql); + $row = $query->row(); + return $row->last_id; + } + + // -------------------------------------------------------------------- + + /** + * Parse major version + * + * Grabs the major version number from the + * database server version string passed in. + * + * @access private + * @param string $version + * @return int16 major version number + */ + function _parse_major_version($version) + { + preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info); + return $ver_info[1]; // return the major version b/c that's all we're interested in. + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT @@VERSION AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name"; + + // for future compatibility + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + //$sql .= " LIKE '".$this->dbprefix."%'"; + return FALSE; // not currently supported + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * List column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access private + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 * FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + // Are errros even supported in MS SQL? + return ''; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + // Are error numbers supported? + return ''; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + // I don't believe this is necessary with MS SQL. Not sure, though. - Rick + + /* + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + */ + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item(s) + * @param boolean should spaces be backticked + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $i = $limit + $offset; + + return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql); + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mssql_close($conn_id); + } + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php new file mode 100755 index 0000000..baf776c --- /dev/null +++ b/system/database/drivers/mssql/mssql_forge.php @@ -0,0 +1,219 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php new file mode 100755 index 0000000..c95fd91 --- /dev/null +++ b/system/database/drivers/mssql/mssql_result.php @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mssql_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mssql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mssql_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->max_length = $field->max_length; + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mssql_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mssql_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mssql_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mssql_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php new file mode 100755 index 0000000..87f8196 --- /dev/null +++ b/system/database/drivers/mssql/mssql_utility.php @@ -0,0 +1,121 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/.svn/all-wcprops b/system/database/drivers/mysql/.svn/all-wcprops new file mode 100644 index 0000000..3cdd85f --- /dev/null +++ b/system/database/drivers/mysql/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql +END +mysql_driver.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql/mysql_driver.php +END +mysql_result.php +K 25 +svn:wc:ra_dav:version-url +V 69 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql/mysql_result.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql/index.html +END +mysql_forge.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql/mysql_forge.php +END +mysql_utility.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/18/trunk/system/database/drivers/mysql/mysql_utility.php +END diff --git a/system/database/drivers/mysql/.svn/entries b/system/database/drivers/mysql/.svn/entries new file mode 100644 index 0000000..eedb6bf --- /dev/null +++ b/system/database/drivers/mysql/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/mysql +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +mysql_driver.php +file + + + + +2009-09-15T00:18:10.000000Z +e6ab9e69493a64112747b0eca750b20f +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15444 + +mysql_result.php +file + + + + +2009-09-15T00:18:10.000000Z +4725f3ebc66dedf81c2d136bbe780e9c +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3555 + +index.html +file + + + + +2009-09-15T00:18:10.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +mysql_forge.php +file + + + + +2009-09-15T00:18:10.000000Z +f1d756b830042607d41e2b11b2789b4d +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5350 + +mysql_utility.php +file + + + + +2009-09-15T00:18:10.000000Z +5db9a87c63db730afcc98ea88e2fb119 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5928 + diff --git a/system/database/drivers/mysql/.svn/prop-base/index.html.svn-base b/system/database/drivers/mysql/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysql/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysql/.svn/prop-base/mysql_driver.php.svn-base b/system/database/drivers/mysql/.svn/prop-base/mysql_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysql/.svn/prop-base/mysql_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysql/.svn/prop-base/mysql_forge.php.svn-base b/system/database/drivers/mysql/.svn/prop-base/mysql_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysql/.svn/prop-base/mysql_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysql/.svn/prop-base/mysql_result.php.svn-base b/system/database/drivers/mysql/.svn/prop-base/mysql_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysql/.svn/prop-base/mysql_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysql/.svn/prop-base/mysql_utility.php.svn-base b/system/database/drivers/mysql/.svn/prop-base/mysql_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysql/.svn/prop-base/mysql_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysql/.svn/text-base/index.html.svn-base b/system/database/drivers/mysql/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mysql/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mysql/.svn/text-base/mysql_driver.php.svn-base b/system/database/drivers/mysql/.svn/text-base/mysql_driver.php.svn-base new file mode 100644 index 0000000..edf09a1 --- /dev/null +++ b/system/database/drivers/mysql/.svn/text-base/mysql_driver.php.svn-base @@ -0,0 +1,655 @@ +hostname, $this->username, $this->password, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @mysql_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mysql_select_db($this->database, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @mysql_query($sql, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + // "DELETE FROM TABLE" returns 0 affected rows This hack modifies + // the query so that it returns the number of affected rows + if ($this->delete_hack === TRUE) + { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql); + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('SET AUTOCOMMIT=0'); + $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val); + } + + return $str; + } + + if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id)) + { + return mysql_real_escape_string($str, $this->conn_id); + } + elseif (function_exists('mysql_escape_string')) + { + return mysql_escape_string($str); + } + else + { + return addslashes($str); + } + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mysql_affected_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @mysql_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return mysql_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return mysql_errno($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '`' . str_replace('.', '`.`', $table) . '`'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "`{$item}`"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " `{$exception}` ") !== FALSE) + { + $item = preg_replace('/ `('.preg_quote($exception).')` /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql."LIMIT ".$offset.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mysql_close($conn_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/.svn/text-base/mysql_forge.php.svn-base b/system/database/drivers/mysql/.svn/text-base/mysql_forge.php.svn-base new file mode 100644 index 0000000..6e3a2d1 --- /dev/null +++ b/system/database/drivers/mysql/.svn/text-base/mysql_forge.php.svn-base @@ -0,0 +1,223 @@ +$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + if (array_key_exists('NAME', $attributes)) + { + $sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' '; + } + + if (array_key_exists('TYPE', $attributes)) + { + $sql .= ' '.$attributes['TYPE']; + } + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes)) + { + $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param mixed the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + + $sql .= $this->_process_fields($fields); + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tKEY ($key)"; + } + } + + $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return "DROP TABLE IF EXISTS ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param array fields + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $fields, $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type "; + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql.$this->db->_protect_identifiers($fields); + } + + $sql .= $this->_process_fields($fields); + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/.svn/text-base/mysql_result.php.svn-base b/system/database/drivers/mysql/.svn/text-base/mysql_result.php.svn-base new file mode 100644 index 0000000..9e6a3c3 --- /dev/null +++ b/system/database/drivers/mysql/.svn/text-base/mysql_result.php.svn-base @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mysql_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mysql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mysql_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->default = $field->def; + $F->max_length = $field->max_length; + $F->primary_key = $field->primary_key; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mysql_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mysql_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mysql_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mysql_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/.svn/text-base/mysql_utility.php.svn-base b/system/database/drivers/mysql/.svn/text-base/mysql_utility.php.svn-base new file mode 100644 index 0000000..dc8fd08 --- /dev/null +++ b/system/database/drivers/mysql/.svn/text-base/mysql_utility.php.svn-base @@ -0,0 +1,252 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return "REPAIR TABLE ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + /** + * MySQL Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + if (count($params) == 0) + { + return FALSE; + } + + // Extract the prefs for simplicity + extract($params); + + // Build the output + $output = ''; + foreach ((array)$tables as $table) + { + // Is the table in the "ignore" list? + if (in_array($table, (array)$ignore, TRUE)) + { + continue; + } + + // Get the table schema + $query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.'.$table); + + // No result means the table name was invalid + if ($query === FALSE) + { + continue; + } + + // Write out the table schema + $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline; + + if ($add_drop == TRUE) + { + $output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline; + } + + $i = 0; + $result = $query->result_array(); + foreach ($result[0] as $val) + { + if ($i++ % 2) + { + $output .= $val.';'.$newline.$newline; + } + } + + // If inserts are not needed we're done... + if ($add_insert == FALSE) + { + continue; + } + + // Grab all the data from the current table + $query = $this->db->query("SELECT * FROM $table"); + + if ($query->num_rows() == 0) + { + continue; + } + + // Fetch the field names and determine if the field is an + // integer type. We use this info to decide whether to + // surround the data with quotes or not + + $i = 0; + $field_str = ''; + $is_int = array(); + while ($field = mysql_fetch_field($query->result_id)) + { + // Most versions of MySQL store timestamp as a string + $is_int[$i] = (in_array( + strtolower(mysql_field_type($query->result_id, $i)), + array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), + TRUE) + ) ? TRUE : FALSE; + + // Create a string of field names + $field_str .= $field->name.', '; + $i++; + } + + // Trim off the end comma + $field_str = preg_replace( "/, $/" , "" , $field_str); + + + // Build the insert string + foreach ($query->result_array() as $row) + { + $val_str = ''; + + $i = 0; + foreach ($row as $v) + { + // Is the value NULL? + if ($v === NULL) + { + $val_str .= 'NULL'; + } + else + { + // Do a little formatting... + $v = str_replace(array("\x00", "\x0a", "\x0d", "\x1a"), array('\0', '\n', '\r', '\Z'), $v); + $v = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $v); + $v = str_replace('\\', '\\\\', $v); + $v = str_replace('\'', '\\\'', $v); + $v = str_replace('\\\n', '\n', $v); + $v = str_replace('\\\r', '\r', $v); + $v = str_replace('\\\t', '\t', $v); + + // Escape the data if it's not an integer + if ($is_int[$i] == FALSE) + { + $val_str .= $this->db->escape($v); + } + else + { + $val_str .= $v; + } + } + + // Append a comma + $val_str .= ', '; + $i++; + } + + // Remove the comma at the end of the string + $val_str = preg_replace( "/, $/" , "" , $val_str); + + // Build the INSERT string + $output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline; + } + + $output .= $newline.$newline; + } + + return $output; + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/index.html b/system/database/drivers/mysql/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mysql/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php new file mode 100755 index 0000000..edf09a1 --- /dev/null +++ b/system/database/drivers/mysql/mysql_driver.php @@ -0,0 +1,655 @@ +hostname, $this->username, $this->password, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @mysql_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mysql_select_db($this->database, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @mysql_query($sql, $this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + // "DELETE FROM TABLE" returns 0 affected rows This hack modifies + // the query so that it returns the number of affected rows + if ($this->delete_hack === TRUE) + { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql); + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('SET AUTOCOMMIT=0'); + $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + if (is_array($str)) + { + foreach($str as $key => $val) + { + $str[$key] = $this->escape_str($val); + } + + return $str; + } + + if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id)) + { + return mysql_real_escape_string($str, $this->conn_id); + } + elseif (function_exists('mysql_escape_string')) + { + return mysql_escape_string($str); + } + else + { + return addslashes($str); + } + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mysql_affected_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @mysql_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return mysql_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return mysql_errno($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '`' . str_replace('.', '`.`', $table) . '`'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "`{$item}`"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " `{$exception}` ") !== FALSE) + { + $item = preg_replace('/ `('.preg_quote($exception).')` /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql."LIMIT ".$offset.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mysql_close($conn_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php new file mode 100755 index 0000000..6e3a2d1 --- /dev/null +++ b/system/database/drivers/mysql/mysql_forge.php @@ -0,0 +1,223 @@ +$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + if (array_key_exists('NAME', $attributes)) + { + $sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' '; + } + + if (array_key_exists('TYPE', $attributes)) + { + $sql .= ' '.$attributes['TYPE']; + } + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes)) + { + $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param mixed the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + + $sql .= $this->_process_fields($fields); + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tKEY ($key)"; + } + } + + $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return "DROP TABLE IF EXISTS ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param array fields + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $fields, $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type "; + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql.$this->db->_protect_identifiers($fields); + } + + $sql .= $this->_process_fields($fields); + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php new file mode 100755 index 0000000..9e6a3c3 --- /dev/null +++ b/system/database/drivers/mysql/mysql_result.php @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mysql_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mysql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mysql_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->default = $field->def; + $F->max_length = $field->max_length; + $F->primary_key = $field->primary_key; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mysql_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mysql_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mysql_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mysql_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php new file mode 100755 index 0000000..dc8fd08 --- /dev/null +++ b/system/database/drivers/mysql/mysql_utility.php @@ -0,0 +1,252 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return "REPAIR TABLE ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + /** + * MySQL Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + if (count($params) == 0) + { + return FALSE; + } + + // Extract the prefs for simplicity + extract($params); + + // Build the output + $output = ''; + foreach ((array)$tables as $table) + { + // Is the table in the "ignore" list? + if (in_array($table, (array)$ignore, TRUE)) + { + continue; + } + + // Get the table schema + $query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.'.$table); + + // No result means the table name was invalid + if ($query === FALSE) + { + continue; + } + + // Write out the table schema + $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline; + + if ($add_drop == TRUE) + { + $output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline; + } + + $i = 0; + $result = $query->result_array(); + foreach ($result[0] as $val) + { + if ($i++ % 2) + { + $output .= $val.';'.$newline.$newline; + } + } + + // If inserts are not needed we're done... + if ($add_insert == FALSE) + { + continue; + } + + // Grab all the data from the current table + $query = $this->db->query("SELECT * FROM $table"); + + if ($query->num_rows() == 0) + { + continue; + } + + // Fetch the field names and determine if the field is an + // integer type. We use this info to decide whether to + // surround the data with quotes or not + + $i = 0; + $field_str = ''; + $is_int = array(); + while ($field = mysql_fetch_field($query->result_id)) + { + // Most versions of MySQL store timestamp as a string + $is_int[$i] = (in_array( + strtolower(mysql_field_type($query->result_id, $i)), + array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), + TRUE) + ) ? TRUE : FALSE; + + // Create a string of field names + $field_str .= $field->name.', '; + $i++; + } + + // Trim off the end comma + $field_str = preg_replace( "/, $/" , "" , $field_str); + + + // Build the insert string + foreach ($query->result_array() as $row) + { + $val_str = ''; + + $i = 0; + foreach ($row as $v) + { + // Is the value NULL? + if ($v === NULL) + { + $val_str .= 'NULL'; + } + else + { + // Do a little formatting... + $v = str_replace(array("\x00", "\x0a", "\x0d", "\x1a"), array('\0', '\n', '\r', '\Z'), $v); + $v = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $v); + $v = str_replace('\\', '\\\\', $v); + $v = str_replace('\'', '\\\'', $v); + $v = str_replace('\\\n', '\n', $v); + $v = str_replace('\\\r', '\r', $v); + $v = str_replace('\\\t', '\t', $v); + + // Escape the data if it's not an integer + if ($is_int[$i] == FALSE) + { + $val_str .= $this->db->escape($v); + } + else + { + $val_str .= $v; + } + } + + // Append a comma + $val_str .= ', '; + $i++; + } + + // Remove the comma at the end of the string + $val_str = preg_replace( "/, $/" , "" , $val_str); + + // Build the INSERT string + $output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline; + } + + $output .= $newline.$newline; + } + + return $output; + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/.svn/all-wcprops b/system/database/drivers/mysqli/.svn/all-wcprops new file mode 100644 index 0000000..20dddb9 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli +END +mysqli_driver.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli/mysqli_driver.php +END +mysqli_result.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli/mysqli_result.php +END +mysqli_forge.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli/mysqli_forge.php +END +mysqli_utility.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli/mysqli_utility.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/database/drivers/mysqli/index.html +END diff --git a/system/database/drivers/mysqli/.svn/entries b/system/database/drivers/mysqli/.svn/entries new file mode 100644 index 0000000..7df1130 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/mysqli +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +mysqli_driver.php +file + + + + +2009-09-15T00:18:11.000000Z +f8329a39645c3ddf14c7ab9e593d13e2 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15345 + +mysqli_result.php +file + + + + +2009-09-15T00:18:11.000000Z +afb632fed3007d9044d7f7427eeeb90a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3594 + +mysqli_forge.php +file + + + + +2009-09-15T00:18:11.000000Z +29e514ef887a5e2042b044b55c8aab40 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5254 + +mysqli_utility.php +file + + + + +2009-09-15T00:18:11.000000Z +44e2ee2885d23222296638f6b09e554a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2677 + +index.html +file + + + + +2009-09-15T00:18:11.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/database/drivers/mysqli/.svn/prop-base/index.html.svn-base b/system/database/drivers/mysqli/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysqli/.svn/prop-base/mysqli_driver.php.svn-base b/system/database/drivers/mysqli/.svn/prop-base/mysqli_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/prop-base/mysqli_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysqli/.svn/prop-base/mysqli_forge.php.svn-base b/system/database/drivers/mysqli/.svn/prop-base/mysqli_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/prop-base/mysqli_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysqli/.svn/prop-base/mysqli_result.php.svn-base b/system/database/drivers/mysqli/.svn/prop-base/mysqli_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/prop-base/mysqli_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysqli/.svn/prop-base/mysqli_utility.php.svn-base b/system/database/drivers/mysqli/.svn/prop-base/mysqli_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/prop-base/mysqli_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/mysqli/.svn/text-base/index.html.svn-base b/system/database/drivers/mysqli/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mysqli/.svn/text-base/mysqli_driver.php.svn-base b/system/database/drivers/mysqli/.svn/text-base/mysqli_driver.php.svn-base new file mode 100644 index 0000000..73396c5 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/text-base/mysqli_driver.php.svn-base @@ -0,0 +1,648 @@ +hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return $this->db_connect(); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mysqli_select_db($this->conn_id, $this->database); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + $result = @mysqli_query($this->conn_id, $sql); + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + // "DELETE FROM TABLE" returns 0 affected rows This hack modifies + // the query so that it returns the number of affected rows + if ($this->delete_hack === TRUE) + { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql); + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('SET AUTOCOMMIT=0'); + $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id)) + { + return mysqli_real_escape_string($this->conn_id, $str); + } + elseif (function_exists('mysql_escape_string')) + { + return mysql_escape_string($str); + } + else + { + return addslashes($str); + } + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mysqli_affected_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @mysqli_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return mysqli_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return mysqli_errno($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '`' . str_replace('.', '`.`', $table) . '`'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "`{$item}`"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " `{$exception}` ") !== FALSE) + { + $item = preg_replace('/ `('.preg_quote($exception).')` /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $sql .= "LIMIT ".$limit; + + if ($offset > 0) + { + $sql .= " OFFSET ".$offset; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mysqli_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/.svn/text-base/mysqli_forge.php.svn-base b/system/database/drivers/mysqli/.svn/text-base/mysqli_forge.php.svn-base new file mode 100644 index 0000000..cb315a4 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/text-base/mysqli_forge.php.svn-base @@ -0,0 +1,217 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tKEY ($key)"; + } + } + + $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/.svn/text-base/mysqli_result.php.svn-base b/system/database/drivers/mysqli/.svn/text-base/mysqli_result.php.svn-base new file mode 100644 index 0000000..586c292 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/text-base/mysqli_result.php.svn-base @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mysqli_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mysqli_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mysqli_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->default = $field->def; + $F->max_length = $field->max_length; + $F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mysqli_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mysqli_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mysqli_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mysqli_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/.svn/text-base/mysqli_utility.php.svn-base b/system/database/drivers/mysqli/.svn/text-base/mysqli_utility.php.svn-base new file mode 100644 index 0000000..4ab2bb1 --- /dev/null +++ b/system/database/drivers/mysqli/.svn/text-base/mysqli_utility.php.svn-base @@ -0,0 +1,121 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return "REPAIR TABLE ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * MySQLi Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/index.html b/system/database/drivers/mysqli/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/mysqli/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php new file mode 100755 index 0000000..73396c5 --- /dev/null +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -0,0 +1,648 @@ +hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return $this->db_connect(); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return @mysqli_select_db($this->conn_id, $this->database); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + $result = @mysqli_query($this->conn_id, $sql); + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + // "DELETE FROM TABLE" returns 0 affected rows This hack modifies + // the query so that it returns the number of affected rows + if ($this->delete_hack === TRUE) + { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql); + } + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('SET AUTOCOMMIT=0'); + $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + $this->simple_query('SET AUTOCOMMIT=1'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id)) + { + return mysqli_real_escape_string($this->conn_id, $str); + } + elseif (function_exists('mysql_escape_string')) + { + return mysql_escape_string($str); + } + else + { + return addslashes($str); + } + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @mysqli_affected_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @mysqli_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return mysqli_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return mysqli_errno($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '`' . str_replace('.', '`.`', $table) . '`'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "`{$item}`"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " `{$exception}` ") !== FALSE) + { + $item = preg_replace('/ `('.preg_quote($exception).')` /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $sql .= "LIMIT ".$limit; + + if ($offset > 0) + { + $sql .= " OFFSET ".$offset; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @mysqli_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php new file mode 100755 index 0000000..cb315a4 --- /dev/null +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -0,0 +1,217 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tKEY ($key)"; + } + } + + $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php new file mode 100755 index 0000000..586c292 --- /dev/null +++ b/system/database/drivers/mysqli/mysqli_result.php @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @mysqli_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + while ($field = mysqli_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + while ($field = mysqli_fetch_field($this->result_id)) + { + $F = new stdClass(); + $F->name = $field->name; + $F->type = $field->type; + $F->default = $field->def; + $F->max_length = $field->max_length; + $F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + mysqli_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return mysqli_data_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return mysqli_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return mysqli_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php new file mode 100755 index 0000000..4ab2bb1 --- /dev/null +++ b/system/database/drivers/mysqli/mysqli_utility.php @@ -0,0 +1,121 @@ +db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return "REPAIR TABLE ".$this->db->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * MySQLi Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/.svn/all-wcprops b/system/database/drivers/oci8/.svn/all-wcprops new file mode 100644 index 0000000..4239b6f --- /dev/null +++ b/system/database/drivers/oci8/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8 +END +oci8_driver.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8/oci8_driver.php +END +oci8_result.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8/oci8_result.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8/index.html +END +oci8_forge.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8/oci8_forge.php +END +oci8_utility.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/18/trunk/system/database/drivers/oci8/oci8_utility.php +END diff --git a/system/database/drivers/oci8/.svn/entries b/system/database/drivers/oci8/.svn/entries new file mode 100644 index 0000000..f91a499 --- /dev/null +++ b/system/database/drivers/oci8/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/oci8 +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +oci8_driver.php +file + + + + +2009-09-15T00:18:09.000000Z +8cfe9d477e076f5208bb3f9a8b733ffb +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +17885 + +oci8_result.php +file + + + + +2009-09-15T00:18:09.000000Z +bc636a34060c36e47836d439315e8df1 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5193 + +index.html +file + + + + +2009-09-15T00:18:09.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +oci8_forge.php +file + + + + +2009-09-15T00:18:09.000000Z +6fc4b5a41a960f16de0efd80b5f3066a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5069 + +oci8_utility.php +file + + + + +2009-09-15T00:18:09.000000Z +31cd221cd1d653b8dace1a1f563bbb9d +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2599 + diff --git a/system/database/drivers/oci8/.svn/prop-base/index.html.svn-base b/system/database/drivers/oci8/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/oci8/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/oci8/.svn/prop-base/oci8_driver.php.svn-base b/system/database/drivers/oci8/.svn/prop-base/oci8_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/oci8/.svn/prop-base/oci8_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/oci8/.svn/prop-base/oci8_forge.php.svn-base b/system/database/drivers/oci8/.svn/prop-base/oci8_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/oci8/.svn/prop-base/oci8_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/oci8/.svn/prop-base/oci8_result.php.svn-base b/system/database/drivers/oci8/.svn/prop-base/oci8_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/oci8/.svn/prop-base/oci8_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/oci8/.svn/prop-base/oci8_utility.php.svn-base b/system/database/drivers/oci8/.svn/prop-base/oci8_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/oci8/.svn/prop-base/oci8_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/oci8/.svn/text-base/index.html.svn-base b/system/database/drivers/oci8/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/oci8/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/oci8/.svn/text-base/oci8_driver.php.svn-base b/system/database/drivers/oci8/.svn/text-base/oci8_driver.php.svn-base new file mode 100644 index 0000000..ec26f5b --- /dev/null +++ b/system/database/drivers/oci8/.svn/text-base/oci8_driver.php.svn-base @@ -0,0 +1,764 @@ +username, $this->password, $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @ociplogon($this->username, $this->password, $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return ociserverversion($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + // oracle must parse the query before it is run. All of the actions with + // the query are based on the statement id returned by ociparse + $this->_set_stmt_id($sql); + ocisetprefetch($this->stmt_id, 1000); + return @ociexecute($this->stmt_id, $this->_commit); + } + + /** + * Generate a statement ID + * + * @access private + * @param string an SQL query + * @return none + */ + function _set_stmt_id($sql) + { + if ( ! is_resource($this->stmt_id)) + { + $this->stmt_id = ociparse($this->conn_id, $this->_prep_query($sql)); + } + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * getCursor. Returns a cursor from the datbase + * + * @access public + * @return cursor id + */ + function get_cursor() + { + $this->curs_id = ocinewcursor($this->conn_id); + return $this->curs_id; + } + + // -------------------------------------------------------------------- + + /** + * Stored Procedure. Executes a stored procedure + * + * @access public + * @param package package stored procedure is in + * @param procedure stored procedure to execute + * @param params array of parameters + * @return array + * + * params array keys + * + * KEY OPTIONAL NOTES + * name no the name of the parameter should be in : format + * value no the value of the parameter. If this is an OUT or IN OUT parameter, + * this should be a reference to a variable + * type yes the type of the parameter + * length yes the max size of the parameter + */ + function stored_procedure($package, $procedure, $params) + { + if ($package == '' OR $procedure == '' OR ! is_array($params)) + { + if ($this->db_debug) + { + log_message('error', 'Invalid query: '.$package.'.'.$procedure); + return $this->display_error('db_invalid_query'); + } + return FALSE; + } + + // build the query string + $sql = "begin $package.$procedure("; + + $have_cursor = FALSE; + foreach($params as $param) + { + $sql .= $param['name'] . ","; + + if (array_key_exists('type', $param) && ($param['type'] == OCI_B_CURSOR)) + { + $have_cursor = TRUE; + } + } + $sql = trim($sql, ",") . "); end;"; + + $this->stmt_id = FALSE; + $this->_set_stmt_id($sql); + $this->_bind_params($params); + $this->query($sql, FALSE, $have_cursor); + } + + // -------------------------------------------------------------------- + + /** + * Bind parameters + * + * @access private + * @return none + */ + function _bind_params($params) + { + if ( ! is_array($params) OR ! is_resource($this->stmt_id)) + { + return; + } + + foreach ($params as $param) + { + foreach (array('name', 'value', 'type', 'length') as $val) + { + if ( ! isset($param[$val])) + { + $param[$val] = ''; + } + } + + ocibindbyname($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']); + } + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->_commit = OCI_DEFAULT; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = OCIcommit($this->conn_id); + $this->_commit = OCI_COMMIT_ON_SUCCESS; + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = OCIrollback($this->conn_id); + $this->_commit = OCI_COMMIT_ON_SUCCESS; + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @ocirowcount($this->stmt_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + // not supported in oracle + return $this->display_error('db_unsupported_function'); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query == FALSE) + { + return 0; + } + + $row = $query->row(); + return $row->NUMROWS; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT TABLE_NAME FROM ALL_TABLES"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." where rownum = 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + $error = ocierror($this->conn_id); + return $error['message']; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + $error = ocierror($this->conn_id); + return $error['code']; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE TABLE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $limit = $offset + $limit; + $newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)"; + + if ($offset != 0) + { + $newsql .= " WHERE rnum >= $offset"; + } + + // remember that we used limits + $this->limit_used = TRUE; + + return $newsql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @ocilogoff($conn_id); + } + + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/.svn/text-base/oci8_forge.php.svn-base b/system/database/drivers/oci8/.svn/text-base/oci8_forge.php.svn-base new file mode 100644 index 0000000..b9d9e63 --- /dev/null +++ b/system/database/drivers/oci8/.svn/text-base/oci8_forge.php.svn-base @@ -0,0 +1,216 @@ +db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + $sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $keys) . ")"; + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/.svn/text-base/oci8_result.php.svn-base b/system/database/drivers/oci8/.svn/text-base/oci8_result.php.svn-base new file mode 100644 index 0000000..30dd0da --- /dev/null +++ b/system/database/drivers/oci8/.svn/text-base/oci8_result.php.svn-base @@ -0,0 +1,251 @@ +result_array()); + @ociexecute($this->stmt_id); + if ($this->curs_id) + { + @ociexecute($this->curs_id); + } + return $rowcount; + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + $count = @ocinumcols($this->stmt_id); + + // if we used a limit we subtract it + if ($this->limit_used) + { + $count = $count - 1; + } + + return $count; + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + $fieldCount = $this->num_fields(); + for ($c = 1; $c <= $fieldCount; $c++) + { + $field_names[] = ocicolumnname($this->stmt_id, $c); + } + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + $fieldCount = $this->num_fields(); + for ($c = 1; $c <= $fieldCount; $c++) + { + $F = new stdClass(); + $F->name = ocicolumnname($this->stmt_id, $c); + $F->type = ocicolumntype($this->stmt_id, $c); + $F->max_length = ocicolumnsize($this->stmt_id, $c); + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + ocifreestatement($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc(&$row) + { + $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; + + return ocifetchinto($id, $row, OCI_ASSOC + OCI_RETURN_NULLS); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + $result = array(); + + // If PHP 5 is being used we can fetch an result object + if (function_exists('oci_fetch_object')) + { + $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; + + return @oci_fetch_object($id); + } + + // If PHP 4 is being used we have to build our own result + foreach ($this->result_array() as $key => $val) + { + $obj = new stdClass(); + if (is_array($val)) + { + foreach ($val as $k => $v) + { + $obj->$k = $v; + } + } + else + { + $obj->$key = $val; + } + + $result[] = $obj; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Query result. "array" version. + * + * @access public + * @return array + */ + function result_array() + { + if (count($this->result_array) > 0) + { + return $this->result_array; + } + + // oracle's fetch functions do not return arrays. + // The information is returned in reference parameters + $row = NULL; + while ($this->_fetch_assoc($row)) + { + $this->result_array[] = $row; + } + + return $this->result_array; + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return FALSE; // Not needed + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/.svn/text-base/oci8_utility.php.svn-base b/system/database/drivers/oci8/.svn/text-base/oci8_utility.php.svn-base new file mode 100644 index 0000000..117f8e6 --- /dev/null +++ b/system/database/drivers/oci8/.svn/text-base/oci8_utility.php.svn-base @@ -0,0 +1,120 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return FALSE; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/index.html b/system/database/drivers/oci8/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/oci8/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php new file mode 100755 index 0000000..ec26f5b --- /dev/null +++ b/system/database/drivers/oci8/oci8_driver.php @@ -0,0 +1,764 @@ +username, $this->password, $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @ociplogon($this->username, $this->password, $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return ociserverversion($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + // oracle must parse the query before it is run. All of the actions with + // the query are based on the statement id returned by ociparse + $this->_set_stmt_id($sql); + ocisetprefetch($this->stmt_id, 1000); + return @ociexecute($this->stmt_id, $this->_commit); + } + + /** + * Generate a statement ID + * + * @access private + * @param string an SQL query + * @return none + */ + function _set_stmt_id($sql) + { + if ( ! is_resource($this->stmt_id)) + { + $this->stmt_id = ociparse($this->conn_id, $this->_prep_query($sql)); + } + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * getCursor. Returns a cursor from the datbase + * + * @access public + * @return cursor id + */ + function get_cursor() + { + $this->curs_id = ocinewcursor($this->conn_id); + return $this->curs_id; + } + + // -------------------------------------------------------------------- + + /** + * Stored Procedure. Executes a stored procedure + * + * @access public + * @param package package stored procedure is in + * @param procedure stored procedure to execute + * @param params array of parameters + * @return array + * + * params array keys + * + * KEY OPTIONAL NOTES + * name no the name of the parameter should be in : format + * value no the value of the parameter. If this is an OUT or IN OUT parameter, + * this should be a reference to a variable + * type yes the type of the parameter + * length yes the max size of the parameter + */ + function stored_procedure($package, $procedure, $params) + { + if ($package == '' OR $procedure == '' OR ! is_array($params)) + { + if ($this->db_debug) + { + log_message('error', 'Invalid query: '.$package.'.'.$procedure); + return $this->display_error('db_invalid_query'); + } + return FALSE; + } + + // build the query string + $sql = "begin $package.$procedure("; + + $have_cursor = FALSE; + foreach($params as $param) + { + $sql .= $param['name'] . ","; + + if (array_key_exists('type', $param) && ($param['type'] == OCI_B_CURSOR)) + { + $have_cursor = TRUE; + } + } + $sql = trim($sql, ",") . "); end;"; + + $this->stmt_id = FALSE; + $this->_set_stmt_id($sql); + $this->_bind_params($params); + $this->query($sql, FALSE, $have_cursor); + } + + // -------------------------------------------------------------------- + + /** + * Bind parameters + * + * @access private + * @return none + */ + function _bind_params($params) + { + if ( ! is_array($params) OR ! is_resource($this->stmt_id)) + { + return; + } + + foreach ($params as $param) + { + foreach (array('name', 'value', 'type', 'length') as $val) + { + if ( ! isset($param[$val])) + { + $param[$val] = ''; + } + } + + ocibindbyname($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']); + } + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->_commit = OCI_DEFAULT; + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = OCIcommit($this->conn_id); + $this->_commit = OCI_COMMIT_ON_SUCCESS; + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = OCIrollback($this->conn_id); + $this->_commit = OCI_COMMIT_ON_SUCCESS; + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @ocirowcount($this->stmt_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + // not supported in oracle + return $this->display_error('db_unsupported_function'); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query == FALSE) + { + return 0; + } + + $row = $query->row(); + return $row->NUMROWS; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT TABLE_NAME FROM ALL_TABLES"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." where rownum = 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + $error = ocierror($this->conn_id); + return $error['message']; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + $error = ocierror($this->conn_id); + return $error['code']; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE TABLE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $limit = $offset + $limit; + $newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)"; + + if ($offset != 0) + { + $newsql .= " WHERE rnum >= $offset"; + } + + // remember that we used limits + $this->limit_used = TRUE; + + return $newsql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @ocilogoff($conn_id); + } + + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php new file mode 100755 index 0000000..b9d9e63 --- /dev/null +++ b/system/database/drivers/oci8/oci8_forge.php @@ -0,0 +1,216 @@ +db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + $sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $keys) . ")"; + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php new file mode 100755 index 0000000..30dd0da --- /dev/null +++ b/system/database/drivers/oci8/oci8_result.php @@ -0,0 +1,251 @@ +result_array()); + @ociexecute($this->stmt_id); + if ($this->curs_id) + { + @ociexecute($this->curs_id); + } + return $rowcount; + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + $count = @ocinumcols($this->stmt_id); + + // if we used a limit we subtract it + if ($this->limit_used) + { + $count = $count - 1; + } + + return $count; + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + $fieldCount = $this->num_fields(); + for ($c = 1; $c <= $fieldCount; $c++) + { + $field_names[] = ocicolumnname($this->stmt_id, $c); + } + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + $fieldCount = $this->num_fields(); + for ($c = 1; $c <= $fieldCount; $c++) + { + $F = new stdClass(); + $F->name = ocicolumnname($this->stmt_id, $c); + $F->type = ocicolumntype($this->stmt_id, $c); + $F->max_length = ocicolumnsize($this->stmt_id, $c); + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + ocifreestatement($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc(&$row) + { + $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; + + return ocifetchinto($id, $row, OCI_ASSOC + OCI_RETURN_NULLS); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + $result = array(); + + // If PHP 5 is being used we can fetch an result object + if (function_exists('oci_fetch_object')) + { + $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id; + + return @oci_fetch_object($id); + } + + // If PHP 4 is being used we have to build our own result + foreach ($this->result_array() as $key => $val) + { + $obj = new stdClass(); + if (is_array($val)) + { + foreach ($val as $k => $v) + { + $obj->$k = $v; + } + } + else + { + $obj->$key = $val; + } + + $result[] = $obj; + } + + return $result; + } + + // -------------------------------------------------------------------- + + /** + * Query result. "array" version. + * + * @access public + * @return array + */ + function result_array() + { + if (count($this->result_array) > 0) + { + return $this->result_array; + } + + // oracle's fetch functions do not return arrays. + // The information is returned in reference parameters + $row = NULL; + while ($this->_fetch_assoc($row)) + { + $this->result_array[] = $row; + } + + return $this->result_array; + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return FALSE; // Not needed + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php new file mode 100755 index 0000000..117f8e6 --- /dev/null +++ b/system/database/drivers/oci8/oci8_utility.php @@ -0,0 +1,120 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return FALSE; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/.svn/all-wcprops b/system/database/drivers/odbc/.svn/all-wcprops new file mode 100644 index 0000000..e6b2e5e --- /dev/null +++ b/system/database/drivers/odbc/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc +END +odbc_forge.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc/odbc_forge.php +END +odbc_utility.php +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc/odbc_utility.php +END +odbc_driver.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc/odbc_driver.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc/index.html +END +odbc_result.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/database/drivers/odbc/odbc_result.php +END diff --git a/system/database/drivers/odbc/.svn/entries b/system/database/drivers/odbc/.svn/entries new file mode 100644 index 0000000..90b82fc --- /dev/null +++ b/system/database/drivers/odbc/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/odbc +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +odbc_forge.php +file + + + + +2009-09-15T00:18:11.000000Z +9831c27c1f09f31bcb8f5a30ec5fc1e2 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5629 + +odbc_utility.php +file + + + + +2009-09-15T00:18:11.000000Z +50d839f84def8f77fea921b85a4a3b52 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3352 + +odbc_driver.php +file + + + + +2009-09-15T00:18:11.000000Z +baec4c8e491218841ac0e66caba68e0e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +14210 + +index.html +file + + + + +2009-09-15T00:18:11.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +odbc_result.php +file + + + + +2009-09-15T00:18:11.000000Z +467a103e9f7a9a8425729bdd1779ac6e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4809 + diff --git a/system/database/drivers/odbc/.svn/prop-base/index.html.svn-base b/system/database/drivers/odbc/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/odbc/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/odbc/.svn/prop-base/odbc_driver.php.svn-base b/system/database/drivers/odbc/.svn/prop-base/odbc_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/odbc/.svn/prop-base/odbc_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/odbc/.svn/prop-base/odbc_forge.php.svn-base b/system/database/drivers/odbc/.svn/prop-base/odbc_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/odbc/.svn/prop-base/odbc_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/odbc/.svn/prop-base/odbc_result.php.svn-base b/system/database/drivers/odbc/.svn/prop-base/odbc_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/odbc/.svn/prop-base/odbc_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/odbc/.svn/prop-base/odbc_utility.php.svn-base b/system/database/drivers/odbc/.svn/prop-base/odbc_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/odbc/.svn/prop-base/odbc_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/odbc/.svn/text-base/index.html.svn-base b/system/database/drivers/odbc/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/odbc/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/odbc/.svn/text-base/odbc_driver.php.svn-base b/system/database/drivers/odbc/.svn/text-base/odbc_driver.php.svn-base new file mode 100644 index 0000000..bdedab3 --- /dev/null +++ b/system/database/drivers/odbc/.svn/text-base/odbc_driver.php.svn-base @@ -0,0 +1,616 @@ +_random_keyword = ' RND('.time().')'; // database specific random keyword + } + + /** + * Non-persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_connect() + { + return @odbc_connect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @odbc_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + // Not needed for ODBC + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @odbc_exec($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return odbc_autocommit($this->conn_id, FALSE); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = odbc_commit($this->conn_id); + odbc_autocommit($this->conn_id, TRUE); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = odbc_rollback($this->conn_id); + odbc_autocommit($this->conn_id, TRUE); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + // ODBC doesn't require escaping + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @odbc_num_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @odbc_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + //$sql .= " LIKE '".$this->dbprefix."%'"; + return FALSE; // not currently supported + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return odbc_errormsg($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return odbc_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + // used to add backticks in other db drivers + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "{$item}"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " {$exception} ") !== FALSE) + { + $item = preg_replace('/ ('.preg_quote($exception).') /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return $this->_delete($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + // Does ODBC doesn't use the LIMIT clause? + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @odbc_close($conn_id); + } + + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/.svn/text-base/odbc_forge.php.svn-base b/system/database/drivers/odbc/.svn/text-base/odbc_forge.php.svn-base new file mode 100644 index 0000000..374c15f --- /dev/null +++ b/system/database/drivers/odbc/.svn/text-base/odbc_forge.php.svn-base @@ -0,0 +1,236 @@ +db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + // ODBC has no "drop database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/.svn/text-base/odbc_result.php.svn-base b/system/database/drivers/odbc/.svn/text-base/odbc_result.php.svn-base new file mode 100644 index 0000000..dd3f923 --- /dev/null +++ b/system/database/drivers/odbc/.svn/text-base/odbc_result.php.svn-base @@ -0,0 +1,232 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @odbc_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = odbc_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = odbc_field_name($this->result_id, $i); + $F->type = odbc_field_type($this->result_id, $i); + $F->max_length = odbc_field_len($this->result_id, $i); + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + odbc_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + if (function_exists('odbc_fetch_object')) + { + return odbc_fetch_array($this->result_id); + } + else + { + return $this->_odbc_fetch_array($this->result_id); + } + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + if (function_exists('odbc_fetch_object')) + { + return odbc_fetch_object($this->result_id); + } + else + { + return $this->_odbc_fetch_object($this->result_id); + } + } + + + /** + * Result - object + * + * subsititutes the odbc_fetch_object function when + * not available (odbc_fetch_object requires unixODBC) + * + * @access private + * @return object + */ + function _odbc_fetch_object(& $odbc_result) { + $rs = array(); + $rs_obj = false; + if (odbc_fetch_into($odbc_result, $rs)) { + foreach ($rs as $k=>$v) { + $field_name= odbc_field_name($odbc_result, $k+1); + $rs_obj->$field_name = $v; + } + } + return $rs_obj; + } + + + /** + * Result - array + * + * subsititutes the odbc_fetch_array function when + * not available (odbc_fetch_array requires unixODBC) + * + * @access private + * @return array + */ + function _odbc_fetch_array(& $odbc_result) { + $rs = array(); + $rs_assoc = false; + if (odbc_fetch_into($odbc_result, $rs)) { + $rs_assoc=array(); + foreach ($rs as $k=>$v) { + $field_name= odbc_field_name($odbc_result, $k+1); + $rs_assoc[$field_name] = $v; + } + } + return $rs_assoc; + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/.svn/text-base/odbc_utility.php.svn-base b/system/database/drivers/odbc/.svn/text-base/odbc_utility.php.svn-base new file mode 100644 index 0000000..f74d031 --- /dev/null +++ b/system/database/drivers/odbc/.svn/text-base/odbc_utility.php.svn-base @@ -0,0 +1,146 @@ +db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Optimize table query + * + * Generates a platform-specific query so that a table can be optimized + * + * @access private + * @param string the table name + * @return object + */ + function _optimize_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * ODBC Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database() + { + // ODBC has no "create database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + // ODBC has no "drop database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/index.html b/system/database/drivers/odbc/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/odbc/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php new file mode 100755 index 0000000..bdedab3 --- /dev/null +++ b/system/database/drivers/odbc/odbc_driver.php @@ -0,0 +1,616 @@ +_random_keyword = ' RND('.time().')'; // database specific random keyword + } + + /** + * Non-persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_connect() + { + return @odbc_connect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + return @odbc_pconnect($this->hostname, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + // Not needed for ODBC + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @odbc_exec($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return odbc_autocommit($this->conn_id, FALSE); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = odbc_commit($this->conn_id); + odbc_autocommit($this->conn_id, TRUE); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $ret = odbc_rollback($this->conn_id); + odbc_autocommit($this->conn_id, TRUE); + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + // ODBC doesn't require escaping + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @odbc_num_rows($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @odbc_insert_id($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SHOW TABLES FROM `".$this->database."`"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + //$sql .= " LIKE '".$this->dbprefix."%'"; + return FALSE; // not currently supported + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SHOW COLUMNS FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 FROM ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return odbc_errormsg($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return odbc_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + // used to add backticks in other db drivers + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "`item1` `item2`" and not "`item1 item2`" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "`field` >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1`$2`$3', $item); + } + else + { + return "{$item}"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " {$exception} ") !== FALSE) + { + $item = preg_replace('/ ('.preg_quote($exception).') /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return $this->_delete($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + // Does ODBC doesn't use the LIMIT clause? + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @odbc_close($conn_id); + } + + +} + + +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php new file mode 100755 index 0000000..374c15f --- /dev/null +++ b/system/database/drivers/odbc/odbc_forge.php @@ -0,0 +1,236 @@ +db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + // ODBC has no "drop database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php new file mode 100755 index 0000000..dd3f923 --- /dev/null +++ b/system/database/drivers/odbc/odbc_result.php @@ -0,0 +1,232 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @odbc_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = odbc_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = odbc_field_name($this->result_id, $i); + $F->type = odbc_field_type($this->result_id, $i); + $F->max_length = odbc_field_len($this->result_id, $i); + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + odbc_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + if (function_exists('odbc_fetch_object')) + { + return odbc_fetch_array($this->result_id); + } + else + { + return $this->_odbc_fetch_array($this->result_id); + } + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + if (function_exists('odbc_fetch_object')) + { + return odbc_fetch_object($this->result_id); + } + else + { + return $this->_odbc_fetch_object($this->result_id); + } + } + + + /** + * Result - object + * + * subsititutes the odbc_fetch_object function when + * not available (odbc_fetch_object requires unixODBC) + * + * @access private + * @return object + */ + function _odbc_fetch_object(& $odbc_result) { + $rs = array(); + $rs_obj = false; + if (odbc_fetch_into($odbc_result, $rs)) { + foreach ($rs as $k=>$v) { + $field_name= odbc_field_name($odbc_result, $k+1); + $rs_obj->$field_name = $v; + } + } + return $rs_obj; + } + + + /** + * Result - array + * + * subsititutes the odbc_fetch_array function when + * not available (odbc_fetch_array requires unixODBC) + * + * @access private + * @return array + */ + function _odbc_fetch_array(& $odbc_result) { + $rs = array(); + $rs_assoc = false; + if (odbc_fetch_into($odbc_result, $rs)) { + $rs_assoc=array(); + foreach ($rs as $k=>$v) { + $field_name= odbc_field_name($odbc_result, $k+1); + $rs_assoc[$field_name] = $v; + } + } + return $rs_assoc; + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php new file mode 100755 index 0000000..f74d031 --- /dev/null +++ b/system/database/drivers/odbc/odbc_utility.php @@ -0,0 +1,146 @@ +db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Optimize table query + * + * Generates a platform-specific query so that a table can be optimized + * + * @access private + * @param string the table name + * @return object + */ + function _optimize_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Generates a platform-specific query so that a table can be repaired + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + // Not a supported ODBC feature + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * ODBC Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database() + { + // ODBC has no "create database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + // ODBC has no "drop database" command since it's + // designed to connect to an existing database + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return FALSE; + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/.svn/all-wcprops b/system/database/drivers/postgre/.svn/all-wcprops new file mode 100644 index 0000000..de538b3 --- /dev/null +++ b/system/database/drivers/postgre/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre +END +postgre_driver.php +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre/postgre_driver.php +END +postgre_result.php +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre/postgre_result.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre/index.html +END +postgre_forge.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre/postgre_forge.php +END +postgre_utility.php +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/18/trunk/system/database/drivers/postgre/postgre_utility.php +END diff --git a/system/database/drivers/postgre/.svn/entries b/system/database/drivers/postgre/.svn/entries new file mode 100644 index 0000000..f05e1da --- /dev/null +++ b/system/database/drivers/postgre/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/postgre +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +postgre_driver.php +file + + + + +2009-09-15T00:18:09.000000Z +a8aa3b34fcff964bd99f7d5e04124b52 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15248 + +postgre_result.php +file + + + + +2009-09-15T00:18:09.000000Z +d911a90ebf026046f575d2e69cb026b9 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3591 + +index.html +file + + + + +2009-09-15T00:18:09.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +postgre_forge.php +file + + + + +2009-09-15T00:18:09.000000Z +37e0a7f6566246222d0a703d8d4ec8f3 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5194 + +postgre_utility.php +file + + + + +2009-09-15T00:18:09.000000Z +0a2e23163fbe4b5e5a717cd2c8f8d3ef +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2556 + diff --git a/system/database/drivers/postgre/.svn/prop-base/index.html.svn-base b/system/database/drivers/postgre/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/postgre/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/postgre/.svn/prop-base/postgre_driver.php.svn-base b/system/database/drivers/postgre/.svn/prop-base/postgre_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/postgre/.svn/prop-base/postgre_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/postgre/.svn/prop-base/postgre_forge.php.svn-base b/system/database/drivers/postgre/.svn/prop-base/postgre_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/postgre/.svn/prop-base/postgre_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/postgre/.svn/prop-base/postgre_result.php.svn-base b/system/database/drivers/postgre/.svn/prop-base/postgre_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/postgre/.svn/prop-base/postgre_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/postgre/.svn/prop-base/postgre_utility.php.svn-base b/system/database/drivers/postgre/.svn/prop-base/postgre_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/postgre/.svn/prop-base/postgre_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/postgre/.svn/text-base/index.html.svn-base b/system/database/drivers/postgre/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/postgre/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/postgre/.svn/text-base/postgre_driver.php.svn-base b/system/database/drivers/postgre/.svn/text-base/postgre_driver.php.svn-base new file mode 100644 index 0000000..ce8cb25 --- /dev/null +++ b/system/database/drivers/postgre/.svn/text-base/postgre_driver.php.svn-base @@ -0,0 +1,644 @@ +port == '') ? '' : " port=".$this->port; + + return @pg_connect("host=".$this->hostname.$port." dbname=".$this->database." user=".$this->username." password=".$this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + $port = ($this->port == '') ? '' : " port=".$this->port; + + return @pg_pconnect("host=".$this->hostname.$port." dbname=".$this->database." user=".$this->username." password=".$this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + // Not needed for Postgre so we'll return TRUE + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @pg_query($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return @pg_exec($this->conn_id, "begin"); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return @pg_exec($this->conn_id, "commit"); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return @pg_exec($this->conn_id, "rollback"); + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return pg_escape_string($str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @pg_affected_rows($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + $v = $this->_version(); + $v = $v['server']; + + $table = func_num_args() > 0 ? func_get_arg(0) : null; + $column = func_num_args() > 1 ? func_get_arg(1) : null; + + if ($table == null && $v >= '8.1') + { + $sql='SELECT LASTVAL() as ins_id'; + } + elseif ($table != null && $column != null && $v >= '8.0') + { + $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column); + $query = $this->query($sql); + $row = $query->row(); + $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq); + } + elseif ($table != null) + { + // seq_name passed in table parameter + $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table); + } + else + { + return pg_last_oid($this->result_id); + } + $query = $this->query($sql); + $row = $query->row(); + return $row->ins_id; + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " AND table_name LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$this->_escape_table($table)."'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return pg_last_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return ''; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped. + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $sql .= "LIMIT ".$limit; + + if ($offset > 0) + { + $sql .= " OFFSET ".$offset; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @pg_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/.svn/text-base/postgre_forge.php.svn-base b/system/database/drivers/postgre/.svn/text-base/postgre_forge.php.svn-base new file mode 100644 index 0000000..81ac8e9 --- /dev/null +++ b/system/database/drivers/postgre/.svn/text-base/postgre_forge.php.svn-base @@ -0,0 +1,219 @@ +db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n);"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return "DROP TABLE ".$this->db->_escape_table($table)." CASCADE"; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/.svn/text-base/postgre_result.php.svn-base b/system/database/drivers/postgre/.svn/text-base/postgre_result.php.svn-base new file mode 100644 index 0000000..fdce01a --- /dev/null +++ b/system/database/drivers/postgre/.svn/text-base/postgre_result.php.svn-base @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @pg_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = pg_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = pg_field_name($this->result_id, $i); + $F->type = pg_field_type($this->result_id, $i); + $F->max_length = pg_field_size($this->result_id, $i); + $F->primary_key = $i == 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + pg_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return pg_result_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return pg_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return pg_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/.svn/text-base/postgre_utility.php.svn-base b/system/database/drivers/postgre/.svn/text-base/postgre_utility.php.svn-base new file mode 100644 index 0000000..573654f --- /dev/null +++ b/system/database/drivers/postgre/.svn/text-base/postgre_utility.php.svn-base @@ -0,0 +1,122 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/index.html b/system/database/drivers/postgre/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/postgre/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php new file mode 100755 index 0000000..ce8cb25 --- /dev/null +++ b/system/database/drivers/postgre/postgre_driver.php @@ -0,0 +1,644 @@ +port == '') ? '' : " port=".$this->port; + + return @pg_connect("host=".$this->hostname.$port." dbname=".$this->database." user=".$this->username." password=".$this->password); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + $port = ($this->port == '') ? '' : " port=".$this->port; + + return @pg_pconnect("host=".$this->hostname.$port." dbname=".$this->database." user=".$this->username." password=".$this->password); + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + // Not needed for Postgre so we'll return TRUE + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return "SELECT version() AS ver"; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @pg_query($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return @pg_exec($this->conn_id, "begin"); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return @pg_exec($this->conn_id, "commit"); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return @pg_exec($this->conn_id, "rollback"); + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return pg_escape_string($str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @pg_affected_rows($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + $v = $this->_version(); + $v = $v['server']; + + $table = func_num_args() > 0 ? func_get_arg(0) : null; + $column = func_num_args() > 1 ? func_get_arg(1) : null; + + if ($table == null && $v >= '8.1') + { + $sql='SELECT LASTVAL() as ins_id'; + } + elseif ($table != null && $column != null && $v >= '8.0') + { + $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column); + $query = $this->query($sql); + $row = $query->row(); + $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq); + } + elseif ($table != null) + { + // seq_name passed in table parameter + $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table); + } + else + { + return pg_last_oid($this->result_id); + } + $query = $this->query($sql); + $row = $query->row(); + return $row->ins_id; + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * Show table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " AND table_name LIKE '".$this->dbprefix."%'"; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$this->_escape_table($table)."'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return pg_last_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return ''; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped. + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + if (strpos($table, '.') !== FALSE) + { + $table = '"' . str_replace('.', '"."', $table) . '"'; + } + + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need ""item1" "item2"" and not ""item1 item2"" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return ""field" >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1"$2"$3', $item); + } + else + { + return "\"{$item}\""; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " \"{$exception}\" ") !== FALSE) + { + $item = preg_replace('/ "('.preg_quote($exception).')" /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $sql .= "LIMIT ".$limit; + + if ($offset > 0) + { + $sql .= " OFFSET ".$offset; + } + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @pg_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php new file mode 100755 index 0000000..81ac8e9 --- /dev/null +++ b/system/database/drivers/postgre/postgre_forge.php @@ -0,0 +1,219 @@ +db->_escape_table($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + foreach ($keys as $key) + { + $sql .= ",\n\tFOREIGN KEY ($key)"; + } + } + + $sql .= "\n);"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * @access private + * @return bool + */ + function _drop_table($table) + { + return "DROP TABLE ".$this->db->_escape_table($table)." CASCADE"; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php new file mode 100755 index 0000000..fdce01a --- /dev/null +++ b/system/database/drivers/postgre/postgre_result.php @@ -0,0 +1,173 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @pg_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = pg_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = pg_field_name($this->result_id, $i); + $F->type = pg_field_type($this->result_id, $i); + $F->max_length = pg_field_size($this->result_id, $i); + $F->primary_key = $i == 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + pg_free_result($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return pg_result_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return pg_fetch_assoc($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return pg_fetch_object($this->result_id); + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php new file mode 100755 index 0000000..573654f --- /dev/null +++ b/system/database/drivers/postgre/postgre_utility.php @@ -0,0 +1,122 @@ +db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access private + * @param string the database name + * @return bool + */ + function _create_database($name) + { + return "CREATE DATABASE ".$name; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + return "DROP DATABASE ".$name; + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/.svn/all-wcprops b/system/database/drivers/sqlite/.svn/all-wcprops new file mode 100644 index 0000000..38b96d0 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite +END +sqlite_driver.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite/sqlite_driver.php +END +sqlite_result.php +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite/sqlite_result.php +END +sqlite_forge.php +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite/sqlite_forge.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite/index.html +END +sqlite_utility.php +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/18/trunk/system/database/drivers/sqlite/sqlite_utility.php +END diff --git a/system/database/drivers/sqlite/.svn/entries b/system/database/drivers/sqlite/.svn/entries new file mode 100644 index 0000000..1efbc61 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/database/drivers/sqlite +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +sqlite_driver.php +file + + + + +2009-09-15T00:18:08.000000Z +59478f71c407a11bd80120a7e981a6ac +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +14499 + +sqlite_result.php +file + + + + +2009-09-15T00:18:08.000000Z +1f64ffeb7ba68ee29826aa413017cf88 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3711 + +sqlite_forge.php +file + + + + +2009-09-15T00:18:08.000000Z +5875b96d4edc90fe50fb6619c0a410a2 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5769 + +index.html +file + + + + +2009-09-15T00:18:08.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +sqlite_utility.php +file + + + + +2009-09-15T00:18:08.000000Z +161a2bfecb4ded594f412de7d582945a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3148 + diff --git a/system/database/drivers/sqlite/.svn/prop-base/index.html.svn-base b/system/database/drivers/sqlite/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/sqlite/.svn/prop-base/sqlite_driver.php.svn-base b/system/database/drivers/sqlite/.svn/prop-base/sqlite_driver.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/prop-base/sqlite_driver.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/sqlite/.svn/prop-base/sqlite_forge.php.svn-base b/system/database/drivers/sqlite/.svn/prop-base/sqlite_forge.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/prop-base/sqlite_forge.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/sqlite/.svn/prop-base/sqlite_result.php.svn-base b/system/database/drivers/sqlite/.svn/prop-base/sqlite_result.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/prop-base/sqlite_result.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/sqlite/.svn/prop-base/sqlite_utility.php.svn-base b/system/database/drivers/sqlite/.svn/prop-base/sqlite_utility.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/prop-base/sqlite_utility.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/database/drivers/sqlite/.svn/text-base/index.html.svn-base b/system/database/drivers/sqlite/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/sqlite/.svn/text-base/sqlite_driver.php.svn-base b/system/database/drivers/sqlite/.svn/text-base/sqlite_driver.php.svn-base new file mode 100644 index 0000000..c51edfb --- /dev/null +++ b/system/database/drivers/sqlite/.svn/text-base/sqlite_driver.php.svn-base @@ -0,0 +1,641 @@ +database, 0666, $error)) + { + log_message('error', $error); + + if ($this->db_debug) + { + $this->display_error($error, '', TRUE); + } + + return FALSE; + } + + return $conn_id; + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + if ( ! $conn_id = @sqlite_popen($this->database, 0666, $error)) + { + log_message('error', $error); + + if ($this->db_debug) + { + $this->display_error($error, '', TRUE); + } + + return FALSE; + } + + return $conn_id; + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return sqlite_libversion(); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @sqlite_query($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('BEGIN TRANSACTION'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return sqlite_escape_string($str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return sqlite_changes($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @sqlite_last_insert_rowid($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT name from sqlite_master WHERE type='table'"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " AND 'name' LIKE '".$this->dbprefix."%'"; + } + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + // Not supported + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return sqlite_error_string(sqlite_last_error($this->conn_id)); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return sqlite_last_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + + // other database drivers use this to add backticks, hence this + // function is simply going to return the tablename for sqlite + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "item1 item2" and not "item1 item2" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "field >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1$2$3', $item); + } + else + { + return "{$item}"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " {$exception} ") !== FALSE) + { + $item = preg_replace('/ ('.preg_quote($exception).') /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return $this->_delete($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql."LIMIT ".$offset.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @sqlite_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/.svn/text-base/sqlite_forge.php.svn-base b/system/database/drivers/sqlite/.svn/text-base/sqlite_forge.php.svn-base new file mode 100644 index 0000000..1fd2a2b --- /dev/null +++ b/system/database/drivers/sqlite/.svn/text-base/sqlite_forge.php.svn-base @@ -0,0 +1,234 @@ +db->database) OR ! @unlink($this->db->database)) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unable_to_drop'); + } + return FALSE; + } + return TRUE; + } + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + // IF NOT EXISTS added to SQLite in 3.3.0 + if ($if_not_exists === TRUE && version_compare($this->_version(), '3.3.0', '>=') === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)."("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + $sql .= ",\n\tUNIQUE (" . implode(', ', $keys) . ")"; + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * Unsupported feature in SQLite + * + * @access private + * @return bool + */ + function _drop_table($table) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return array(); + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + // SQLite does not support dropping columns + // http://www.sqlite.org/omitted.html + // http://www.sqlite.org/faq.html#q11 + return FALSE; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/.svn/text-base/sqlite_result.php.svn-base b/system/database/drivers/sqlite/.svn/text-base/sqlite_result.php.svn-base new file mode 100644 index 0000000..b8f3dc5 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/text-base/sqlite_result.php.svn-base @@ -0,0 +1,183 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @sqlite_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = sqlite_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = sqlite_field_name($this->result_id, $i); + $F->type = 'varchar'; + $F->max_length = 0; + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + // Not implemented in SQLite + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return sqlite_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return sqlite_fetch_array($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + if (function_exists('sqlite_fetch_object')) + { + return sqlite_fetch_object($this->result_id); + } + else + { + $arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC); + if (is_array($arr)) + { + $obj = (object) $arr; + return $obj; + } else { + return NULL; + } + } + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/.svn/text-base/sqlite_utility.php.svn-base b/system/database/drivers/sqlite/.svn/text-base/sqlite_utility.php.svn-base new file mode 100644 index 0000000..d1e1fe0 --- /dev/null +++ b/system/database/drivers/sqlite/.svn/text-base/sqlite_utility.php.svn-base @@ -0,0 +1,139 @@ +db_debug) + { + return $this->display_error('db_unsuported_feature'); + } + return array(); + } + + // -------------------------------------------------------------------- + + /** + * Optimize table query + * + * Is optimization even supported in SQLite? + * + * @access private + * @param string the table name + * @return object + */ + function _optimize_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Are table repairs even supported in SQLite? + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * SQLite Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function _create_database() + { + // In SQLite, a database is created when you connect to the database. + // We'll return TRUE so that an error isn't generated + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database)) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unable_to_drop'); + } + return FALSE; + } + return TRUE; + } + +} +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/index.html b/system/database/drivers/sqlite/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/drivers/sqlite/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php new file mode 100755 index 0000000..c51edfb --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_driver.php @@ -0,0 +1,641 @@ +database, 0666, $error)) + { + log_message('error', $error); + + if ($this->db_debug) + { + $this->display_error($error, '', TRUE); + } + + return FALSE; + } + + return $conn_id; + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + if ( ! $conn_id = @sqlite_popen($this->database, 0666, $error)) + { + log_message('error', $error); + + if ($this->db_debug) + { + $this->display_error($error, '', TRUE); + } + + return FALSE; + } + + return $conn_id; + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // TODO - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + return sqlite_libversion(); + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return @sqlite_query($this->conn_id, $sql); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + $this->simple_query('BEGIN TRANSACTION'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('COMMIT'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + $this->simple_query('ROLLBACK'); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @return string + */ + function escape_str($str) + { + return sqlite_escape_string($str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return sqlite_changes($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @access public + * @return integer + */ + function insert_id() + { + return @sqlite_last_insert_rowid($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($this->dbprefix.$table)); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + $sql = "SELECT name from sqlite_master WHERE type='table'"; + + if ($prefix_limit !== FALSE AND $this->dbprefix != '') + { + $sql .= " AND 'name' LIKE '".$this->dbprefix."%'"; + } + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Show column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access public + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + // Not supported + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1"; + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + return sqlite_error_string(sqlite_last_error($this->conn_id)); + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + return sqlite_last_error($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + + // other database drivers use this to add backticks, hence this + // function is simply going to return the tablename for sqlite + return $table; + } + + // -------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function adds backticks if appropriate based on db type + * + * @access private + * @param mixed the item to escape + * @param boolean only affect the first word + * @return mixed the item with backticks + */ + function _protect_identifiers($item, $first_word_only = FALSE) + { + if (is_array($item)) + { + $escaped_array = array(); + + foreach($item as $k=>$v) + { + $escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v, $first_word_only); + } + + return $escaped_array; + } + + // This function may get "item1 item2" as a string, and so + // we may need "item1 item2" and not "item1 item2" + if (ctype_alnum($item) === FALSE) + { + if (strpos($item, '.') !== FALSE) + { + $aliased_tables = implode(".",$this->ar_aliased_tables).'.'; + $table_name = substr($item, 0, strpos($item, '.')+1); + $item = (strpos($aliased_tables, $table_name) !== FALSE) ? $item = $item : $this->dbprefix.$item; + } + + // This function may get "field >= 1", and need it to return "field >= 1" + $lbound = ($first_word_only === TRUE) ? '' : '|\s|\('; + + $item = preg_replace('/(^'.$lbound.')([\w\d\-\_]+?)(\s|\)|$)/iS', '$1$2$3', $item); + } + else + { + return "{$item}"; + } + + $exceptions = array('AS', '/', '-', '%', '+', '*'); + + foreach ($exceptions as $exception) + { + + if (stristr($item, " {$exception} ") !== FALSE) + { + $item = preg_replace('/ ('.preg_quote($exception).') /i', ' $1 ', $item); + } + } + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if (! is_array($tables)) + { + $tables = array($tables); + } + + return '('.implode(', ', $tables).')'; + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where, $orderby = array(), $limit = FALSE) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; + + $sql = "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr); + $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; + $sql .= $orderby.$limit; + + return $sql; + } + + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return $this->_delete($table); + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where = array(), $like = array(), $limit = FALSE) + { + $conditions = ''; + + if (count($where) > 0 || count($like) > 0) + { + $conditions = "\nWHERE "; + $conditions .= implode("\n", $this->ar_where); + + if (count($where) > 0 && count($like) > 0) + { + $conditions .= " AND "; + } + $conditions .= implode("\n", $like); + } + + $limit = (!$limit) ? '' : ' LIMIT '.$limit; + + return "DELETE FROM ".$table.$conditions.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql."LIMIT ".$offset.$limit; + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @sqlite_close($conn_id); + } + + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php new file mode 100755 index 0000000..1fd2a2b --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_forge.php @@ -0,0 +1,234 @@ +db->database) OR ! @unlink($this->db->database)) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unable_to_drop'); + } + return FALSE; + } + return TRUE; + } + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + // IF NOT EXISTS added to SQLite in 3.3.0 + if ($if_not_exists === TRUE && version_compare($this->_version(), '3.3.0', '>=') === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_table($table)."("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (count($keys) > 0) + { + $keys = $this->db->_protect_identifiers($keys); + $sql .= ",\n\tUNIQUE (" . implode(', ', $keys) . ")"; + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Drop Table + * + * Unsupported feature in SQLite + * + * @access private + * @return bool + */ + function _drop_table($table) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unsuported_feature'); + } + return array(); + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + // SQLite does not support dropping columns + // http://www.sqlite.org/omitted.html + // http://www.sqlite.org/faq.html#q11 + return FALSE; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } +} +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php new file mode 100755 index 0000000..b8f3dc5 --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_result.php @@ -0,0 +1,183 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @sqlite_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $field_names[] = sqlite_field_name($this->result_id, $i); + } + + return $field_names; + } + + // Deprecated + function field_names() + { + return $this->list_fields(); + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + for ($i = 0; $i < $this->num_fields(); $i++) + { + $F = new stdClass(); + $F->name = sqlite_field_name($this->result_id, $i); + $F->type = 'varchar'; + $F->max_length = 0; + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + // Not implemented in SQLite + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + return sqlite_seek($this->result_id, $n); + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return sqlite_fetch_array($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + if (function_exists('sqlite_fetch_object')) + { + return sqlite_fetch_object($this->result_id); + } + else + { + $arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC); + if (is_array($arr)) + { + $obj = (object) $arr; + return $obj; + } else { + return NULL; + } + } + } + +} + +?> \ No newline at end of file diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php new file mode 100755 index 0000000..d1e1fe0 --- /dev/null +++ b/system/database/drivers/sqlite/sqlite_utility.php @@ -0,0 +1,139 @@ +db_debug) + { + return $this->display_error('db_unsuported_feature'); + } + return array(); + } + + // -------------------------------------------------------------------- + + /** + * Optimize table query + * + * Is optimization even supported in SQLite? + * + * @access private + * @param string the table name + * @return object + */ + function _optimize_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Repair table query + * + * Are table repairs even supported in SQLite? + * + * @access private + * @param string the table name + * @return object + */ + function _repair_table($table) + { + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * SQLite Export + * + * @access private + * @param array Preferences + * @return mixed + */ + function _backup($params = array()) + { + // Currently unsupported + return $this->db->display_error('db_unsuported_feature'); + } + + /** + * + * The functions below have been deprecated as of 1.6, and are only here for backwards + * compatibility. They now reside in dbforge(). The use of dbutils for database manipulation + * is STRONGLY discouraged in favour if using dbforge. + * + */ + + /** + * Create database + * + * @access public + * @param string the database name + * @return bool + */ + function _create_database() + { + // In SQLite, a database is created when you connect to the database. + // We'll return TRUE so that an error isn't generated + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Drop database + * + * @access private + * @param string the database name + * @return bool + */ + function _drop_database($name) + { + if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database)) + { + if ($this->db->db_debug) + { + return $this->db->display_error('db_unable_to_drop'); + } + return FALSE; + } + return TRUE; + } + +} +?> \ No newline at end of file diff --git a/system/database/index.html b/system/database/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/database/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/fonts/.svn/all-wcprops b/system/fonts/.svn/all-wcprops new file mode 100644 index 0000000..1eb7df4 --- /dev/null +++ b/system/fonts/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 35 +/svn/!svn/ver/18/trunk/system/fonts +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/!svn/ver/18/trunk/system/fonts/index.html +END +texb.ttf +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/!svn/ver/18/trunk/system/fonts/texb.ttf +END diff --git a/system/fonts/.svn/entries b/system/fonts/.svn/entries new file mode 100644 index 0000000..6368a76 --- /dev/null +++ b/system/fonts/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/fonts +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:18:18.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +texb.ttf +file + + + + +2009-09-15T00:18:18.000000Z +6e11f57e02c11c605077f09c086be5fa +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +143821 + diff --git a/system/fonts/.svn/prop-base/index.html.svn-base b/system/fonts/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/fonts/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/fonts/.svn/prop-base/texb.ttf.svn-base b/system/fonts/.svn/prop-base/texb.ttf.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/system/fonts/.svn/prop-base/texb.ttf.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/fonts/.svn/text-base/index.html.svn-base b/system/fonts/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/fonts/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/fonts/.svn/text-base/texb.ttf.svn-base b/system/fonts/.svn/text-base/texb.ttf.svn-base new file mode 100644 index 0000000..a7aa646 Binary files /dev/null and b/system/fonts/.svn/text-base/texb.ttf.svn-base differ diff --git a/system/fonts/index.html b/system/fonts/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/fonts/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/fonts/texb.ttf b/system/fonts/texb.ttf new file mode 100755 index 0000000..a7aa646 Binary files /dev/null and b/system/fonts/texb.ttf differ diff --git a/system/helpers/.svn/all-wcprops b/system/helpers/.svn/all-wcprops new file mode 100644 index 0000000..2bef02d --- /dev/null +++ b/system/helpers/.svn/all-wcprops @@ -0,0 +1,119 @@ +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/!svn/ver/101/trunk/system/helpers +END +path_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/path_helper.php +END +xml_helper.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/helpers/xml_helper.php +END +url_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/101/trunk/system/helpers/url_helper.php +END +smiley_helper.php +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/18/trunk/system/helpers/smiley_helper.php +END +form_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/form_helper.php +END +directory_helper.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/helpers/directory_helper.php +END +html_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/html_helper.php +END +string_helper.php +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/18/trunk/system/helpers/string_helper.php +END +typography_helper.php +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/helpers/typography_helper.php +END +security_helper.php +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/helpers/security_helper.php +END +download_helper.php +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/helpers/download_helper.php +END +cookie_helper.php +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/18/trunk/system/helpers/cookie_helper.php +END +date_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/date_helper.php +END +array_helper.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/helpers/array_helper.php +END +file_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/file_helper.php +END +text_helper.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/helpers/text_helper.php +END +inflector_helper.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/helpers/inflector_helper.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/18/trunk/system/helpers/index.html +END +email_helper.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/helpers/email_helper.php +END diff --git a/system/helpers/.svn/entries b/system/helpers/.svn/entries new file mode 100644 index 0000000..bfc8635 --- /dev/null +++ b/system/helpers/.svn/entries @@ -0,0 +1,674 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/helpers +http://sweetcron.googlecode.com/svn + + + +2008-09-11T14:11:28.940058Z +101 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +path_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +5e0ab331d8d40d3f126359874efa6a12 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1761 + +xml_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +2e249657e0bde8eb5e6be7d75baa7306 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1592 + +url_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +4e2a91f579b8978a01c69df291bdcacb +2008-09-11T14:11:28.940058Z +101 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +12460 + +smiley_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +4327cb7a62fee0424114fad129b4f310 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4329 + +form_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +d0be6072ddd92a9afbbf1940e5210b71 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +12831 + +directory_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +e01158fb1876e78878620534b512e479 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1765 + +html_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +dabb3f12f1b2f0ad03b7140755f60b00 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7081 + +string_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +8387e9aacdd0051c00667c82321c4e6b +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5641 + +typography_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +8abe3f0613879d05ad9ceef0e4e275b2 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +14037 + +security_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +36c844051be7121fd908c3ddefd3df5b +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2647 + +download_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +7aaa44a70c93d91a6a1e87f2154b13a0 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2534 + +cookie_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +417ef048f222653802f3827f10979a19 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3187 + +date_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +c0c635e45e96d433af5eafbf6b711d00 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +13296 + +array_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +4e6a82f5c35f568743bc6700519508be +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1816 + +file_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +9f6ed9b3bd3750e9772a2fe3204c220f +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +11343 + +text_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +5e83cc428cba46401c4c984d2732e829 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +11146 + +inflector_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +b7c77cd61a5897aa3596102688ab6dd0 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3405 + +index.html +file + + + + +2009-09-15T00:17:45.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +email_helper.php +file + + + + +2009-09-15T00:17:45.000000Z +23b652a074c3b1a8724a7e299e1692e7 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1450 + diff --git a/system/helpers/.svn/prop-base/array_helper.php.svn-base b/system/helpers/.svn/prop-base/array_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/array_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/cookie_helper.php.svn-base b/system/helpers/.svn/prop-base/cookie_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/cookie_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/date_helper.php.svn-base b/system/helpers/.svn/prop-base/date_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/date_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/directory_helper.php.svn-base b/system/helpers/.svn/prop-base/directory_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/directory_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/download_helper.php.svn-base b/system/helpers/.svn/prop-base/download_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/download_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/email_helper.php.svn-base b/system/helpers/.svn/prop-base/email_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/email_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/file_helper.php.svn-base b/system/helpers/.svn/prop-base/file_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/file_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/form_helper.php.svn-base b/system/helpers/.svn/prop-base/form_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/form_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/html_helper.php.svn-base b/system/helpers/.svn/prop-base/html_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/html_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/index.html.svn-base b/system/helpers/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/inflector_helper.php.svn-base b/system/helpers/.svn/prop-base/inflector_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/inflector_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/path_helper.php.svn-base b/system/helpers/.svn/prop-base/path_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/path_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/security_helper.php.svn-base b/system/helpers/.svn/prop-base/security_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/security_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/smiley_helper.php.svn-base b/system/helpers/.svn/prop-base/smiley_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/smiley_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/string_helper.php.svn-base b/system/helpers/.svn/prop-base/string_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/string_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/text_helper.php.svn-base b/system/helpers/.svn/prop-base/text_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/text_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/typography_helper.php.svn-base b/system/helpers/.svn/prop-base/typography_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/typography_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/url_helper.php.svn-base b/system/helpers/.svn/prop-base/url_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/url_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/prop-base/xml_helper.php.svn-base b/system/helpers/.svn/prop-base/xml_helper.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/helpers/.svn/prop-base/xml_helper.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/helpers/.svn/text-base/array_helper.php.svn-base b/system/helpers/.svn/text-base/array_helper.php.svn-base new file mode 100644 index 0000000..236e390 --- /dev/null +++ b/system/helpers/.svn/text-base/array_helper.php.svn-base @@ -0,0 +1,76 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/cookie_helper.php.svn-base b/system/helpers/.svn/text-base/cookie_helper.php.svn-base new file mode 100644 index 0000000..102057f --- /dev/null +++ b/system/helpers/.svn/text-base/cookie_helper.php.svn-base @@ -0,0 +1,134 @@ +config->item('cookie_prefix') != '') + { + $prefix = $CI->config->item('cookie_prefix'); + } + if ($domain == '' AND $CI->config->item('cookie_domain') != '') + { + $domain = $CI->config->item('cookie_domain'); + } + if ($path == '/' AND $CI->config->item('cookie_path') != '/') + { + $path = $CI->config->item('cookie_path'); + } + + if ( ! is_numeric($expire)) + { + $expire = time() - 86500; + } + else + { + if ($expire > 0) + { + $expire = time() + $expire; + } + else + { + $expire = 0; + } + } + + setcookie($prefix.$name, $value, $expire, $path, $domain, 0); + } +} + +// -------------------------------------------------------------------- + +/** + * Fetch an item from the COOKIE array + * + * @access public + * @param string + * @param bool + * @return mixed + */ +if (! function_exists('get_cookie')) +{ + function get_cookie($index = '', $xss_clean = FALSE) + { + $CI =& get_instance(); + return $CI->input->cookie($index, $xss_clean); + } +} + +// -------------------------------------------------------------------- + +/** + * Delete a COOKIE + * + * @param mixed + * @param string the cookie domain. Usually: .yourdomain.com + * @param string the cookie path + * @param string the cookie prefix + * @return void + */ +if (! function_exists('delete_cookie')) +{ + function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '') + { + set_cookie($name, '', '', $domain, $path, $prefix); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/date_helper.php.svn-base b/system/helpers/.svn/text-base/date_helper.php.svn-base new file mode 100644 index 0000000..24e0b17 --- /dev/null +++ b/system/helpers/.svn/text-base/date_helper.php.svn-base @@ -0,0 +1,599 @@ +config->item('time_reference')) == 'gmt') + { + $now = time(); + $system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)); + + if (strlen($system_time) < 10) + { + $system_time = time(); + log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.'); + } + + return $system_time; + } + else + { + return time(); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert MySQL Style Datecodes + * + * This function is identical to PHPs date() function, + * except that it allows date codes to be formatted using + * the MySQL style, where each code letter is preceded + * with a percent sign: %Y %m %d etc... + * + * The benefit of doing dates this way is that you don't + * have to worry about escaping your text letters that + * match the date codes. + * + * @access public + * @param string + * @param integer + * @return integer + */ +if (! function_exists('mdate')) +{ + function mdate($datestr = '', $time = '') + { + if ($datestr == '') + return ''; + + if ($time == '') + $time = now(); + + $datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr)); + return date($datestr, $time); + } +} + +// ------------------------------------------------------------------------ + +/** + * Standard Date + * + * Returns a date formatted according to the submitted standard. + * + * @access public + * @param string the chosen format + * @param integer Unix timestamp + * @return string + */ +if (! function_exists('standard_date')) +{ + function standard_date($fmt = 'DATE_RFC822', $time = '') + { + $formats = array( + 'DATE_ATOM' => '%Y-%m-%dT%H:%i:%s%Q', + 'DATE_COOKIE' => '%l, %d-%M-%y %H:%i:%s UTC', + 'DATE_ISO8601' => '%Y-%m-%dT%H:%i:%s%O', + 'DATE_RFC822' => '%D, %d %M %y %H:%i:%s %O', + 'DATE_RFC850' => '%l, %d-%M-%y %H:%m:%i UTC', + 'DATE_RFC1036' => '%D, %d %M %y %H:%i:%s %O', + 'DATE_RFC1123' => '%D, %d %M %Y %H:%i:%s %O', + 'DATE_RSS' => '%D, %d %M %Y %H:%i:%s %O', + 'DATE_W3C' => '%Y-%m-%dT%H:%i:%s%Q' + ); + + if ( ! isset($formats[$fmt])) + { + return FALSE; + } + + return mdate($formats[$fmt], $time); + } +} + +// ------------------------------------------------------------------------ + +/** + * Timespan + * + * Returns a span of seconds in this format: + * 10 days 14 hours 36 minutes 47 seconds + * + * @access public + * @param integer a number of seconds + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('timespan')) +{ + function timespan($seconds = 1, $time = '') + { + $CI =& get_instance(); + $CI->lang->load('date'); + + if ( ! is_numeric($seconds)) + { + $seconds = 1; + } + + if ( ! is_numeric($time)) + { + $time = time(); + } + + if ($time <= $seconds) + { + $seconds = 1; + } + else + { + $seconds = $time - $seconds; + } + + $str = ''; + $years = floor($seconds / 31536000); + + if ($years > 0) + { + $str .= $years.' '.$CI->lang->line((($years > 1) ? 'date_years' : 'date_year')).', '; + } + + $seconds -= $years * 31536000; + $months = floor($seconds / 2628000); + + if ($years > 0 OR $months > 0) + { + if ($months > 0) + { + $str .= $months.' '.$CI->lang->line((($months > 1) ? 'date_months' : 'date_month')).', '; + } + + $seconds -= $months * 2628000; + } + + $weeks = floor($seconds / 604800); + + if ($years > 0 OR $months > 0 OR $weeks > 0) + { + if ($weeks > 0) + { + $str .= $weeks.' '.$CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')).', '; + } + + $seconds -= $weeks * 604800; + } + + $days = floor($seconds / 86400); + + if ($months > 0 OR $weeks > 0 OR $days > 0) + { + if ($days > 0) + { + $str .= $days.' '.$CI->lang->line((($days > 1) ? 'date_days' : 'date_day')).', '; + } + + $seconds -= $days * 86400; + } + + $hours = floor($seconds / 3600); + + if ($days > 0 OR $hours > 0) + { + if ($hours > 0) + { + $str .= $hours.' '.$CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')).', '; + } + + $seconds -= $hours * 3600; + } + + $minutes = floor($seconds / 60); + + if ($days > 0 OR $hours > 0 OR $minutes > 0) + { + if ($minutes > 0) + { + $str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', '; + } + + $seconds -= $minutes * 60; + } + + if ($str == '') + { + $str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', '; + } + + return substr(trim($str), 0, -1); + } +} + +// ------------------------------------------------------------------------ + +/** + * Number of days in a month + * + * Takes a month/year as input and returns the number of days + * for the given month/year. Takes leap years into consideration. + * + * @access public + * @param integer a numeric month + * @param integer a numeric year + * @return integer + */ +if (! function_exists('days_in_month')) +{ + function days_in_month($month = 0, $year = '') + { + if ($month < 1 OR $month > 12) + { + return 0; + } + + if ( ! is_numeric($year) OR strlen($year) != 4) + { + $year = date('Y'); + } + + if ($month == 2) + { + if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0)) + { + return 29; + } + } + + $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + return $days_in_month[$month - 1]; + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts a local Unix timestamp to GMT + * + * @access public + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('local_to_gmt')) +{ + function local_to_gmt($time = '') + { + if ($time == '') + $time = time(); + + return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time)); + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts GMT time to a localized value + * + * Takes a Unix timestamp (in GMT) as input, and returns + * at the local value based on the timezone and DST setting + * submitted + * + * @access public + * @param integer Unix timestamp + * @param string timezone + * @param bool whether DST is active + * @return integer + */ +if (! function_exists('gmt_to_local')) +{ + function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE) + { + if ($time == '') + { + return now(); + } + + $time += timezones($timezone) * 3600; + + if ($dst == TRUE) + { + $time += 3600; + } + + return $time; + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts a MySQL Timestamp to Unix + * + * @access public + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('mysql_to_unix')) +{ + function mysql_to_unix($time = '') + { + // We'll remove certain characters for backward compatibility + // since the formatting changed with MySQL 4.1 + // YYYY-MM-DD HH:MM:SS + + $time = str_replace('-', '', $time); + $time = str_replace(':', '', $time); + $time = str_replace(' ', '', $time); + + // YYYYMMDDHHMMSS + return mktime( + substr($time, 8, 2), + substr($time, 10, 2), + substr($time, 12, 2), + substr($time, 4, 2), + substr($time, 6, 2), + substr($time, 0, 4) + ); + } +} + +// ------------------------------------------------------------------------ + +/** + * Unix to "Human" + * + * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM + * + * @access public + * @param integer Unix timestamp + * @param bool whether to show seconds + * @param string format: us or euro + * @return string + */ +if (! function_exists('unix_to_human')) +{ + function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us') + { + $r = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' '; + + if ($fmt == 'us') + { + $r .= date('h', $time).':'.date('i', $time); + } + else + { + $r .= date('H', $time).':'.date('i', $time); + } + + if ($seconds) + { + $r .= ':'.date('s', $time); + } + + if ($fmt == 'us') + { + $r .= ' '.date('A', $time); + } + + return $r; + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert "human" date to GMT + * + * Reverses the above process + * + * @access public + * @param string format: us or euro + * @return integer + */ +if (! function_exists('human_to_unix')) +{ + function human_to_unix($datestr = '') + { + if ($datestr == '') + { + return FALSE; + } + + $datestr = trim($datestr); + $datestr = preg_replace("/\040+/", "\040", $datestr); + + if ( ! ereg("^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\040[0-9]{1,2}:[0-9]{1,2}.*$", $datestr)) + { + return FALSE; + } + + $split = preg_split("/\040/", $datestr); + + $ex = explode("-", $split['0']); + + $year = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0']; + $month = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1']; + $day = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2']; + + $ex = explode(":", $split['1']); + + $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0']; + $min = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1']; + + if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2'])) + { + $sec = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2']; + } + else + { + // Unless specified, seconds get set to zero. + $sec = '00'; + } + + if (isset($split['2'])) + { + $ampm = strtolower($split['2']); + + if (substr($ampm, 0, 1) == 'p' AND $hour < 12) + $hour = $hour + 12; + + if (substr($ampm, 0, 1) == 'a' AND $hour == 12) + $hour = '00'; + + if (strlen($hour) == 1) + $hour = '0'.$hour; + } + + return mktime($hour, $min, $sec, $month, $day, $year); + } +} + +// ------------------------------------------------------------------------ + +/** + * Timezone Menu + * + * Generates a drop-down menu of timezones. + * + * @access public + * @param string timezone + * @param string classname + * @param string menu name + * @return string + */ +if (! function_exists('timezone_menu')) +{ + function timezone_menu($default = 'UTC', $class = "", $name = 'timezones') + { + $CI =& get_instance(); + $CI->lang->load('date'); + + if ($default == 'GMT') + $default = 'UTC'; + + $menu = '"; + + return $menu; + } +} + +// ------------------------------------------------------------------------ + +/** + * Timezones + * + * Returns an array of timezones. This is a helper function + * for various other ones in this library + * + * @access public + * @param string timezone + * @return string + */ +if (! function_exists('timezones')) +{ + function timezones($tz = '') + { + // Note: Don't change the order of these even though + // some items appear to be in the wrong order + + $zones = array( + 'UM12' => -12, + 'UM11' => -11, + 'UM10' => -10, + 'UM9' => -9, + 'UM8' => -8, + 'UM7' => -7, + 'UM6' => -6, + 'UM5' => -5, + 'UM4' => -4, + 'UM25' => -2.5, + 'UM3' => -3, + 'UM2' => -2, + 'UM1' => -1, + 'UTC' => 0, + 'UP1' => +1, + 'UP2' => +2, + 'UP3' => +3, + 'UP25' => +2.5, + 'UP4' => +4, + 'UP35' => +3.5, + 'UP5' => +5, + 'UP45' => +4.5, + 'UP6' => +6, + 'UP7' => +7, + 'UP8' => +8, + 'UP9' => +9, + 'UP85' => +8.5, + 'UP10' => +10, + 'UP11' => +11, + 'UP12' => +12 + ); + + if ($tz == '') + { + return $zones; + } + + if ($tz == 'GMT') + $tz = 'UTC'; + + return ( ! isset($zones[$tz])) ? 0 : $zones[$tz]; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/directory_helper.php.svn-base b/system/helpers/.svn/text-base/directory_helper.php.svn-base new file mode 100644 index 0000000..5a23944 --- /dev/null +++ b/system/helpers/.svn/text-base/directory_helper.php.svn-base @@ -0,0 +1,69 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/download_helper.php.svn-base b/system/helpers/.svn/text-base/download_helper.php.svn-base new file mode 100644 index 0000000..2d0e737 --- /dev/null +++ b/system/helpers/.svn/text-base/download_helper.php.svn-base @@ -0,0 +1,98 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/email_helper.php.svn-base b/system/helpers/.svn/text-base/email_helper.php.svn-base new file mode 100644 index 0000000..e677afd --- /dev/null +++ b/system/helpers/.svn/text-base/email_helper.php.svn-base @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/file_helper.php.svn-base b/system/helpers/.svn/text-base/file_helper.php.svn-base new file mode 100644 index 0000000..aed2502 --- /dev/null +++ b/system/helpers/.svn/text-base/file_helper.php.svn-base @@ -0,0 +1,461 @@ + 0) + { + $data =& fread($fp, filesize($file)); + } + + flock($fp, LOCK_UN); + fclose($fp); + + return $data; + } +} + +// ------------------------------------------------------------------------ + +/** + * Write File + * + * Writes data to the file specified in the path. + * Creates a new file if non-existent. + * + * @access public + * @param string path to file + * @param string file data + * @return bool + */ +if ( ! function_exists('write_file')) +{ + function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE) + { + if ( ! $fp = @fopen($path, $mode)) + { + return FALSE; + } + + flock($fp, LOCK_EX); + fwrite($fp, $data); + flock($fp, LOCK_UN); + fclose($fp); + + return TRUE; + } +} + +// ------------------------------------------------------------------------ + +/** + * Delete Files + * + * Deletes all files contained in the supplied directory path. + * Files must be writable or owned by the system in order to be deleted. + * If the second parameter is set to TRUE, any directories contained + * within the supplied base directory will be nuked as well. + * + * @access public + * @param string path to file + * @param bool whether to delete any directories found in the path + * @return bool + */ +if ( ! function_exists('delete_files')) +{ + function delete_files($path, $del_dir = FALSE, $level = 0) + { + // Trim the trailing slash + $path = preg_replace("|^(.+?)/*$|", "\\1", $path); + + if ( ! $current_dir = @opendir($path)) + return; + + while(FALSE !== ($filename = @readdir($current_dir))) + { + if ($filename != "." and $filename != "..") + { + if (is_dir($path.'/'.$filename)) + { + delete_files($path.'/'.$filename, $del_dir, $level + 1); + } + else + { + unlink($path.'/'.$filename); + } + } + } + @closedir($current_dir); + + if ($del_dir == TRUE AND $level > 0) + { + @rmdir($path); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Get Filenames + * + * Reads the specified directory and builds an array containing the filenames. + * Any sub-folders contained within the specified path are read as well. + * + * @access public + * @param string path to source + * @param bool whether to include the path as part of the filename + * @param bool internal variable to determine recursion status - do not use in calls + * @return array + */ +if ( ! function_exists('get_filenames')) +{ + function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE) + { + static $_filedata = array(); + + if ($fp = @opendir($source_dir)) + { + // reset the array and make sure $source_dir has a trailing slash on the initial call + if ($_recursion === FALSE) + { + $_filedata = array(); + $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; + } + + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0) + { + get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); + } + elseif (strncmp($file, '.', 1) !== 0) + { + + $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file; + } + } + return $_filedata; + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** + * Get Directory File Information + * + * Reads the specified directory and builds an array containing the filenames, + * filesize, dates, and permissions + * + * Any sub-folders contained within the specified path are read as well. + * + * @access public + * @param string path to source + * @param bool whether to include the path as part of the filename + * @param bool internal variable to determine recursion status - do not use in calls + * @return array + */ +if ( ! function_exists('get_dir_file_info')) +{ + function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE) + { + $_filedata = array(); + $relative_path = $source_dir; + + if ($fp = @opendir($source_dir)) + { + // reset the array and make sure $source_dir has a trailing slash on the initial call + if ($_recursion === FALSE) + { + $_filedata = array(); + $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; + } + + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0) + { + get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); + } + elseif (strncmp($file, '.', 1) !== 0) + { + $_filedata[$file] = get_file_info($source_dir.$file); + $_filedata[$file]['relative_path'] = $relative_path; + } + } + return $_filedata; + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** +* Get File Info +* +* Given a file and path, returns the name, path, size, date modified +* Second parameter allows you to explicitly declare what information you want returned +* Options are: name, server_path, size, date, readable, writable, executable, fileperms +* Returns FALSE if the file cannot be found. +* +* @access public +* @param string path to file +* @param mixed array or comma separated string of information returned +* @return array +*/ +if ( ! function_exists('get_file_info')) +{ + function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) + { + + if ( ! file_exists($file)) + { + return FALSE; + } + + if (is_string($returned_values)) + { + $returned_values = explode(',', $returned_values); + } + + foreach ($returned_values as $key) + { + switch ($key) + { + case 'name': + $fileinfo['name'] = substr(strrchr($file, '/'), 1); + break; + case 'server_path': + $fileinfo['server_path'] = $file; + break; + case 'size': + $fileinfo['size'] = filesize($file); + break; + case 'date': + $fileinfo['date'] = filectime($file); + break; + case 'readable': + $fileinfo['readable'] = is_readable($file); + break; + case 'writable': + // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms() + $fileinfo['writable'] = is_writable($file); + break; + case 'executable': + $fileinfo['executable'] = is_executable($file); + break; + case 'fileperms': + $fileinfo['fileperms'] = fileperms($file); + break; + } + } + + return $fileinfo; + } +} + +// -------------------------------------------------------------------- + +/** + * Get Mime by Extension + * + * Translates a file extension into a mime type based on config/mimes.php. + * Returns FALSE if it can't determine the type, or open the mime config file + * + * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience + * It should NOT be trusted, and should certainly NOT be used for security + * + * @access public + * @param string path to file + * @return mixed + */ +if ( ! function_exists('get_mime_by_extension')) +{ + function get_mime_by_extension($file) + { + $extension = substr(strrchr($file, '.'), 1); + + global $mimes; + + if ( ! is_array($mimes)) + { + if ( ! require_once(APPPATH.'config/mimes.php')) + { + return FALSE; + } + } + + if (array_key_exists($extension, $mimes)) + { + if (is_array($mimes[$extension])) + { + // Multiple mime types, just give the first one + return current($mimes[$extension]); + } + else + { + return $mimes[$extension]; + } + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** + * Symbolic Permissions + * + * Takes a numeric value representing a file's permissions and returns + * standard symbolic notation representing that value + * + * @access public + * @param int + * @return string + */ +if ( ! function_exists('symbolic_permissions')) +{ + function symbolic_permissions($perms) + { + if (($perms & 0xC000) == 0xC000) + { + $symbolic = 's'; // Socket + } + elseif (($perms & 0xA000) == 0xA000) + { + $symbolic = 'l'; // Symbolic Link + } + elseif (($perms & 0x8000) == 0x8000) + { + $symbolic = '-'; // Regular + } + elseif (($perms & 0x6000) == 0x6000) + { + $symbolic = 'b'; // Block special + } + elseif (($perms & 0x4000) == 0x4000) + { + $symbolic = 'd'; // Directory + } + elseif (($perms & 0x2000) == 0x2000) + { + $symbolic = 'c'; // Character special + } + elseif (($perms & 0x1000) == 0x1000) + { + $symbolic = 'p'; // FIFO pipe + } + else + { + $symbolic = 'u'; // Unknown + } + + // Owner + $symbolic .= (($perms & 0x0100) ? 'r' : '-'); + $symbolic .= (($perms & 0x0080) ? 'w' : '-'); + $symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); + + // Group + $symbolic .= (($perms & 0x0020) ? 'r' : '-'); + $symbolic .= (($perms & 0x0010) ? 'w' : '-'); + $symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); + + // World + $symbolic .= (($perms & 0x0004) ? 'r' : '-'); + $symbolic .= (($perms & 0x0002) ? 'w' : '-'); + $symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); + + return $symbolic; + } +} + +// -------------------------------------------------------------------- + +/** + * Octal Permissions + * + * Takes a numeric value representing a file's permissions and returns + * a three character string representing the file's octal permissions + * + * @access public + * @param int + * @return string + */ +if ( ! function_exists('octal_permissions')) +{ + function octal_permissions($perms) + { + return substr(sprintf('%o', $perms), -3); + } +} + + +/* End of file file_helper.php */ +/* Location: ./system/helpers/file_helper.php */ \ No newline at end of file diff --git a/system/helpers/.svn/text-base/form_helper.php.svn-base b/system/helpers/.svn/text-base/form_helper.php.svn-base new file mode 100644 index 0000000..7c3b16f --- /dev/null +++ b/system/helpers/.svn/text-base/form_helper.php.svn-base @@ -0,0 +1,586 @@ +config->site_url($action) : $action; + + $form = '
    0) + { + foreach ($attributes as $key => $val) + { + $form .= ' '.$key.'="'.$val.'"'; + } + } + + $form .= '>'; + + if (is_array($hidden) AND count($hidden > 0)) + { + $form .= form_hidden($hidden); + } + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Declaration - Multipart type + * + * Creates the opening portion of the form, but with "multipart/form-data". + * + * @access public + * @param string the URI segments of the form destination + * @param array a key/value pair of attributes + * @param array a key/value pair hidden data + * @return string + */ +if (! function_exists('form_open_multipart')) +{ + function form_open_multipart($action, $attributes = array(), $hidden = array()) + { + $attributes['enctype'] = 'multipart/form-data'; + return form_open($action, $attributes, $hidden); + } +} + +// ------------------------------------------------------------------------ + +/** + * Hidden Input Field + * + * Generates hidden fields. You can pass a simple key/value string or an associative + * array with multiple values. + * + * @access public + * @param mixed + * @param string + * @return string + */ +if (! function_exists('form_hidden')) +{ + function form_hidden($name, $value = '') + { + if ( ! is_array($name)) + { + return ''; + } + + $form = ''; + foreach ($name as $name => $value) + { + $form .= ''; + } + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Text Input Field + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_input')) +{ + function form_input($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value, 'maxlength' => '500', 'size' => '50'); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Password Field + * + * Identical to the input function but adds the "password" type + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_password')) +{ + function form_password($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'password'; + return form_input($data, $value, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Upload Field + * + * Identical to the input function but adds the "file" type + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_upload')) +{ + function form_upload($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'file'; + return form_input($data, $value, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Textarea field + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_textarea')) +{ + function form_textarea($data = '', $value = '', $extra = '') + { + $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12'); + + if ( ! is_array($data) OR ! isset($data['value'])) + { + $val = $value; + } + else + { + $val = $data['value']; + unset($data['value']); // textareas don't use the value attribute + } + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Drop-down Menu + * + * @access public + * @param string + * @param array + * @param string + * @param string + * @return string + */ +if (! function_exists('form_dropdown')) +{ + function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '') + { + if ( ! is_array($selected)) + { + $selected = array($selected); + } + + if ($extra != '') $extra = ' '.$extra; + + $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; + + $form = ''; + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Checkbox Field + * + * @access public + * @param mixed + * @param string + * @param bool + * @param string + * @return string + */ +if (! function_exists('form_checkbox')) +{ + function form_checkbox($data = '', $value = '', $checked = TRUE, $extra = '') + { + $defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + if (is_array($data) AND array_key_exists('checked', $data)) + { + $checked = $data['checked']; + + if ($checked == FALSE) + { + unset($data['checked']); + } + else + { + $data['checked'] = 'checked'; + } + } + + if ($checked == TRUE) + $defaults['checked'] = 'checked'; + else + unset($defaults['checked']); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Radio Button + * + * @access public + * @param mixed + * @param string + * @param bool + * @param string + * @return string + */ +if (! function_exists('form_radio')) +{ + function form_radio($data = '', $value = '', $checked = TRUE, $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'radio'; + return form_checkbox($data, $value, $checked, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Submit Button + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_submit')) +{ + function form_submit($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Reset Button + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_reset')) +{ + function form_reset($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Label Tag + * + * @access public + * @param string The text to appear onscreen + * @param string The id the label applies to + * @param string Additional attributes + * @return string + */ +if (! function_exists('form_label')) +{ + function form_label($label_text = '', $id = '', $attributes = array()) + { + + $label = ' 0) + { + foreach ($attributes as $key => $val) + { + $label .= ' '.$key.'="'.$val.'"'; + } + } + + $label .= ">$label_text"; + + return $label; + } +} + +// ------------------------------------------------------------------------ +/** + * Fieldset Tag + * + * Used to produce

    text. To close fieldset + * use form_fieldset_close() + * + * @access public + * @param string The legend text + * @param string Additional attributes + * @return string + */ +if (! function_exists('form_fieldset')) +{ + function form_fieldset($legend_text = '', $attributes = array()) + { + + $fieldset = " 0) + { + foreach ($attributes as $key => $val) + { + $fieldset .= ' '.$key.'="'.$val.'"'; + } + } + + $fieldset .= ">\n"; + + if ($legend_text != '') + { + $fieldset .= "$legend_text\n"; + } + + + + return $fieldset; + } +} + +// ------------------------------------------------------------------------ + +/** + * Fieldset Close Tag + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_fieldset_close')) +{ + function form_fieldset_close($extra = '') + { + return "
    \n".$extra; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Close Tag + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_close')) +{ + function form_close($extra = '') + { + return "\n".$extra; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Prep + * + * Formats text so that it can be safely placed in a form field in the event it has HTML tags. + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_prep')) +{ + function form_prep($str = '') + { + if ($str === '') + { + return ''; + } + + $temp = '__TEMP_AMPERSANDS__'; + + // Replace entities to temporary markers so that + // htmlspecialchars won't mess them up + $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); + $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); + + $str = htmlspecialchars($str); + + // In case htmlspecialchars misses these. + $str = str_replace(array("'", '"'), array("'", """), $str); + + // Decode the temp markers back to entities + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;",$str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse the form attributes + * + * Helper function used by some of the form helpers + * + * @access private + * @param array + * @param array + * @return string + */ +if (! function_exists('parse_form_attributes')) +{ + function parse_form_attributes($attributes, $default) + { + if (is_array($attributes)) + { + foreach ($default as $key => $val) + { + if (isset($attributes[$key])) + { + $default[$key] = $attributes[$key]; + unset($attributes[$key]); + } + } + + if (count($attributes) > 0) + { + $default = array_merge($default, $attributes); + } + } + + $att = ''; + foreach ($default as $key => $val) + { + if ($key == 'value') + { + $val = form_prep($val); + } + + $att .= $key . '="' . $val . '" '; + } + + return $att; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/html_helper.php.svn-base b/system/helpers/.svn/text-base/html_helper.php.svn-base new file mode 100644 index 0000000..0c88450 --- /dev/null +++ b/system/helpers/.svn/text-base/html_helper.php.svn-base @@ -0,0 +1,354 @@ +".$data.""; + } +} + +// ------------------------------------------------------------------------ + +/** + * Unordered List + * + * Generates an HTML unordered list from an single or multi-dimensional array. + * + * @access public + * @param array + * @param mixed + * @return string + */ +if (! function_exists('ul')) +{ + function ul($list, $attributes = '') + { + return _list('ul', $list, $attributes); + } +} + +// ------------------------------------------------------------------------ + +/** + * Ordered List + * + * Generates an HTML ordered list from an single or multi-dimensional array. + * + * @access public + * @param array + * @param mixed + * @return string + */ +if (! function_exists('ol')) +{ + function ol($list, $attributes = '') + { + return _list('ol', $list, $attributes); + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates the list + * + * Generates an HTML ordered list from an single or multi-dimensional array. + * + * @access private + * @param string + * @param mixed + * @param mixed + * @param intiger + * @return string + */ +if (! function_exists('_list')) +{ + function _list($type = 'ul', $list, $attributes = '', $depth = 0) + { + // If an array wasn't submitted there's nothing to do... + if ( ! is_array($list)) + { + return $list; + } + + // Set the indentation based on the depth + $out = str_repeat(" ", $depth); + + // Were any attributes submitted? If so generate a string + if (is_array($attributes)) + { + $atts = ''; + foreach ($attributes as $key => $val) + { + $atts .= ' ' . $key . '="' . $val . '"'; + } + $attributes = $atts; + } + + // Write the opening list tag + $out .= "<".$type.$attributes.">\n"; + + // Cycle through the list elements. If an array is + // encountered we will recursively call _list() + + static $_last_list_item = ''; + foreach ($list as $key => $val) + { + $_last_list_item = $key; + + $out .= str_repeat(" ", $depth + 2); + $out .= "
  • "; + + if ( ! is_array($val)) + { + $out .= $val; + } + else + { + $out .= $_last_list_item."\n"; + $out .= _list($type, $val, '', $depth + 4); + $out .= str_repeat(" ", $depth + 2); + } + + $out .= "
  • \n"; + } + + // Set the indentation for the closing tag + $out .= str_repeat(" ", $depth); + + // Write the closing list tag + $out .= "\n"; + + return $out; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates HTML BR tags based on number supplied + * + * @access public + * @param integer + * @return string + */ +if (! function_exists('br')) +{ + function br($num = 1) + { + return str_repeat("
    ", $num); + } +} + +// ------------------------------------------------------------------------ + +/** + * Image + * + * Generates an element + * + * @access public + * @param mixed + * @return string + */ +if (! function_exists('img')) +{ + function img($src = '', $index_page = FALSE) + { + if ( ! is_array($src) ) + { + $src = array('src' => $src); + } + + $img = '$v) + { + + if ($k == 'src' AND strpos($v, '://') === FALSE) + { + $CI =& get_instance(); + + if ($index_page === TRUE) + { + $img .= ' src="'.$CI->config->site_url($v).'" '; + } + else + { + $img .= ' src="'.$CI->config->slash_item('base_url').$v.'" '; + } + } + else + { + $img .= " $k=\"$v\" "; + } + } + + $img .= '/>'; + + return $img; + } +} + +// ------------------------------------------------------------------------ + +/** + * Link + * + * Generates link to a CSS file + * + * @access public + * @param mixed stylesheet hrefs or an array + * @param string rel + * @param string type + * @param string title + * @param string media + * @param boolean should index_page be added to the css path + * @return string + */ +if (! function_exists('link_tag')) +{ + function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE) + { + $CI =& get_instance(); + + $link = '$v) + { + if ($k == 'href' AND strpos($k, '://') === FALSE) + { + if ($index_page === TRUE) + { + $link .= ' href="'.$CI->config->site_url($v).'" '; + } + else + { + $link .= ' href="'.$CI->config->slash_item('base_url').$v.'" '; + } + } + else + { + $link .= "$k=\"$v\" "; + } + } + + $link .= "/>\n"; + } + else + { + if ( strpos($href, '://') !== FALSE) + { + $link .= ' href="'.$href.'" '; + } + elseif ($index_page === TRUE) + { + $link .= ' href="'.$CI->config->site_url($href).'" '; + } + else + { + $link .= ' href="'.$CI->config->slash_item('base_url').$href.'" '; + } + + $link .= 'rel="'.$rel.'" type="'.$type.'" '; + + if ($media != '') + { + $link .= 'media="'.$media.'" '; + } + + if ($title != '') + { + $link .= 'title="'.$title.'" '; + } + + $link .= '/>'."\n"; + } + + + return $link; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates meta tags from an array of key/values + * + * @access public + * @param array + * @return string + */ +if (! function_exists('meta')) +{ + function meta($meta = array(), $newline = "\n") + { + $str = ''; + foreach ($meta as $key => $val) + { + $str .= ''.$newline; + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates non-breaking space entities based on number supplied + * + * @access public + * @param integer + * @return string + */ +if (! function_exists('nbs')) +{ + function nbs($num = 1) + { + return str_repeat(" ", $num); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/index.html.svn-base b/system/helpers/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/helpers/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/inflector_helper.php.svn-base b/system/helpers/.svn/text-base/inflector_helper.php.svn-base new file mode 100644 index 0000000..bf70a67 --- /dev/null +++ b/system/helpers/.svn/text-base/inflector_helper.php.svn-base @@ -0,0 +1,167 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/path_helper.php.svn-base b/system/helpers/.svn/text-base/path_helper.php.svn-base new file mode 100644 index 0000000..30d26d6 --- /dev/null +++ b/system/helpers/.svn/text-base/path_helper.php.svn-base @@ -0,0 +1,70 @@ + \ No newline at end of file diff --git a/system/helpers/.svn/text-base/security_helper.php.svn-base b/system/helpers/.svn/text-base/security_helper.php.svn-base new file mode 100644 index 0000000..7552fd8 --- /dev/null +++ b/system/helpers/.svn/text-base/security_helper.php.svn-base @@ -0,0 +1,124 @@ +input->xss_clean($str, $charset); + } +} + +// -------------------------------------------------------------------- + +/** + * Hash encode a string + * + * @access public + * @param string + * @return string + */ +if (! function_exists('dohash')) +{ + function dohash($str, $type = 'sha1') + { + if ($type == 'sha1') + { + if ( ! function_exists('sha1')) + { + if ( ! function_exists('mhash')) + { + require_once(BASEPATH.'libraries/Sha1'.EXT); + $SH = new CI_SHA; + return $SH->generate($str); + } + else + { + return bin2hex(mhash(MHASH_SHA1, $str)); + } + } + else + { + return sha1($str); + } + } + else + { + return md5($str); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Strip Image Tags + * + * @access public + * @param string + * @return string + */ +if (! function_exists('strip_image_tags')) +{ + function strip_image_tags($str) + { + $str = preg_replace("##", "\\1", $str); + $str = preg_replace("##", "\\1", $str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert PHP tags to entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('encode_php_tags')) +{ + function encode_php_tags($str) + { + return str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/smiley_helper.php.svn-base b/system/helpers/.svn/text-base/smiley_helper.php.svn-base new file mode 100644 index 0000000..25962eb --- /dev/null +++ b/system/helpers/.svn/text-base/smiley_helper.php.svn-base @@ -0,0 +1,173 @@ + + function insert_smiley(smiley) + { + document.{$form_name}.{$form_field}.value += " " + smiley; + } + +EOF; + } +} +// ------------------------------------------------------------------------ + +/** + * Get Clickable Smileys + * + * Returns an array of image tag links that can be clicked to be inserted + * into a form field. + * + * @access public + * @param string the URL to the folder containing the smiley images + * @return array + */ +if (! function_exists('get_clickable_smileys')) +{ + function get_clickable_smileys($image_url = '', $smileys = NULL) + { + if ( ! is_array($smileys)) + { + if (FALSE === ($smileys = _get_smiley_array())) + { + return $smileys; + } + } + + // Add a trailing slash to the file path if needed + $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url); + + $used = array(); + foreach ($smileys as $key => $val) + { + // Keep duplicates from being used, which can happen if the + // mapping array contains multiple identical replacements. For example: + // :-) and :) might be replaced with the same image so both smileys + // will be in the array. + if (isset($used[$smileys[$key][0]])) + { + continue; + } + + $link[] = "\"".$smileys[$key][3]."\""; + + $used[$smileys[$key][0]] = TRUE; + } + + return $link; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse Smileys + * + * Takes a string as input and swaps any contained smileys for the actual image + * + * @access public + * @param string the text to be parsed + * @param string the URL to the folder containing the smiley images + * @return string + */ +if (! function_exists('parse_smileys')) +{ + function parse_smileys($str = '', $image_url = '', $smileys = NULL) + { + if ($image_url == '') + { + return $str; + } + + if ( ! is_array($smileys)) + { + if (FALSE === ($smileys = _get_smiley_array())) + { + return $str; + } + } + + // Add a trailing slash to the file path if needed + $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url); + + foreach ($smileys as $key => $val) + { + $str = str_replace($key, "\"".$smileys[$key][3]."\"", $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Get Smiley Array + * + * Fetches the config/smiley.php file + * + * @access private + * @return mixed + */ +if (! function_exists('_get_smiley_array')) +{ + function _get_smiley_array() + { + if ( ! file_exists(APPPATH.'config/smileys'.EXT)) + { + return FALSE; + } + + include(APPPATH.'config/smileys'.EXT); + + if ( ! isset($smileys) OR ! is_array($smileys)) + { + return FALSE; + } + + return $smileys; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/string_helper.php.svn-base b/system/helpers/.svn/text-base/string_helper.php.svn-base new file mode 100644 index 0000000..f68f44a --- /dev/null +++ b/system/helpers/.svn/text-base/string_helper.php.svn-base @@ -0,0 +1,271 @@ + $val) + { + $str[$key] = strip_slashes($val); + } + } + else + { + $str = stripslashes($str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Strip Quotes + * + * Removes single and double quotes from a string + * + * @access public + * @param string + * @return string + */ +if (! function_exists('strip_quotes')) +{ + function strip_quotes($str) + { + return str_replace(array('"', "'"), '', $str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Quotes to Entities + * + * Converts single and double quotes to entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('quotes_to_entities')) +{ + function quotes_to_entities($str) + { + return str_replace(array("\'","\"","'",'"'), array("'",""","'","""), $str); + } +} + +// ------------------------------------------------------------------------ +/** + * Reduce Double Slashes + * + * Converts double slashes in a string to a single slash, + * except those found in http:// + * + * http://www.some-site.com//index.php + * + * becomes: + * + * http://www.some-site.com/index.php + * + * @access public + * @param string + * @return string + */ +if (! function_exists('reduce_double_slashes')) +{ + function reduce_double_slashes($str) + { + return preg_replace("#([^:])//+#", "\\1/", $str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Reduce Multiples + * + * Reduces multiple instances of a particular character. Example: + * + * Fred, Bill,, Joe, Jimmy + * + * becomes: + * + * Fred, Bill, Joe, Jimmy + * + * @access public + * @param string + * @param string the character you wish to reduce + * @param bool TRUE/FALSE - whether to trim the character from the beginning/end + * @return string + */ +if (! function_exists('reduce_multiples')) +{ + function reduce_multiples($str, $character = ',', $trim = FALSE) + { + $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str); + + if ($trim === TRUE) + { + $str = trim($str, $character); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Create a Random String + * + * Useful for generating passwords or hashes. + * + * @access public + * @param string type of random string. Options: alunum, numeric, nozero, unique + * @param integer number of characters + * @return string + */ +if (! function_exists('random_string')) +{ + function random_string($type = 'alnum', $len = 8) + { + switch($type) + { + case 'alnum' : + case 'numeric' : + case 'nozero' : + + switch ($type) + { + case 'alnum' : $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + break; + case 'numeric' : $pool = '0123456789'; + break; + case 'nozero' : $pool = '123456789'; + break; + } + + $str = ''; + for ($i=0; $i < $len; $i++) + { + $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); + } + return $str; + break; + case 'unique' : return md5(uniqid(mt_rand())); + break; + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Alternator + * + * Allows strings to be alternated. See docs... + * + * @access public + * @param string (as many parameters as needed) + * @return string + */ +if (! function_exists('alternator')) +{ + function alternator() + { + static $i; + + if (func_num_args() == 0) + { + $i = 0; + return ''; + } + $args = func_get_args(); + return $args[($i++ % count($args))]; + } +} + +// ------------------------------------------------------------------------ + +/** + * Repeater function + * + * @access public + * @param string + * @param integer number of repeats + * @return string + */ +if (! function_exists('repeater')) +{ + function repeater($data, $num = 1) + { + return (($num > 0) ? str_repeat($data, $num) : ''); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/text_helper.php.svn-base b/system/helpers/.svn/text-base/text_helper.php.svn-base new file mode 100644 index 0000000..21ab778 --- /dev/null +++ b/system/helpers/.svn/text-base/text_helper.php.svn-base @@ -0,0 +1,439 @@ += $n) + { + return trim($out).$end_char; + } + } + } +} + +// ------------------------------------------------------------------------ + +/** + * High ASCII to Entities + * + * Converts High ascii text and MS Word special characters to character entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('ascii_to_entities')) +{ + function ascii_to_entities($str) + { + $count = 1; + $out = ''; + $temp = array(); + + for ($i = 0, $s = strlen($str); $i < $s; $i++) + { + $ordinal = ord($str[$i]); + + if ($ordinal < 128) + { + $out .= $str[$i]; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + + $out .= '&#'.$number.';'; + $count = 1; + $temp = array(); + } + } + } + + return $out; + } +} + +// ------------------------------------------------------------------------ + +/** + * Entities to ASCII + * + * Converts character entities back to ASCII + * + * @access public + * @param string + * @param bool + * @return string + */ +if (! function_exists('entities_to_ascii')) +{ + function entities_to_ascii($str, $all = TRUE) + { + if (preg_match_all('/\&#(\d+)\;/', $str, $matches)) + { + for ($i = 0, $s = count($matches['0']); $i < $s; $i++) + { + $digits = $matches['1'][$i]; + + $out = ''; + + if ($digits < 128) + { + $out .= chr($digits); + + } + elseif ($digits < 2048) + { + $out .= chr(192 + (($digits - ($digits % 64)) / 64)); + $out .= chr(128 + ($digits % 64)); + } + else + { + $out .= chr(224 + (($digits - ($digits % 4096)) / 4096)); + $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64)); + $out .= chr(128 + ($digits % 64)); + } + + $str = str_replace($matches['0'][$i], $out, $str); + } + } + + if ($all) + { + $str = str_replace(array("&", "<", ">", """, "'", "-"), + array("&","<",">","\"", "'", "-"), + $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Word Censoring Function + * + * Supply a string and an array of disallowed words and any + * matched words will be converted to #### or to the replacement + * word you've submitted. + * + * @access public + * @param string the text string + * @param string the array of censoered words + * @param string the optional replacement value + * @return string + */ +if (! function_exists('word_censor')) +{ + function word_censor($str, $censored, $replacement = '') + { + if ( ! is_array($censored)) + { + return $str; + } + + $str = ' '.$str.' '; + foreach ($censored as $badword) + { + if ($replacement != '') + { + $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/i", $replacement, $str); + } + else + { + $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/ie", "str_repeat('#', strlen('\\1'))", $str); + } + } + + return trim($str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Code Highlighter + * + * Colorizes code strings + * + * @access public + * @param string the text string + * @return string + */ +if (! function_exists('highlight_code')) +{ + function highlight_code($str) + { + // The highlight string function encodes and highlights + // brackets so we need them to start raw + $str = str_replace(array('<', '>'), array('<', '>'), $str); + + // Replace any existing PHP tags to temporary markers so they don't accidentally + // break the string out of PHP, and thus, thwart the highlighting. + + $str = str_replace(array('', '<%', '%>', '\\', ''), + array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str); + + // The highlight_string function requires that the text be surrounded + // by PHP tags. Since we don't know if A) the submitted text has PHP tags, + // or B) whether the PHP tags enclose the entire string, we will add our + // own PHP tags around the string along with some markers to make replacement easier later + + $str = ''; + + // All the magic happens here, baby! + $str = highlight_string($str, TRUE); + + // Prior to PHP 5, the highlight function used icky font tags + // so we'll replace them with span tags. + if (abs(phpversion()) < 5) + { + $str = str_replace(array(''), array(''), $str); + $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str); + } + + // Remove our artificially added PHP + $str = preg_replace("#\.+?tempstart\
    (?:\)?#is", "\n", $str); + $str = preg_replace("#tempend.+#is", "
    \n", $str); + + // Replace our markers back to PHP tags. + $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), + array('<?', '?>', '<%', '%>', '\\', '</script>'), $str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Phrase Highlighter + * + * Highlights a phrase within a text string + * + * @access public + * @param string the text string + * @param string the phrase you'd like to highlight + * @param string the openging tag to precede the phrase with + * @param string the closing tag to end the phrase with + * @return string + */ +if (! function_exists('highlight_phrase')) +{ + function highlight_phrase($str, $phrase, $tag_open = '', $tag_close = '') + { + if ($str == '') + { + return ''; + } + + if ($phrase != '') + { + return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Word Wrap + * + * Wraps text at the specified character. Maintains the integrity of words. + * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor + * will URLs. + * + * @access public + * @param string the text string + * @param integer the number of characters to wrap at + * @return string + */ +if (! function_exists('word_wrap')) +{ + function word_wrap($str, $charlim = '76') + { + // Se the character limit + if ( ! is_numeric($charlim)) + $charlim = 76; + + // Reduce multiple spaces + $str = preg_replace("| +|", " ", $str); + + // Standardize newlines + $str = preg_replace("/\r\n|\r/", "\n", $str); + + // If the current word is surrounded by {unwrap} tags we'll + // strip the entire chunk and replace it with a marker. + $unwrap = array(); + if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches)) + { + for ($i = 0; $i < count($matches['0']); $i++) + { + $unwrap[] = $matches['1'][$i]; + $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str); + } + } + + // Use PHP's native function to do the initial wordwrap. + // We set the cut flag to FALSE so that any individual words that are + // too long get left alone. In the next step we'll deal with them. + $str = wordwrap($str, $charlim, "\n", FALSE); + + // Split the string into individual lines of text and cycle through them + $output = ""; + foreach (explode("\n", $str) as $line) + { + // Is the line within the allowed character count? + // If so we'll join it to the output and continue + if (strlen($line) <= $charlim) + { + $output .= $line."\n"; + continue; + } + + $temp = ''; + while((strlen($line)) > $charlim) + { + // If the over-length word is a URL we won't wrap it + if (preg_match("!\[url.+\]|://|wwww.!", $line)) + { + break; + } + + // Trim the word down + $temp .= substr($line, 0, $charlim-1); + $line = substr($line, $charlim-1); + } + + // If $temp contains data it means we had to split up an over-length + // word into smaller chunks so we'll add it back to our current line + if ($temp != '') + { + $output .= $temp . "\n" . $line; + } + else + { + $output .= $line; + } + + $output .= "\n"; + } + + // Put our markers back + if (count($unwrap) > 0) + { + foreach ($unwrap as $key => $val) + { + $output = str_replace("{{unwrapped".$key."}}", $val, $output); + } + } + + // Remove the unwrap tags + $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output); + + return $output; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/typography_helper.php.svn-base b/system/helpers/.svn/text-base/typography_helper.php.svn-base new file mode 100644 index 0000000..4d9a1bb --- /dev/null +++ b/system/helpers/.svn/text-base/typography_helper.php.svn-base @@ -0,0 +1,545 @@ +",$str); + $ct = count($ex); + + $newstr = ""; + for ($i = 0; $i < $ct; $i++) + { + if (($i % 2) == 0) + { + $newstr .= nl2br($ex[$i]); + } + else + { + $newstr .= $ex[$i]; + } + + if ($ct - 1 != $i) + $newstr .= "pre>"; + } + + return $newstr; + } +} + +// ------------------------------------------------------------------------ + +/** + * Auto Typography Wrapper Function + * + * + * @access public + * @param string + * @return string + */ +if (! function_exists('auto_typography')) +{ + function auto_typography($str) + { + $TYPE = new Auto_typography(); + return $TYPE->convert($str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Auto Typography Class + * + * + * @access private + * @category Helpers + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/helpers/ + */ +class Auto_typography { + + // Block level elements that should not be wrapped inside

    tags + var $block_elements = 'div|blockquote|pre|code|h\d|script|ol|ul'; + + // Elements that should not have

    and
    tags within them. + var $skip_elements = 'pre|ol|ul'; + + // Tags we want the parser to completely ignore when splitting the string. + var $ignore_elements = 'a|b|i|em|strong|span|img|li'; + + + /** + * Main Processing Function + * + */ + function convert($str) + { + if ($str == '') + { + return ''; + } + + $str = ' '.$str.' '; + + // Standardize Newlines to make matching easier + $str = preg_replace("/(\r\n|\r)/", "\n", $str); + + /* + * Reduce line breaks + * + * If there are more than two consecutive line + * breaks we'll compress them down to a maximum + * of two since there's no benefit to more. + * + */ + $str = preg_replace("/\n\n+/", "\n\n", $str); + + /* + * Convert quotes within tags to temporary marker + * + * We don't want quotes converted within + * tags so we'll temporarily convert them to + * {@DQ} and {@SQ} + * + */ + if (preg_match_all("#\<.+?>#si", $str, $matches)) + { + for ($i = 0; $i < count($matches['0']); $i++) + { + $str = str_replace($matches['0'][$i], + str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]), + $str); + } + } + + + /* + * Add closing/opening paragraph tags before/after "block" elements + * + * Since block elements (like ,

    , etc.) do not get
    +		 * wrapped in paragraph tags we will add a closing 

    tag just before + * each block element starts and an opening

    tag right after the block element + * ends. Later on we'll do some further clean up. + * + */ + $str = preg_replace("#(<)(".$this->block_elements.")(.*?>)#", "

    \\1\\2\\3", $str); + $str = preg_replace("#(block_elements.")(.*?>)#", "\\1\\2\\3

    ", $str); + + /* + * Convert "ignore" tags to temporary marker + * + * The parser splits out the string at every tag + * it encounters. Certain inline tags, like image + * tags, links, span tags, etc. will be adversely + * affected if they are split out so we'll convert + * the opening < temporarily to: {@TAG} + * + */ + $str = preg_replace("#<(/*)(".$this->ignore_elements.")#i", "{@TAG}\\1\\2", $str); + + /* + * Split the string at every tag + * + * This creates an array with this prototype: + * + * [array] + * { + * [0] = + * [1] = Content contained between the tags + * [2] = + * Etc... + * } + * + */ + $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + + /* + * Build our finalized string + * + * We'll cycle through the array, skipping tags, + * and processing the contained text + * + */ + $str = ''; + $process = TRUE; + foreach ($chunks as $chunk) + { + /* + * Are we dealing with a tag? + * + * If so, we'll skip the processing for this cycle. + * Well also set the "process" flag which allows us + * to skip

     tags and a few other things.
    +			 *
    +			 */
    +			if (preg_match("#<(/*)(".$this->block_elements.").*?\>#", $chunk, $match))
    +			{
    +				if (preg_match("#".$this->skip_elements."#", $match['2']))
    +				{
    +					$process =  ($match['1'] == '/') ? TRUE : FALSE;		
    +				}
    +		
    +				$str .= $chunk;
    +				continue;
    +			}
    +		
    +			if ($process == FALSE)
    +			{
    +				$str .= $chunk;
    +				continue;
    +			}
    +			
    +			//  Convert Newlines into 

    and
    tags + $str .= $this->format_newlines($chunk); + } + + // FINAL CLEAN UP + // IMPORTANT: DO NOT ALTER THE ORDER OF THE ITEMS BELOW! + + /* + * Clean up paragraph tags before/after "block" elements + * + * Earlier we added

    tags before/after block level elements. + * Then, we added paragraph tags around double line breaks. This + * potentially created incorrectly formatted paragraphs so we'll + * clean it up here. + * + */ + $str = preg_replace("#

    ({@TAG}.*?)(".$this->block_elements.")(.*?>)#", "\\1\\2\\3", $str); + $str = preg_replace("#({@TAG}/.*?)(".$this->block_elements.")(.*?>)

    #", "\\1\\2\\3", $str); + + // Convert Quotes and other characters + $str = $this->format_characters($str); + + // Fix an artifact that happens during the paragraph replacement + $str = preg_replace('#(

    \n*

    )#', '', $str); + + // If the user submitted their own paragraph tags with class data + // in them we will retain them instead of using our tags. + $str = preg_replace('#()

    #', "\\1", $str); + + // Final clean up + $str = str_replace( + array( + '

    ', + '

    ', + '

    ', + '

    ', + '{@TAG}', + '{@DQ}', + '{@SQ}', + '

    ' + ), + array( + '

    ', + '

    ', + '

    ', + '

    ', + '<', + '"', + "'", + '' + ), + $str + ); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Format Characters + * + * This function mainly converts double and single quotes + * to entities, but since these are directional, it does + * it based on some rules. It also converts em-dashes + * and a couple other things. + */ + function format_characters($str) + { + $table = array( + ' "' => " “", + '" ' => "” ", + " '" => " ‘", + "' " => "’ ", + + '>"' => ">“", + '"<' => "”<", + ">'" => ">‘", + "'<" => "’<", + + "\"." => "”.", + "\"," => "”,", + "\";" => "”;", + "\":" => "”:", + "\"!" => "”!", + "\"?" => "”?", + + ". " => ".  ", + "? " => "?  ", + "! " => "!  ", + ": " => ":  ", + ); + + // These deal with quotes within quotes, like: "'hi here'" + $start = 0; + $space = array("\n", "\t", " "); + + while(TRUE) + { + $current = strpos(substr($str, $start), "\"'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + + if ( ! in_array($one_after, $space, TRUE) && $one_after != "<") + { + $str = str_replace( $one_before."\"'".$one_after, + $one_before."“‘".$one_after, + $str); + } + elseif ( ! in_array($one_before, $space, TRUE) && (in_array($one_after, $space, TRUE) OR $one_after == '<')) + { + $str = str_replace( $one_before."\"'".$one_after, + $one_before."”’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'\""); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + + if ( in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE) && $one_after != "<") + { + $str = str_replace( $one_before."'\"".$one_after, + $one_before."‘“".$one_after, + $str); + } + elseif ( ! in_array($one_before, $space, TRUE) && $one_before != ">") + { + $str = str_replace( $one_before."'\"".$one_after, + $one_before."’”".$one_after, + $str); + } + + $start = $start+$current+2; + } + + // Are there quotes within a word, as in: ("something") + if (preg_match_all("/(.)\"(\S+?)\"(.)/", $str, $matches)) + { + for ($i=0, $s=sizeof($matches['0']); $i < $s; ++$i) + { + if ( ! in_array($matches['1'][$i], $space, TRUE) && ! in_array($matches['3'][$i], $space, TRUE)) + { + $str = str_replace( $matches['0'][$i], + $matches['1'][$i]."“".$matches['2'][$i]."”".$matches['3'][$i], + $str); + } + } + } + + if (preg_match_all("/(.)\'(\S+?)\'(.)/", $str, $matches)) + { + for ($i=0, $s=sizeof($matches['0']); $i < $s; ++$i) + { + if ( ! in_array($matches['1'][$i], $space, TRUE) && ! in_array($matches['3'][$i], $space, TRUE)) + { + $str = str_replace( $matches['0'][$i], + $matches['1'][$i]."‘".$matches['2'][$i]."’".$matches['3'][$i], + $str); + } + } + } + + // How about one apostrophe, as in Rick's + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + // Em-dashes + $start = 0; + while(TRUE) + { + $current = strpos(substr($str, $start), "--"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + $two_before = substr($str, $start+$current-2, 1); + $two_after = substr($str, $start+$current+3, 1); + + if (( ! in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE)) + OR + ( ! in_array($two_before, $space, TRUE) && ! in_array($two_after, $space, TRUE) && $one_before == ' ' && $one_after == ' ') + ) + { + $str = str_replace( $two_before.$one_before."--".$one_after.$two_after, + $two_before.trim($one_before)."—".trim($one_after).$two_after, + $str); + } + + $start = $start+$current+2; + } + + // Ellipsis + $str = preg_replace("#(\w)\.\.\.(\s|
    |

    )#", "\\1…\\2", $str); + $str = preg_replace("#(\s|
    |

    )\.\.\.(\w)#", "\\1…\\2", $str); + + // Run the translation array we defined above + $str = str_replace(array_keys($table), array_values($table), $str); + + // If there are any stray double quotes we'll catch them here + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), '"'); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before.'"'.$one_after, + $one_before."“".$one_after, + $str); + } + elseif( ! in_array($one_before, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."”".$one_after, + $str); + } + + $start = $start+$current+2; + } + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."‘".$one_after, + $str); + } + elseif( ! in_array($one_before, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Format Newlines + * + * Converts newline characters into either

    tags or
    + * + */ + function format_newlines($str) + { + if ($str == '') + { + return $str; + } + + if (strpos($str, "\n") === FALSE) + { + return '

    '.$str.'

    '; + } + + $str = str_replace("\n\n", "

    \n\n

    ", $str); + $str = preg_replace("/([^\n])(\n)([^\n])/", "\\1
    \\2\\3", $str); + + return '

    '.$str.'

    '; + } +} + + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/url_helper.php.svn-base b/system/helpers/.svn/text-base/url_helper.php.svn-base new file mode 100644 index 0000000..d190488 --- /dev/null +++ b/system/helpers/.svn/text-base/url_helper.php.svn-base @@ -0,0 +1,545 @@ +config->site_url($uri); + } +} + +// ------------------------------------------------------------------------ + +/** + * Base URL + * + * Returns the "base_url" item from your config file + * + * @access public + * @return string + */ +if (! function_exists('base_url')) +{ + function base_url() + { + $CI =& get_instance(); + return $CI->config->slash_item('base_url'); + } +} + +// ------------------------------------------------------------------------ + +/** + * Index page + * + * Returns the "index_page" from your config file + * + * @access public + * @return string + */ +if (! function_exists('index_page')) +{ + function index_page() + { + $CI =& get_instance(); + return $CI->config->item('index_page'); + } +} + +// ------------------------------------------------------------------------ + +/** + * Anchor Link + * + * Creates an anchor based on the local URL. + * + * @access public + * @param string the URL + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('anchor')) +{ + function anchor($uri = '', $title = '', $attributes = '') + { + $title = (string) $title; + + if ( ! is_array($uri)) + { + $site_url = ( ! preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + } + else + { + $site_url = site_url($uri); + } + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes == '') + { + $attributes = ' title="'.$title.'"'; + } + else + { + $attributes = _parse_attributes($attributes); + } + + return ''.$title.''; + } +} + +// ------------------------------------------------------------------------ + +/** + * Anchor Link - Pop-up version + * + * Creates an anchor based on the local URL. The link + * opens a new window based on the attributes specified. + * + * @access public + * @param string the URL + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('anchor_popup')) +{ + function anchor_popup($uri = '', $title = '', $attributes = FALSE) + { + $title = (string) $title; + + $site_url = ( ! preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes === FALSE) + { + return "".$title.""; + } + + if ( ! is_array($attributes)) + { + $attributes = array(); + } + + foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val) + { + $atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key]; + } + + return "".$title.""; + } +} + +// ------------------------------------------------------------------------ + +/** + * Mailto Link + * + * @access public + * @param string the email address + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('mailto')) +{ + function mailto($email, $title = '', $attributes = '') + { + $title = (string) $title; + + if ($title == "") + { + $title = $email; + } + + $attributes = _parse_attributes($attributes); + + return ''.$title.''; + } +} + +// ------------------------------------------------------------------------ + +/** + * Encoded Mailto Link + * + * Create a spam-protected mailto link written in Javascript + * + * @access public + * @param string the email address + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('safe_mailto')) +{ + function safe_mailto($email, $title = '', $attributes = '') + { + $title = (string) $title; + + if ($title == "") + { + $title = $email; + } + + for ($i = 0; $i < 16; $i++) + { + $x[] = substr(' $val) + { + $x[] = ' '.$key.'="'; + for ($i = 0; $i < strlen($val); $i++) + { + $x[] = "|".ord(substr($val, $i, 1)); + } + $x[] = '"'; + } + } + else + { + for ($i = 0; $i < strlen($attributes); $i++) + { + $x[] = substr($attributes, $i, 1); + } + } + } + + $x[] = '>'; + + $temp = array(); + for ($i = 0; $i < strlen($title); $i++) + { + $ordinal = ord($title[$i]); + + if ($ordinal < 128) + { + $x[] = "|".$ordinal; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + $x[] = "|".$number; + $count = 1; + $temp = array(); + } + } + } + + $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>'; + + $x = array_reverse($x); + ob_start(); + + ?>http'. + $matches['4'][$i].'://'. + $matches['5'][$i]. + $matches['6'][$i].''. + $period, $str); + } + } + } + + if ($type != 'url') + { + if (preg_match_all("/([a-zA-Z0-9_\.\-]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches)) + { + for ($i = 0; $i < sizeof($matches['0']); $i++) + { + $period = ''; + if (preg_match("|\.$|", $matches['3'][$i])) + { + $period = '.'; + $matches['3'][$i] = substr($matches['3'][$i], 0, -1); + } + + $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str); + } + + } + } + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Prep URL + * + * Simply adds the http:// part if missing + * + * @access public + * @param string the URL + * @return string + */ +if (! function_exists('prep_url')) +{ + function prep_url($str = '') + { + if ($str == 'http://' OR $str == '') + { + return ''; + } + + if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') + { + $str = 'http://'.$str; + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Create URL Title + * + * Takes a "title" string as input and creates a + * human-friendly URL string with either a dash + * or an underscore as the word separator. + * + * @access public + * @param string the string + * @param string the separator: dash, or underscore + * @return string + */ +if (! function_exists('url_title')) +{ + function url_title($str, $separator = 'dash') + { + if ($separator == 'dash') + { + $search = '_'; + $replace = '-'; + } + else + { + $search = '-'; + $replace = '_'; + } + + /* debut modif */ + $caracteres_speciaux = array( + "¥" => "Y", "µ" => "u", "À" => "A", "Á" => "A", "Â" => "A", "Ã" => "A", "Ä" => "A", "Å" => "A", "Æ" => "A", "Ç" => "C", "È" => "E", "É" => "E", "Ê" => "E", "Ë" => "E", "Ì" => "I", "Í" => "I", "Î" => "I", "Ï" => "I", "Ð" => "D", "Ñ" => "N", "Ò" => "O", "Ó" => "O", "Ô" => "O", "Õ" => "O", "Ö" => "O", "Ø" => "O", "Ù" => "U", "Ú" => "U", "Û" => "U", "Ü" => "U", "Ý" => "Y", "ß" => "s", "à" => "a", "á" => "a", "â" => "a", "ã" => "a", "ä" => "a", "å" => "a", "æ" => "a", "ç" => "c", "è" => "e", "é" => "e", "ê" => "e", "ë" => "e", "ì" => "i", "í" => "i", "î" => "i", "ï" => "i", "ð" => "o", "ñ" => "n", "ò" => "o", "ó" => "o", "ô" => "o", "õ" => "o", "ö" => "o", "ø" => "o", "ù" => "u", "ú" => "u", "û" => "u", "ü" => "u", "ý" => "y", "ÿ" => "y", "€" => "e"); + + $str = strtr($str, $caracteres_speciaux); + + /* fin modif */ + + $trans = array( + $search => $replace, + "\s+" => $replace, + "[^a-z0-9".$replace."]" => '', + $replace."+" => $replace, + $replace."$" => '', + "^".$replace => '' + ); + + $str = strip_tags(strtolower($str)); + + foreach ($trans as $key => $val) + { + $str = preg_replace("#".$key."#", $val, $str); + } + + return trim(stripslashes($str)); + } +} + +// ------------------------------------------------------------------------ + +/** + * Header Redirect + * + * Header redirect in two flavors + * + * @access public + * @param string the URL + * @param string the method: location or redirect + * @return string + */ +if (! function_exists('redirect')) +{ + function redirect($uri = '', $method = 'location') + { + switch($method) + { + case 'refresh' : header("Refresh:0;url=".site_url($uri)); + break; + default : header("Location: ".site_url($uri)); + break; + } + exit; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse out the attributes + * + * Some of the functions use this + * + * @access private + * @param array + * @param bool + * @return string + */ +if (! function_exists('_parse_attributes')) +{ + function _parse_attributes($attributes, $javascript = FALSE) + { + if (is_string($attributes)) + { + return ($attributes != '') ? ' '.$attributes : ''; + } + + $att = ''; + foreach ($attributes as $key => $val) + { + if ($javascript == TRUE) + { + $att .= $key . '=' . $val . ','; + } + else + { + $att .= ' ' . $key . '="' . $val . '"'; + } + } + + if ($javascript == TRUE AND $att != '') + { + $att = substr($att, 0, -1); + } + + return $att; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/.svn/text-base/xml_helper.php.svn-base b/system/helpers/.svn/text-base/xml_helper.php.svn-base new file mode 100644 index 0000000..5aa6de9 --- /dev/null +++ b/system/helpers/.svn/text-base/xml_helper.php.svn-base @@ -0,0 +1,60 @@ +","\"", "'", "-"), + array("&", "<", ">", """, "'", "-"), + $str); + + // Decode the temp markers back to entities + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;", $str); + + return $str; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php new file mode 100755 index 0000000..236e390 --- /dev/null +++ b/system/helpers/array_helper.php @@ -0,0 +1,76 @@ + \ No newline at end of file diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php new file mode 100755 index 0000000..102057f --- /dev/null +++ b/system/helpers/cookie_helper.php @@ -0,0 +1,134 @@ +config->item('cookie_prefix') != '') + { + $prefix = $CI->config->item('cookie_prefix'); + } + if ($domain == '' AND $CI->config->item('cookie_domain') != '') + { + $domain = $CI->config->item('cookie_domain'); + } + if ($path == '/' AND $CI->config->item('cookie_path') != '/') + { + $path = $CI->config->item('cookie_path'); + } + + if ( ! is_numeric($expire)) + { + $expire = time() - 86500; + } + else + { + if ($expire > 0) + { + $expire = time() + $expire; + } + else + { + $expire = 0; + } + } + + setcookie($prefix.$name, $value, $expire, $path, $domain, 0); + } +} + +// -------------------------------------------------------------------- + +/** + * Fetch an item from the COOKIE array + * + * @access public + * @param string + * @param bool + * @return mixed + */ +if (! function_exists('get_cookie')) +{ + function get_cookie($index = '', $xss_clean = FALSE) + { + $CI =& get_instance(); + return $CI->input->cookie($index, $xss_clean); + } +} + +// -------------------------------------------------------------------- + +/** + * Delete a COOKIE + * + * @param mixed + * @param string the cookie domain. Usually: .yourdomain.com + * @param string the cookie path + * @param string the cookie prefix + * @return void + */ +if (! function_exists('delete_cookie')) +{ + function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '') + { + set_cookie($name, '', '', $domain, $path, $prefix); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php new file mode 100755 index 0000000..24e0b17 --- /dev/null +++ b/system/helpers/date_helper.php @@ -0,0 +1,599 @@ +config->item('time_reference')) == 'gmt') + { + $now = time(); + $system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)); + + if (strlen($system_time) < 10) + { + $system_time = time(); + log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.'); + } + + return $system_time; + } + else + { + return time(); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert MySQL Style Datecodes + * + * This function is identical to PHPs date() function, + * except that it allows date codes to be formatted using + * the MySQL style, where each code letter is preceded + * with a percent sign: %Y %m %d etc... + * + * The benefit of doing dates this way is that you don't + * have to worry about escaping your text letters that + * match the date codes. + * + * @access public + * @param string + * @param integer + * @return integer + */ +if (! function_exists('mdate')) +{ + function mdate($datestr = '', $time = '') + { + if ($datestr == '') + return ''; + + if ($time == '') + $time = now(); + + $datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr)); + return date($datestr, $time); + } +} + +// ------------------------------------------------------------------------ + +/** + * Standard Date + * + * Returns a date formatted according to the submitted standard. + * + * @access public + * @param string the chosen format + * @param integer Unix timestamp + * @return string + */ +if (! function_exists('standard_date')) +{ + function standard_date($fmt = 'DATE_RFC822', $time = '') + { + $formats = array( + 'DATE_ATOM' => '%Y-%m-%dT%H:%i:%s%Q', + 'DATE_COOKIE' => '%l, %d-%M-%y %H:%i:%s UTC', + 'DATE_ISO8601' => '%Y-%m-%dT%H:%i:%s%O', + 'DATE_RFC822' => '%D, %d %M %y %H:%i:%s %O', + 'DATE_RFC850' => '%l, %d-%M-%y %H:%m:%i UTC', + 'DATE_RFC1036' => '%D, %d %M %y %H:%i:%s %O', + 'DATE_RFC1123' => '%D, %d %M %Y %H:%i:%s %O', + 'DATE_RSS' => '%D, %d %M %Y %H:%i:%s %O', + 'DATE_W3C' => '%Y-%m-%dT%H:%i:%s%Q' + ); + + if ( ! isset($formats[$fmt])) + { + return FALSE; + } + + return mdate($formats[$fmt], $time); + } +} + +// ------------------------------------------------------------------------ + +/** + * Timespan + * + * Returns a span of seconds in this format: + * 10 days 14 hours 36 minutes 47 seconds + * + * @access public + * @param integer a number of seconds + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('timespan')) +{ + function timespan($seconds = 1, $time = '') + { + $CI =& get_instance(); + $CI->lang->load('date'); + + if ( ! is_numeric($seconds)) + { + $seconds = 1; + } + + if ( ! is_numeric($time)) + { + $time = time(); + } + + if ($time <= $seconds) + { + $seconds = 1; + } + else + { + $seconds = $time - $seconds; + } + + $str = ''; + $years = floor($seconds / 31536000); + + if ($years > 0) + { + $str .= $years.' '.$CI->lang->line((($years > 1) ? 'date_years' : 'date_year')).', '; + } + + $seconds -= $years * 31536000; + $months = floor($seconds / 2628000); + + if ($years > 0 OR $months > 0) + { + if ($months > 0) + { + $str .= $months.' '.$CI->lang->line((($months > 1) ? 'date_months' : 'date_month')).', '; + } + + $seconds -= $months * 2628000; + } + + $weeks = floor($seconds / 604800); + + if ($years > 0 OR $months > 0 OR $weeks > 0) + { + if ($weeks > 0) + { + $str .= $weeks.' '.$CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')).', '; + } + + $seconds -= $weeks * 604800; + } + + $days = floor($seconds / 86400); + + if ($months > 0 OR $weeks > 0 OR $days > 0) + { + if ($days > 0) + { + $str .= $days.' '.$CI->lang->line((($days > 1) ? 'date_days' : 'date_day')).', '; + } + + $seconds -= $days * 86400; + } + + $hours = floor($seconds / 3600); + + if ($days > 0 OR $hours > 0) + { + if ($hours > 0) + { + $str .= $hours.' '.$CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')).', '; + } + + $seconds -= $hours * 3600; + } + + $minutes = floor($seconds / 60); + + if ($days > 0 OR $hours > 0 OR $minutes > 0) + { + if ($minutes > 0) + { + $str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', '; + } + + $seconds -= $minutes * 60; + } + + if ($str == '') + { + $str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', '; + } + + return substr(trim($str), 0, -1); + } +} + +// ------------------------------------------------------------------------ + +/** + * Number of days in a month + * + * Takes a month/year as input and returns the number of days + * for the given month/year. Takes leap years into consideration. + * + * @access public + * @param integer a numeric month + * @param integer a numeric year + * @return integer + */ +if (! function_exists('days_in_month')) +{ + function days_in_month($month = 0, $year = '') + { + if ($month < 1 OR $month > 12) + { + return 0; + } + + if ( ! is_numeric($year) OR strlen($year) != 4) + { + $year = date('Y'); + } + + if ($month == 2) + { + if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0)) + { + return 29; + } + } + + $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + return $days_in_month[$month - 1]; + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts a local Unix timestamp to GMT + * + * @access public + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('local_to_gmt')) +{ + function local_to_gmt($time = '') + { + if ($time == '') + $time = time(); + + return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time)); + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts GMT time to a localized value + * + * Takes a Unix timestamp (in GMT) as input, and returns + * at the local value based on the timezone and DST setting + * submitted + * + * @access public + * @param integer Unix timestamp + * @param string timezone + * @param bool whether DST is active + * @return integer + */ +if (! function_exists('gmt_to_local')) +{ + function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE) + { + if ($time == '') + { + return now(); + } + + $time += timezones($timezone) * 3600; + + if ($dst == TRUE) + { + $time += 3600; + } + + return $time; + } +} + +// ------------------------------------------------------------------------ + +/** + * Converts a MySQL Timestamp to Unix + * + * @access public + * @param integer Unix timestamp + * @return integer + */ +if (! function_exists('mysql_to_unix')) +{ + function mysql_to_unix($time = '') + { + // We'll remove certain characters for backward compatibility + // since the formatting changed with MySQL 4.1 + // YYYY-MM-DD HH:MM:SS + + $time = str_replace('-', '', $time); + $time = str_replace(':', '', $time); + $time = str_replace(' ', '', $time); + + // YYYYMMDDHHMMSS + return mktime( + substr($time, 8, 2), + substr($time, 10, 2), + substr($time, 12, 2), + substr($time, 4, 2), + substr($time, 6, 2), + substr($time, 0, 4) + ); + } +} + +// ------------------------------------------------------------------------ + +/** + * Unix to "Human" + * + * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM + * + * @access public + * @param integer Unix timestamp + * @param bool whether to show seconds + * @param string format: us or euro + * @return string + */ +if (! function_exists('unix_to_human')) +{ + function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us') + { + $r = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' '; + + if ($fmt == 'us') + { + $r .= date('h', $time).':'.date('i', $time); + } + else + { + $r .= date('H', $time).':'.date('i', $time); + } + + if ($seconds) + { + $r .= ':'.date('s', $time); + } + + if ($fmt == 'us') + { + $r .= ' '.date('A', $time); + } + + return $r; + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert "human" date to GMT + * + * Reverses the above process + * + * @access public + * @param string format: us or euro + * @return integer + */ +if (! function_exists('human_to_unix')) +{ + function human_to_unix($datestr = '') + { + if ($datestr == '') + { + return FALSE; + } + + $datestr = trim($datestr); + $datestr = preg_replace("/\040+/", "\040", $datestr); + + if ( ! ereg("^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\040[0-9]{1,2}:[0-9]{1,2}.*$", $datestr)) + { + return FALSE; + } + + $split = preg_split("/\040/", $datestr); + + $ex = explode("-", $split['0']); + + $year = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0']; + $month = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1']; + $day = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2']; + + $ex = explode(":", $split['1']); + + $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0']; + $min = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1']; + + if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2'])) + { + $sec = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2']; + } + else + { + // Unless specified, seconds get set to zero. + $sec = '00'; + } + + if (isset($split['2'])) + { + $ampm = strtolower($split['2']); + + if (substr($ampm, 0, 1) == 'p' AND $hour < 12) + $hour = $hour + 12; + + if (substr($ampm, 0, 1) == 'a' AND $hour == 12) + $hour = '00'; + + if (strlen($hour) == 1) + $hour = '0'.$hour; + } + + return mktime($hour, $min, $sec, $month, $day, $year); + } +} + +// ------------------------------------------------------------------------ + +/** + * Timezone Menu + * + * Generates a drop-down menu of timezones. + * + * @access public + * @param string timezone + * @param string classname + * @param string menu name + * @return string + */ +if (! function_exists('timezone_menu')) +{ + function timezone_menu($default = 'UTC', $class = "", $name = 'timezones') + { + $CI =& get_instance(); + $CI->lang->load('date'); + + if ($default == 'GMT') + $default = 'UTC'; + + $menu = '"; + + return $menu; + } +} + +// ------------------------------------------------------------------------ + +/** + * Timezones + * + * Returns an array of timezones. This is a helper function + * for various other ones in this library + * + * @access public + * @param string timezone + * @return string + */ +if (! function_exists('timezones')) +{ + function timezones($tz = '') + { + // Note: Don't change the order of these even though + // some items appear to be in the wrong order + + $zones = array( + 'UM12' => -12, + 'UM11' => -11, + 'UM10' => -10, + 'UM9' => -9, + 'UM8' => -8, + 'UM7' => -7, + 'UM6' => -6, + 'UM5' => -5, + 'UM4' => -4, + 'UM25' => -2.5, + 'UM3' => -3, + 'UM2' => -2, + 'UM1' => -1, + 'UTC' => 0, + 'UP1' => +1, + 'UP2' => +2, + 'UP3' => +3, + 'UP25' => +2.5, + 'UP4' => +4, + 'UP35' => +3.5, + 'UP5' => +5, + 'UP45' => +4.5, + 'UP6' => +6, + 'UP7' => +7, + 'UP8' => +8, + 'UP9' => +9, + 'UP85' => +8.5, + 'UP10' => +10, + 'UP11' => +11, + 'UP12' => +12 + ); + + if ($tz == '') + { + return $zones; + } + + if ($tz == 'GMT') + $tz = 'UTC'; + + return ( ! isset($zones[$tz])) ? 0 : $zones[$tz]; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php new file mode 100755 index 0000000..5a23944 --- /dev/null +++ b/system/helpers/directory_helper.php @@ -0,0 +1,69 @@ + \ No newline at end of file diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php new file mode 100755 index 0000000..2d0e737 --- /dev/null +++ b/system/helpers/download_helper.php @@ -0,0 +1,98 @@ + \ No newline at end of file diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php new file mode 100755 index 0000000..e677afd --- /dev/null +++ b/system/helpers/email_helper.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php new file mode 100755 index 0000000..aed2502 --- /dev/null +++ b/system/helpers/file_helper.php @@ -0,0 +1,461 @@ + 0) + { + $data =& fread($fp, filesize($file)); + } + + flock($fp, LOCK_UN); + fclose($fp); + + return $data; + } +} + +// ------------------------------------------------------------------------ + +/** + * Write File + * + * Writes data to the file specified in the path. + * Creates a new file if non-existent. + * + * @access public + * @param string path to file + * @param string file data + * @return bool + */ +if ( ! function_exists('write_file')) +{ + function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE) + { + if ( ! $fp = @fopen($path, $mode)) + { + return FALSE; + } + + flock($fp, LOCK_EX); + fwrite($fp, $data); + flock($fp, LOCK_UN); + fclose($fp); + + return TRUE; + } +} + +// ------------------------------------------------------------------------ + +/** + * Delete Files + * + * Deletes all files contained in the supplied directory path. + * Files must be writable or owned by the system in order to be deleted. + * If the second parameter is set to TRUE, any directories contained + * within the supplied base directory will be nuked as well. + * + * @access public + * @param string path to file + * @param bool whether to delete any directories found in the path + * @return bool + */ +if ( ! function_exists('delete_files')) +{ + function delete_files($path, $del_dir = FALSE, $level = 0) + { + // Trim the trailing slash + $path = preg_replace("|^(.+?)/*$|", "\\1", $path); + + if ( ! $current_dir = @opendir($path)) + return; + + while(FALSE !== ($filename = @readdir($current_dir))) + { + if ($filename != "." and $filename != "..") + { + if (is_dir($path.'/'.$filename)) + { + delete_files($path.'/'.$filename, $del_dir, $level + 1); + } + else + { + unlink($path.'/'.$filename); + } + } + } + @closedir($current_dir); + + if ($del_dir == TRUE AND $level > 0) + { + @rmdir($path); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Get Filenames + * + * Reads the specified directory and builds an array containing the filenames. + * Any sub-folders contained within the specified path are read as well. + * + * @access public + * @param string path to source + * @param bool whether to include the path as part of the filename + * @param bool internal variable to determine recursion status - do not use in calls + * @return array + */ +if ( ! function_exists('get_filenames')) +{ + function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE) + { + static $_filedata = array(); + + if ($fp = @opendir($source_dir)) + { + // reset the array and make sure $source_dir has a trailing slash on the initial call + if ($_recursion === FALSE) + { + $_filedata = array(); + $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; + } + + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0) + { + get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); + } + elseif (strncmp($file, '.', 1) !== 0) + { + + $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file; + } + } + return $_filedata; + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** + * Get Directory File Information + * + * Reads the specified directory and builds an array containing the filenames, + * filesize, dates, and permissions + * + * Any sub-folders contained within the specified path are read as well. + * + * @access public + * @param string path to source + * @param bool whether to include the path as part of the filename + * @param bool internal variable to determine recursion status - do not use in calls + * @return array + */ +if ( ! function_exists('get_dir_file_info')) +{ + function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE) + { + $_filedata = array(); + $relative_path = $source_dir; + + if ($fp = @opendir($source_dir)) + { + // reset the array and make sure $source_dir has a trailing slash on the initial call + if ($_recursion === FALSE) + { + $_filedata = array(); + $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; + } + + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0) + { + get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE); + } + elseif (strncmp($file, '.', 1) !== 0) + { + $_filedata[$file] = get_file_info($source_dir.$file); + $_filedata[$file]['relative_path'] = $relative_path; + } + } + return $_filedata; + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** +* Get File Info +* +* Given a file and path, returns the name, path, size, date modified +* Second parameter allows you to explicitly declare what information you want returned +* Options are: name, server_path, size, date, readable, writable, executable, fileperms +* Returns FALSE if the file cannot be found. +* +* @access public +* @param string path to file +* @param mixed array or comma separated string of information returned +* @return array +*/ +if ( ! function_exists('get_file_info')) +{ + function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) + { + + if ( ! file_exists($file)) + { + return FALSE; + } + + if (is_string($returned_values)) + { + $returned_values = explode(',', $returned_values); + } + + foreach ($returned_values as $key) + { + switch ($key) + { + case 'name': + $fileinfo['name'] = substr(strrchr($file, '/'), 1); + break; + case 'server_path': + $fileinfo['server_path'] = $file; + break; + case 'size': + $fileinfo['size'] = filesize($file); + break; + case 'date': + $fileinfo['date'] = filectime($file); + break; + case 'readable': + $fileinfo['readable'] = is_readable($file); + break; + case 'writable': + // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms() + $fileinfo['writable'] = is_writable($file); + break; + case 'executable': + $fileinfo['executable'] = is_executable($file); + break; + case 'fileperms': + $fileinfo['fileperms'] = fileperms($file); + break; + } + } + + return $fileinfo; + } +} + +// -------------------------------------------------------------------- + +/** + * Get Mime by Extension + * + * Translates a file extension into a mime type based on config/mimes.php. + * Returns FALSE if it can't determine the type, or open the mime config file + * + * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience + * It should NOT be trusted, and should certainly NOT be used for security + * + * @access public + * @param string path to file + * @return mixed + */ +if ( ! function_exists('get_mime_by_extension')) +{ + function get_mime_by_extension($file) + { + $extension = substr(strrchr($file, '.'), 1); + + global $mimes; + + if ( ! is_array($mimes)) + { + if ( ! require_once(APPPATH.'config/mimes.php')) + { + return FALSE; + } + } + + if (array_key_exists($extension, $mimes)) + { + if (is_array($mimes[$extension])) + { + // Multiple mime types, just give the first one + return current($mimes[$extension]); + } + else + { + return $mimes[$extension]; + } + } + else + { + return FALSE; + } + } +} + +// -------------------------------------------------------------------- + +/** + * Symbolic Permissions + * + * Takes a numeric value representing a file's permissions and returns + * standard symbolic notation representing that value + * + * @access public + * @param int + * @return string + */ +if ( ! function_exists('symbolic_permissions')) +{ + function symbolic_permissions($perms) + { + if (($perms & 0xC000) == 0xC000) + { + $symbolic = 's'; // Socket + } + elseif (($perms & 0xA000) == 0xA000) + { + $symbolic = 'l'; // Symbolic Link + } + elseif (($perms & 0x8000) == 0x8000) + { + $symbolic = '-'; // Regular + } + elseif (($perms & 0x6000) == 0x6000) + { + $symbolic = 'b'; // Block special + } + elseif (($perms & 0x4000) == 0x4000) + { + $symbolic = 'd'; // Directory + } + elseif (($perms & 0x2000) == 0x2000) + { + $symbolic = 'c'; // Character special + } + elseif (($perms & 0x1000) == 0x1000) + { + $symbolic = 'p'; // FIFO pipe + } + else + { + $symbolic = 'u'; // Unknown + } + + // Owner + $symbolic .= (($perms & 0x0100) ? 'r' : '-'); + $symbolic .= (($perms & 0x0080) ? 'w' : '-'); + $symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); + + // Group + $symbolic .= (($perms & 0x0020) ? 'r' : '-'); + $symbolic .= (($perms & 0x0010) ? 'w' : '-'); + $symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); + + // World + $symbolic .= (($perms & 0x0004) ? 'r' : '-'); + $symbolic .= (($perms & 0x0002) ? 'w' : '-'); + $symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); + + return $symbolic; + } +} + +// -------------------------------------------------------------------- + +/** + * Octal Permissions + * + * Takes a numeric value representing a file's permissions and returns + * a three character string representing the file's octal permissions + * + * @access public + * @param int + * @return string + */ +if ( ! function_exists('octal_permissions')) +{ + function octal_permissions($perms) + { + return substr(sprintf('%o', $perms), -3); + } +} + + +/* End of file file_helper.php */ +/* Location: ./system/helpers/file_helper.php */ \ No newline at end of file diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php new file mode 100755 index 0000000..7c3b16f --- /dev/null +++ b/system/helpers/form_helper.php @@ -0,0 +1,586 @@ +config->site_url($action) : $action; + + $form = '
    0) + { + foreach ($attributes as $key => $val) + { + $form .= ' '.$key.'="'.$val.'"'; + } + } + + $form .= '>'; + + if (is_array($hidden) AND count($hidden > 0)) + { + $form .= form_hidden($hidden); + } + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Declaration - Multipart type + * + * Creates the opening portion of the form, but with "multipart/form-data". + * + * @access public + * @param string the URI segments of the form destination + * @param array a key/value pair of attributes + * @param array a key/value pair hidden data + * @return string + */ +if (! function_exists('form_open_multipart')) +{ + function form_open_multipart($action, $attributes = array(), $hidden = array()) + { + $attributes['enctype'] = 'multipart/form-data'; + return form_open($action, $attributes, $hidden); + } +} + +// ------------------------------------------------------------------------ + +/** + * Hidden Input Field + * + * Generates hidden fields. You can pass a simple key/value string or an associative + * array with multiple values. + * + * @access public + * @param mixed + * @param string + * @return string + */ +if (! function_exists('form_hidden')) +{ + function form_hidden($name, $value = '') + { + if ( ! is_array($name)) + { + return ''; + } + + $form = ''; + foreach ($name as $name => $value) + { + $form .= ''; + } + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Text Input Field + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_input')) +{ + function form_input($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value, 'maxlength' => '500', 'size' => '50'); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Password Field + * + * Identical to the input function but adds the "password" type + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_password')) +{ + function form_password($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'password'; + return form_input($data, $value, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Upload Field + * + * Identical to the input function but adds the "file" type + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_upload')) +{ + function form_upload($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'file'; + return form_input($data, $value, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Textarea field + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_textarea')) +{ + function form_textarea($data = '', $value = '', $extra = '') + { + $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12'); + + if ( ! is_array($data) OR ! isset($data['value'])) + { + $val = $value; + } + else + { + $val = $data['value']; + unset($data['value']); // textareas don't use the value attribute + } + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Drop-down Menu + * + * @access public + * @param string + * @param array + * @param string + * @param string + * @return string + */ +if (! function_exists('form_dropdown')) +{ + function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '') + { + if ( ! is_array($selected)) + { + $selected = array($selected); + } + + if ($extra != '') $extra = ' '.$extra; + + $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : ''; + + $form = ''; + + return $form; + } +} + +// ------------------------------------------------------------------------ + +/** + * Checkbox Field + * + * @access public + * @param mixed + * @param string + * @param bool + * @param string + * @return string + */ +if (! function_exists('form_checkbox')) +{ + function form_checkbox($data = '', $value = '', $checked = TRUE, $extra = '') + { + $defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + if (is_array($data) AND array_key_exists('checked', $data)) + { + $checked = $data['checked']; + + if ($checked == FALSE) + { + unset($data['checked']); + } + else + { + $data['checked'] = 'checked'; + } + } + + if ($checked == TRUE) + $defaults['checked'] = 'checked'; + else + unset($defaults['checked']); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Radio Button + * + * @access public + * @param mixed + * @param string + * @param bool + * @param string + * @return string + */ +if (! function_exists('form_radio')) +{ + function form_radio($data = '', $value = '', $checked = TRUE, $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'radio'; + return form_checkbox($data, $value, $checked, $extra); + } +} + +// ------------------------------------------------------------------------ + +/** + * Submit Button + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_submit')) +{ + function form_submit($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Reset Button + * + * @access public + * @param mixed + * @param string + * @param string + * @return string + */ +if (! function_exists('form_reset')) +{ + function form_reset($data = '', $value = '', $extra = '') + { + $defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value); + + return "\n"; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Label Tag + * + * @access public + * @param string The text to appear onscreen + * @param string The id the label applies to + * @param string Additional attributes + * @return string + */ +if (! function_exists('form_label')) +{ + function form_label($label_text = '', $id = '', $attributes = array()) + { + + $label = ' 0) + { + foreach ($attributes as $key => $val) + { + $label .= ' '.$key.'="'.$val.'"'; + } + } + + $label .= ">$label_text"; + + return $label; + } +} + +// ------------------------------------------------------------------------ +/** + * Fieldset Tag + * + * Used to produce
    text. To close fieldset + * use form_fieldset_close() + * + * @access public + * @param string The legend text + * @param string Additional attributes + * @return string + */ +if (! function_exists('form_fieldset')) +{ + function form_fieldset($legend_text = '', $attributes = array()) + { + + $fieldset = " 0) + { + foreach ($attributes as $key => $val) + { + $fieldset .= ' '.$key.'="'.$val.'"'; + } + } + + $fieldset .= ">\n"; + + if ($legend_text != '') + { + $fieldset .= "$legend_text\n"; + } + + + + return $fieldset; + } +} + +// ------------------------------------------------------------------------ + +/** + * Fieldset Close Tag + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_fieldset_close')) +{ + function form_fieldset_close($extra = '') + { + return "
    \n".$extra; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Close Tag + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_close')) +{ + function form_close($extra = '') + { + return "\n".$extra; + } +} + +// ------------------------------------------------------------------------ + +/** + * Form Prep + * + * Formats text so that it can be safely placed in a form field in the event it has HTML tags. + * + * @access public + * @param string + * @return string + */ +if (! function_exists('form_prep')) +{ + function form_prep($str = '') + { + if ($str === '') + { + return ''; + } + + $temp = '__TEMP_AMPERSANDS__'; + + // Replace entities to temporary markers so that + // htmlspecialchars won't mess them up + $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); + $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); + + $str = htmlspecialchars($str); + + // In case htmlspecialchars misses these. + $str = str_replace(array("'", '"'), array("'", """), $str); + + // Decode the temp markers back to entities + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;",$str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse the form attributes + * + * Helper function used by some of the form helpers + * + * @access private + * @param array + * @param array + * @return string + */ +if (! function_exists('parse_form_attributes')) +{ + function parse_form_attributes($attributes, $default) + { + if (is_array($attributes)) + { + foreach ($default as $key => $val) + { + if (isset($attributes[$key])) + { + $default[$key] = $attributes[$key]; + unset($attributes[$key]); + } + } + + if (count($attributes) > 0) + { + $default = array_merge($default, $attributes); + } + } + + $att = ''; + foreach ($default as $key => $val) + { + if ($key == 'value') + { + $val = form_prep($val); + } + + $att .= $key . '="' . $val . '" '; + } + + return $att; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php new file mode 100755 index 0000000..0c88450 --- /dev/null +++ b/system/helpers/html_helper.php @@ -0,0 +1,354 @@ +".$data.""; + } +} + +// ------------------------------------------------------------------------ + +/** + * Unordered List + * + * Generates an HTML unordered list from an single or multi-dimensional array. + * + * @access public + * @param array + * @param mixed + * @return string + */ +if (! function_exists('ul')) +{ + function ul($list, $attributes = '') + { + return _list('ul', $list, $attributes); + } +} + +// ------------------------------------------------------------------------ + +/** + * Ordered List + * + * Generates an HTML ordered list from an single or multi-dimensional array. + * + * @access public + * @param array + * @param mixed + * @return string + */ +if (! function_exists('ol')) +{ + function ol($list, $attributes = '') + { + return _list('ol', $list, $attributes); + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates the list + * + * Generates an HTML ordered list from an single or multi-dimensional array. + * + * @access private + * @param string + * @param mixed + * @param mixed + * @param intiger + * @return string + */ +if (! function_exists('_list')) +{ + function _list($type = 'ul', $list, $attributes = '', $depth = 0) + { + // If an array wasn't submitted there's nothing to do... + if ( ! is_array($list)) + { + return $list; + } + + // Set the indentation based on the depth + $out = str_repeat(" ", $depth); + + // Were any attributes submitted? If so generate a string + if (is_array($attributes)) + { + $atts = ''; + foreach ($attributes as $key => $val) + { + $atts .= ' ' . $key . '="' . $val . '"'; + } + $attributes = $atts; + } + + // Write the opening list tag + $out .= "<".$type.$attributes.">\n"; + + // Cycle through the list elements. If an array is + // encountered we will recursively call _list() + + static $_last_list_item = ''; + foreach ($list as $key => $val) + { + $_last_list_item = $key; + + $out .= str_repeat(" ", $depth + 2); + $out .= "
  • "; + + if ( ! is_array($val)) + { + $out .= $val; + } + else + { + $out .= $_last_list_item."\n"; + $out .= _list($type, $val, '', $depth + 4); + $out .= str_repeat(" ", $depth + 2); + } + + $out .= "
  • \n"; + } + + // Set the indentation for the closing tag + $out .= str_repeat(" ", $depth); + + // Write the closing list tag + $out .= "\n"; + + return $out; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates HTML BR tags based on number supplied + * + * @access public + * @param integer + * @return string + */ +if (! function_exists('br')) +{ + function br($num = 1) + { + return str_repeat("
    ", $num); + } +} + +// ------------------------------------------------------------------------ + +/** + * Image + * + * Generates an element + * + * @access public + * @param mixed + * @return string + */ +if (! function_exists('img')) +{ + function img($src = '', $index_page = FALSE) + { + if ( ! is_array($src) ) + { + $src = array('src' => $src); + } + + $img = '$v) + { + + if ($k == 'src' AND strpos($v, '://') === FALSE) + { + $CI =& get_instance(); + + if ($index_page === TRUE) + { + $img .= ' src="'.$CI->config->site_url($v).'" '; + } + else + { + $img .= ' src="'.$CI->config->slash_item('base_url').$v.'" '; + } + } + else + { + $img .= " $k=\"$v\" "; + } + } + + $img .= '/>'; + + return $img; + } +} + +// ------------------------------------------------------------------------ + +/** + * Link + * + * Generates link to a CSS file + * + * @access public + * @param mixed stylesheet hrefs or an array + * @param string rel + * @param string type + * @param string title + * @param string media + * @param boolean should index_page be added to the css path + * @return string + */ +if (! function_exists('link_tag')) +{ + function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE) + { + $CI =& get_instance(); + + $link = '$v) + { + if ($k == 'href' AND strpos($k, '://') === FALSE) + { + if ($index_page === TRUE) + { + $link .= ' href="'.$CI->config->site_url($v).'" '; + } + else + { + $link .= ' href="'.$CI->config->slash_item('base_url').$v.'" '; + } + } + else + { + $link .= "$k=\"$v\" "; + } + } + + $link .= "/>\n"; + } + else + { + if ( strpos($href, '://') !== FALSE) + { + $link .= ' href="'.$href.'" '; + } + elseif ($index_page === TRUE) + { + $link .= ' href="'.$CI->config->site_url($href).'" '; + } + else + { + $link .= ' href="'.$CI->config->slash_item('base_url').$href.'" '; + } + + $link .= 'rel="'.$rel.'" type="'.$type.'" '; + + if ($media != '') + { + $link .= 'media="'.$media.'" '; + } + + if ($title != '') + { + $link .= 'title="'.$title.'" '; + } + + $link .= '/>'."\n"; + } + + + return $link; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates meta tags from an array of key/values + * + * @access public + * @param array + * @return string + */ +if (! function_exists('meta')) +{ + function meta($meta = array(), $newline = "\n") + { + $str = ''; + foreach ($meta as $key => $val) + { + $str .= ''.$newline; + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Generates non-breaking space entities based on number supplied + * + * @access public + * @param integer + * @return string + */ +if (! function_exists('nbs')) +{ + function nbs($num = 1) + { + return str_repeat(" ", $num); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/index.html b/system/helpers/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/helpers/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php new file mode 100755 index 0000000..bf70a67 --- /dev/null +++ b/system/helpers/inflector_helper.php @@ -0,0 +1,167 @@ + \ No newline at end of file diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php new file mode 100755 index 0000000..30d26d6 --- /dev/null +++ b/system/helpers/path_helper.php @@ -0,0 +1,70 @@ + \ No newline at end of file diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php new file mode 100755 index 0000000..7552fd8 --- /dev/null +++ b/system/helpers/security_helper.php @@ -0,0 +1,124 @@ +input->xss_clean($str, $charset); + } +} + +// -------------------------------------------------------------------- + +/** + * Hash encode a string + * + * @access public + * @param string + * @return string + */ +if (! function_exists('dohash')) +{ + function dohash($str, $type = 'sha1') + { + if ($type == 'sha1') + { + if ( ! function_exists('sha1')) + { + if ( ! function_exists('mhash')) + { + require_once(BASEPATH.'libraries/Sha1'.EXT); + $SH = new CI_SHA; + return $SH->generate($str); + } + else + { + return bin2hex(mhash(MHASH_SHA1, $str)); + } + } + else + { + return sha1($str); + } + } + else + { + return md5($str); + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Strip Image Tags + * + * @access public + * @param string + * @return string + */ +if (! function_exists('strip_image_tags')) +{ + function strip_image_tags($str) + { + $str = preg_replace("##", "\\1", $str); + $str = preg_replace("##", "\\1", $str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Convert PHP tags to entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('encode_php_tags')) +{ + function encode_php_tags($str) + { + return str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php new file mode 100755 index 0000000..25962eb --- /dev/null +++ b/system/helpers/smiley_helper.php @@ -0,0 +1,173 @@ + + function insert_smiley(smiley) + { + document.{$form_name}.{$form_field}.value += " " + smiley; + } + +EOF; + } +} +// ------------------------------------------------------------------------ + +/** + * Get Clickable Smileys + * + * Returns an array of image tag links that can be clicked to be inserted + * into a form field. + * + * @access public + * @param string the URL to the folder containing the smiley images + * @return array + */ +if (! function_exists('get_clickable_smileys')) +{ + function get_clickable_smileys($image_url = '', $smileys = NULL) + { + if ( ! is_array($smileys)) + { + if (FALSE === ($smileys = _get_smiley_array())) + { + return $smileys; + } + } + + // Add a trailing slash to the file path if needed + $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url); + + $used = array(); + foreach ($smileys as $key => $val) + { + // Keep duplicates from being used, which can happen if the + // mapping array contains multiple identical replacements. For example: + // :-) and :) might be replaced with the same image so both smileys + // will be in the array. + if (isset($used[$smileys[$key][0]])) + { + continue; + } + + $link[] = "\"".$smileys[$key][3]."\""; + + $used[$smileys[$key][0]] = TRUE; + } + + return $link; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse Smileys + * + * Takes a string as input and swaps any contained smileys for the actual image + * + * @access public + * @param string the text to be parsed + * @param string the URL to the folder containing the smiley images + * @return string + */ +if (! function_exists('parse_smileys')) +{ + function parse_smileys($str = '', $image_url = '', $smileys = NULL) + { + if ($image_url == '') + { + return $str; + } + + if ( ! is_array($smileys)) + { + if (FALSE === ($smileys = _get_smiley_array())) + { + return $str; + } + } + + // Add a trailing slash to the file path if needed + $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url); + + foreach ($smileys as $key => $val) + { + $str = str_replace($key, "\"".$smileys[$key][3]."\"", $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Get Smiley Array + * + * Fetches the config/smiley.php file + * + * @access private + * @return mixed + */ +if (! function_exists('_get_smiley_array')) +{ + function _get_smiley_array() + { + if ( ! file_exists(APPPATH.'config/smileys'.EXT)) + { + return FALSE; + } + + include(APPPATH.'config/smileys'.EXT); + + if ( ! isset($smileys) OR ! is_array($smileys)) + { + return FALSE; + } + + return $smileys; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php new file mode 100755 index 0000000..f68f44a --- /dev/null +++ b/system/helpers/string_helper.php @@ -0,0 +1,271 @@ + $val) + { + $str[$key] = strip_slashes($val); + } + } + else + { + $str = stripslashes($str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Strip Quotes + * + * Removes single and double quotes from a string + * + * @access public + * @param string + * @return string + */ +if (! function_exists('strip_quotes')) +{ + function strip_quotes($str) + { + return str_replace(array('"', "'"), '', $str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Quotes to Entities + * + * Converts single and double quotes to entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('quotes_to_entities')) +{ + function quotes_to_entities($str) + { + return str_replace(array("\'","\"","'",'"'), array("'",""","'","""), $str); + } +} + +// ------------------------------------------------------------------------ +/** + * Reduce Double Slashes + * + * Converts double slashes in a string to a single slash, + * except those found in http:// + * + * http://www.some-site.com//index.php + * + * becomes: + * + * http://www.some-site.com/index.php + * + * @access public + * @param string + * @return string + */ +if (! function_exists('reduce_double_slashes')) +{ + function reduce_double_slashes($str) + { + return preg_replace("#([^:])//+#", "\\1/", $str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Reduce Multiples + * + * Reduces multiple instances of a particular character. Example: + * + * Fred, Bill,, Joe, Jimmy + * + * becomes: + * + * Fred, Bill, Joe, Jimmy + * + * @access public + * @param string + * @param string the character you wish to reduce + * @param bool TRUE/FALSE - whether to trim the character from the beginning/end + * @return string + */ +if (! function_exists('reduce_multiples')) +{ + function reduce_multiples($str, $character = ',', $trim = FALSE) + { + $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str); + + if ($trim === TRUE) + { + $str = trim($str, $character); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Create a Random String + * + * Useful for generating passwords or hashes. + * + * @access public + * @param string type of random string. Options: alunum, numeric, nozero, unique + * @param integer number of characters + * @return string + */ +if (! function_exists('random_string')) +{ + function random_string($type = 'alnum', $len = 8) + { + switch($type) + { + case 'alnum' : + case 'numeric' : + case 'nozero' : + + switch ($type) + { + case 'alnum' : $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + break; + case 'numeric' : $pool = '0123456789'; + break; + case 'nozero' : $pool = '123456789'; + break; + } + + $str = ''; + for ($i=0; $i < $len; $i++) + { + $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); + } + return $str; + break; + case 'unique' : return md5(uniqid(mt_rand())); + break; + } + } +} + +// ------------------------------------------------------------------------ + +/** + * Alternator + * + * Allows strings to be alternated. See docs... + * + * @access public + * @param string (as many parameters as needed) + * @return string + */ +if (! function_exists('alternator')) +{ + function alternator() + { + static $i; + + if (func_num_args() == 0) + { + $i = 0; + return ''; + } + $args = func_get_args(); + return $args[($i++ % count($args))]; + } +} + +// ------------------------------------------------------------------------ + +/** + * Repeater function + * + * @access public + * @param string + * @param integer number of repeats + * @return string + */ +if (! function_exists('repeater')) +{ + function repeater($data, $num = 1) + { + return (($num > 0) ? str_repeat($data, $num) : ''); + } +} + +?> \ No newline at end of file diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php new file mode 100755 index 0000000..21ab778 --- /dev/null +++ b/system/helpers/text_helper.php @@ -0,0 +1,439 @@ += $n) + { + return trim($out).$end_char; + } + } + } +} + +// ------------------------------------------------------------------------ + +/** + * High ASCII to Entities + * + * Converts High ascii text and MS Word special characters to character entities + * + * @access public + * @param string + * @return string + */ +if (! function_exists('ascii_to_entities')) +{ + function ascii_to_entities($str) + { + $count = 1; + $out = ''; + $temp = array(); + + for ($i = 0, $s = strlen($str); $i < $s; $i++) + { + $ordinal = ord($str[$i]); + + if ($ordinal < 128) + { + $out .= $str[$i]; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + + $out .= '&#'.$number.';'; + $count = 1; + $temp = array(); + } + } + } + + return $out; + } +} + +// ------------------------------------------------------------------------ + +/** + * Entities to ASCII + * + * Converts character entities back to ASCII + * + * @access public + * @param string + * @param bool + * @return string + */ +if (! function_exists('entities_to_ascii')) +{ + function entities_to_ascii($str, $all = TRUE) + { + if (preg_match_all('/\&#(\d+)\;/', $str, $matches)) + { + for ($i = 0, $s = count($matches['0']); $i < $s; $i++) + { + $digits = $matches['1'][$i]; + + $out = ''; + + if ($digits < 128) + { + $out .= chr($digits); + + } + elseif ($digits < 2048) + { + $out .= chr(192 + (($digits - ($digits % 64)) / 64)); + $out .= chr(128 + ($digits % 64)); + } + else + { + $out .= chr(224 + (($digits - ($digits % 4096)) / 4096)); + $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64)); + $out .= chr(128 + ($digits % 64)); + } + + $str = str_replace($matches['0'][$i], $out, $str); + } + } + + if ($all) + { + $str = str_replace(array("&", "<", ">", """, "'", "-"), + array("&","<",">","\"", "'", "-"), + $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Word Censoring Function + * + * Supply a string and an array of disallowed words and any + * matched words will be converted to #### or to the replacement + * word you've submitted. + * + * @access public + * @param string the text string + * @param string the array of censoered words + * @param string the optional replacement value + * @return string + */ +if (! function_exists('word_censor')) +{ + function word_censor($str, $censored, $replacement = '') + { + if ( ! is_array($censored)) + { + return $str; + } + + $str = ' '.$str.' '; + foreach ($censored as $badword) + { + if ($replacement != '') + { + $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/i", $replacement, $str); + } + else + { + $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword)).")\b/ie", "str_repeat('#', strlen('\\1'))", $str); + } + } + + return trim($str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Code Highlighter + * + * Colorizes code strings + * + * @access public + * @param string the text string + * @return string + */ +if (! function_exists('highlight_code')) +{ + function highlight_code($str) + { + // The highlight string function encodes and highlights + // brackets so we need them to start raw + $str = str_replace(array('<', '>'), array('<', '>'), $str); + + // Replace any existing PHP tags to temporary markers so they don't accidentally + // break the string out of PHP, and thus, thwart the highlighting. + + $str = str_replace(array('', '<%', '%>', '\\', ''), + array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str); + + // The highlight_string function requires that the text be surrounded + // by PHP tags. Since we don't know if A) the submitted text has PHP tags, + // or B) whether the PHP tags enclose the entire string, we will add our + // own PHP tags around the string along with some markers to make replacement easier later + + $str = ''; + + // All the magic happens here, baby! + $str = highlight_string($str, TRUE); + + // Prior to PHP 5, the highlight function used icky font tags + // so we'll replace them with span tags. + if (abs(phpversion()) < 5) + { + $str = str_replace(array(''), array(''), $str); + $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str); + } + + // Remove our artificially added PHP + $str = preg_replace("#\.+?tempstart\
    (?:\)?#is", "\n", $str); + $str = preg_replace("#tempend.+#is", "
    \n", $str); + + // Replace our markers back to PHP tags. + $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), + array('<?', '?>', '<%', '%>', '\\', '</script>'), $str); + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Phrase Highlighter + * + * Highlights a phrase within a text string + * + * @access public + * @param string the text string + * @param string the phrase you'd like to highlight + * @param string the openging tag to precede the phrase with + * @param string the closing tag to end the phrase with + * @return string + */ +if (! function_exists('highlight_phrase')) +{ + function highlight_phrase($str, $phrase, $tag_open = '', $tag_close = '') + { + if ($str == '') + { + return ''; + } + + if ($phrase != '') + { + return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str); + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Word Wrap + * + * Wraps text at the specified character. Maintains the integrity of words. + * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor + * will URLs. + * + * @access public + * @param string the text string + * @param integer the number of characters to wrap at + * @return string + */ +if (! function_exists('word_wrap')) +{ + function word_wrap($str, $charlim = '76') + { + // Se the character limit + if ( ! is_numeric($charlim)) + $charlim = 76; + + // Reduce multiple spaces + $str = preg_replace("| +|", " ", $str); + + // Standardize newlines + $str = preg_replace("/\r\n|\r/", "\n", $str); + + // If the current word is surrounded by {unwrap} tags we'll + // strip the entire chunk and replace it with a marker. + $unwrap = array(); + if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches)) + { + for ($i = 0; $i < count($matches['0']); $i++) + { + $unwrap[] = $matches['1'][$i]; + $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str); + } + } + + // Use PHP's native function to do the initial wordwrap. + // We set the cut flag to FALSE so that any individual words that are + // too long get left alone. In the next step we'll deal with them. + $str = wordwrap($str, $charlim, "\n", FALSE); + + // Split the string into individual lines of text and cycle through them + $output = ""; + foreach (explode("\n", $str) as $line) + { + // Is the line within the allowed character count? + // If so we'll join it to the output and continue + if (strlen($line) <= $charlim) + { + $output .= $line."\n"; + continue; + } + + $temp = ''; + while((strlen($line)) > $charlim) + { + // If the over-length word is a URL we won't wrap it + if (preg_match("!\[url.+\]|://|wwww.!", $line)) + { + break; + } + + // Trim the word down + $temp .= substr($line, 0, $charlim-1); + $line = substr($line, $charlim-1); + } + + // If $temp contains data it means we had to split up an over-length + // word into smaller chunks so we'll add it back to our current line + if ($temp != '') + { + $output .= $temp . "\n" . $line; + } + else + { + $output .= $line; + } + + $output .= "\n"; + } + + // Put our markers back + if (count($unwrap) > 0) + { + foreach ($unwrap as $key => $val) + { + $output = str_replace("{{unwrapped".$key."}}", $val, $output); + } + } + + // Remove the unwrap tags + $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output); + + return $output; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php new file mode 100755 index 0000000..4d9a1bb --- /dev/null +++ b/system/helpers/typography_helper.php @@ -0,0 +1,545 @@ +",$str); + $ct = count($ex); + + $newstr = ""; + for ($i = 0; $i < $ct; $i++) + { + if (($i % 2) == 0) + { + $newstr .= nl2br($ex[$i]); + } + else + { + $newstr .= $ex[$i]; + } + + if ($ct - 1 != $i) + $newstr .= "pre>"; + } + + return $newstr; + } +} + +// ------------------------------------------------------------------------ + +/** + * Auto Typography Wrapper Function + * + * + * @access public + * @param string + * @return string + */ +if (! function_exists('auto_typography')) +{ + function auto_typography($str) + { + $TYPE = new Auto_typography(); + return $TYPE->convert($str); + } +} + +// ------------------------------------------------------------------------ + +/** + * Auto Typography Class + * + * + * @access private + * @category Helpers + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/helpers/ + */ +class Auto_typography { + + // Block level elements that should not be wrapped inside

    tags + var $block_elements = 'div|blockquote|pre|code|h\d|script|ol|ul'; + + // Elements that should not have

    and
    tags within them. + var $skip_elements = 'pre|ol|ul'; + + // Tags we want the parser to completely ignore when splitting the string. + var $ignore_elements = 'a|b|i|em|strong|span|img|li'; + + + /** + * Main Processing Function + * + */ + function convert($str) + { + if ($str == '') + { + return ''; + } + + $str = ' '.$str.' '; + + // Standardize Newlines to make matching easier + $str = preg_replace("/(\r\n|\r)/", "\n", $str); + + /* + * Reduce line breaks + * + * If there are more than two consecutive line + * breaks we'll compress them down to a maximum + * of two since there's no benefit to more. + * + */ + $str = preg_replace("/\n\n+/", "\n\n", $str); + + /* + * Convert quotes within tags to temporary marker + * + * We don't want quotes converted within + * tags so we'll temporarily convert them to + * {@DQ} and {@SQ} + * + */ + if (preg_match_all("#\<.+?>#si", $str, $matches)) + { + for ($i = 0; $i < count($matches['0']); $i++) + { + $str = str_replace($matches['0'][$i], + str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches['0'][$i]), + $str); + } + } + + + /* + * Add closing/opening paragraph tags before/after "block" elements + * + * Since block elements (like ,

    , etc.) do not get
    +		 * wrapped in paragraph tags we will add a closing 

    tag just before + * each block element starts and an opening

    tag right after the block element + * ends. Later on we'll do some further clean up. + * + */ + $str = preg_replace("#(<)(".$this->block_elements.")(.*?>)#", "

    \\1\\2\\3", $str); + $str = preg_replace("#(block_elements.")(.*?>)#", "\\1\\2\\3

    ", $str); + + /* + * Convert "ignore" tags to temporary marker + * + * The parser splits out the string at every tag + * it encounters. Certain inline tags, like image + * tags, links, span tags, etc. will be adversely + * affected if they are split out so we'll convert + * the opening < temporarily to: {@TAG} + * + */ + $str = preg_replace("#<(/*)(".$this->ignore_elements.")#i", "{@TAG}\\1\\2", $str); + + /* + * Split the string at every tag + * + * This creates an array with this prototype: + * + * [array] + * { + * [0] = + * [1] = Content contained between the tags + * [2] = + * Etc... + * } + * + */ + $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + + /* + * Build our finalized string + * + * We'll cycle through the array, skipping tags, + * and processing the contained text + * + */ + $str = ''; + $process = TRUE; + foreach ($chunks as $chunk) + { + /* + * Are we dealing with a tag? + * + * If so, we'll skip the processing for this cycle. + * Well also set the "process" flag which allows us + * to skip

     tags and a few other things.
    +			 *
    +			 */
    +			if (preg_match("#<(/*)(".$this->block_elements.").*?\>#", $chunk, $match))
    +			{
    +				if (preg_match("#".$this->skip_elements."#", $match['2']))
    +				{
    +					$process =  ($match['1'] == '/') ? TRUE : FALSE;		
    +				}
    +		
    +				$str .= $chunk;
    +				continue;
    +			}
    +		
    +			if ($process == FALSE)
    +			{
    +				$str .= $chunk;
    +				continue;
    +			}
    +			
    +			//  Convert Newlines into 

    and
    tags + $str .= $this->format_newlines($chunk); + } + + // FINAL CLEAN UP + // IMPORTANT: DO NOT ALTER THE ORDER OF THE ITEMS BELOW! + + /* + * Clean up paragraph tags before/after "block" elements + * + * Earlier we added

    tags before/after block level elements. + * Then, we added paragraph tags around double line breaks. This + * potentially created incorrectly formatted paragraphs so we'll + * clean it up here. + * + */ + $str = preg_replace("#

    ({@TAG}.*?)(".$this->block_elements.")(.*?>)#", "\\1\\2\\3", $str); + $str = preg_replace("#({@TAG}/.*?)(".$this->block_elements.")(.*?>)

    #", "\\1\\2\\3", $str); + + // Convert Quotes and other characters + $str = $this->format_characters($str); + + // Fix an artifact that happens during the paragraph replacement + $str = preg_replace('#(

    \n*

    )#', '', $str); + + // If the user submitted their own paragraph tags with class data + // in them we will retain them instead of using our tags. + $str = preg_replace('#()

    #', "\\1", $str); + + // Final clean up + $str = str_replace( + array( + '

    ', + '

    ', + '

    ', + '

    ', + '{@TAG}', + '{@DQ}', + '{@SQ}', + '

    ' + ), + array( + '

    ', + '

    ', + '

    ', + '

    ', + '<', + '"', + "'", + '' + ), + $str + ); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Format Characters + * + * This function mainly converts double and single quotes + * to entities, but since these are directional, it does + * it based on some rules. It also converts em-dashes + * and a couple other things. + */ + function format_characters($str) + { + $table = array( + ' "' => " “", + '" ' => "” ", + " '" => " ‘", + "' " => "’ ", + + '>"' => ">“", + '"<' => "”<", + ">'" => ">‘", + "'<" => "’<", + + "\"." => "”.", + "\"," => "”,", + "\";" => "”;", + "\":" => "”:", + "\"!" => "”!", + "\"?" => "”?", + + ". " => ".  ", + "? " => "?  ", + "! " => "!  ", + ": " => ":  ", + ); + + // These deal with quotes within quotes, like: "'hi here'" + $start = 0; + $space = array("\n", "\t", " "); + + while(TRUE) + { + $current = strpos(substr($str, $start), "\"'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + + if ( ! in_array($one_after, $space, TRUE) && $one_after != "<") + { + $str = str_replace( $one_before."\"'".$one_after, + $one_before."“‘".$one_after, + $str); + } + elseif ( ! in_array($one_before, $space, TRUE) && (in_array($one_after, $space, TRUE) OR $one_after == '<')) + { + $str = str_replace( $one_before."\"'".$one_after, + $one_before."”’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'\""); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + + if ( in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE) && $one_after != "<") + { + $str = str_replace( $one_before."'\"".$one_after, + $one_before."‘“".$one_after, + $str); + } + elseif ( ! in_array($one_before, $space, TRUE) && $one_before != ">") + { + $str = str_replace( $one_before."'\"".$one_after, + $one_before."’”".$one_after, + $str); + } + + $start = $start+$current+2; + } + + // Are there quotes within a word, as in: ("something") + if (preg_match_all("/(.)\"(\S+?)\"(.)/", $str, $matches)) + { + for ($i=0, $s=sizeof($matches['0']); $i < $s; ++$i) + { + if ( ! in_array($matches['1'][$i], $space, TRUE) && ! in_array($matches['3'][$i], $space, TRUE)) + { + $str = str_replace( $matches['0'][$i], + $matches['1'][$i]."“".$matches['2'][$i]."”".$matches['3'][$i], + $str); + } + } + } + + if (preg_match_all("/(.)\'(\S+?)\'(.)/", $str, $matches)) + { + for ($i=0, $s=sizeof($matches['0']); $i < $s; ++$i) + { + if ( ! in_array($matches['1'][$i], $space, TRUE) && ! in_array($matches['3'][$i], $space, TRUE)) + { + $str = str_replace( $matches['0'][$i], + $matches['1'][$i]."‘".$matches['2'][$i]."’".$matches['3'][$i], + $str); + } + } + } + + // How about one apostrophe, as in Rick's + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + // Em-dashes + $start = 0; + while(TRUE) + { + $current = strpos(substr($str, $start), "--"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+2, 1); + $two_before = substr($str, $start+$current-2, 1); + $two_after = substr($str, $start+$current+3, 1); + + if (( ! in_array($one_before, $space, TRUE) && ! in_array($one_after, $space, TRUE)) + OR + ( ! in_array($two_before, $space, TRUE) && ! in_array($two_after, $space, TRUE) && $one_before == ' ' && $one_after == ' ') + ) + { + $str = str_replace( $two_before.$one_before."--".$one_after.$two_after, + $two_before.trim($one_before)."—".trim($one_after).$two_after, + $str); + } + + $start = $start+$current+2; + } + + // Ellipsis + $str = preg_replace("#(\w)\.\.\.(\s|
    |

    )#", "\\1…\\2", $str); + $str = preg_replace("#(\s|
    |

    )\.\.\.(\w)#", "\\1…\\2", $str); + + // Run the translation array we defined above + $str = str_replace(array_keys($table), array_values($table), $str); + + // If there are any stray double quotes we'll catch them here + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), '"'); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before.'"'.$one_after, + $one_before."“".$one_after, + $str); + } + elseif( ! in_array($one_before, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."”".$one_after, + $str); + } + + $start = $start+$current+2; + } + + $start = 0; + + while(TRUE) + { + $current = strpos(substr($str, $start), "'"); + + if ($current === FALSE) break; + + $one_before = substr($str, $start+$current-1, 1); + $one_after = substr($str, $start+$current+1, 1); + + if ( ! in_array($one_after, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."‘".$one_after, + $str); + } + elseif( ! in_array($one_before, $space, TRUE)) + { + $str = str_replace( $one_before."'".$one_after, + $one_before."’".$one_after, + $str); + } + + $start = $start+$current+2; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Format Newlines + * + * Converts newline characters into either

    tags or
    + * + */ + function format_newlines($str) + { + if ($str == '') + { + return $str; + } + + if (strpos($str, "\n") === FALSE) + { + return '

    '.$str.'

    '; + } + + $str = str_replace("\n\n", "

    \n\n

    ", $str); + $str = preg_replace("/([^\n])(\n)([^\n])/", "\\1
    \\2\\3", $str); + + return '

    '.$str.'

    '; + } +} + + +?> \ No newline at end of file diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php new file mode 100755 index 0000000..d190488 --- /dev/null +++ b/system/helpers/url_helper.php @@ -0,0 +1,545 @@ +config->site_url($uri); + } +} + +// ------------------------------------------------------------------------ + +/** + * Base URL + * + * Returns the "base_url" item from your config file + * + * @access public + * @return string + */ +if (! function_exists('base_url')) +{ + function base_url() + { + $CI =& get_instance(); + return $CI->config->slash_item('base_url'); + } +} + +// ------------------------------------------------------------------------ + +/** + * Index page + * + * Returns the "index_page" from your config file + * + * @access public + * @return string + */ +if (! function_exists('index_page')) +{ + function index_page() + { + $CI =& get_instance(); + return $CI->config->item('index_page'); + } +} + +// ------------------------------------------------------------------------ + +/** + * Anchor Link + * + * Creates an anchor based on the local URL. + * + * @access public + * @param string the URL + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('anchor')) +{ + function anchor($uri = '', $title = '', $attributes = '') + { + $title = (string) $title; + + if ( ! is_array($uri)) + { + $site_url = ( ! preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + } + else + { + $site_url = site_url($uri); + } + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes == '') + { + $attributes = ' title="'.$title.'"'; + } + else + { + $attributes = _parse_attributes($attributes); + } + + return ''.$title.''; + } +} + +// ------------------------------------------------------------------------ + +/** + * Anchor Link - Pop-up version + * + * Creates an anchor based on the local URL. The link + * opens a new window based on the attributes specified. + * + * @access public + * @param string the URL + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('anchor_popup')) +{ + function anchor_popup($uri = '', $title = '', $attributes = FALSE) + { + $title = (string) $title; + + $site_url = ( ! preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes === FALSE) + { + return "".$title.""; + } + + if ( ! is_array($attributes)) + { + $attributes = array(); + } + + foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val) + { + $atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key]; + } + + return "".$title.""; + } +} + +// ------------------------------------------------------------------------ + +/** + * Mailto Link + * + * @access public + * @param string the email address + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('mailto')) +{ + function mailto($email, $title = '', $attributes = '') + { + $title = (string) $title; + + if ($title == "") + { + $title = $email; + } + + $attributes = _parse_attributes($attributes); + + return ''.$title.''; + } +} + +// ------------------------------------------------------------------------ + +/** + * Encoded Mailto Link + * + * Create a spam-protected mailto link written in Javascript + * + * @access public + * @param string the email address + * @param string the link title + * @param mixed any attributes + * @return string + */ +if (! function_exists('safe_mailto')) +{ + function safe_mailto($email, $title = '', $attributes = '') + { + $title = (string) $title; + + if ($title == "") + { + $title = $email; + } + + for ($i = 0; $i < 16; $i++) + { + $x[] = substr(' $val) + { + $x[] = ' '.$key.'="'; + for ($i = 0; $i < strlen($val); $i++) + { + $x[] = "|".ord(substr($val, $i, 1)); + } + $x[] = '"'; + } + } + else + { + for ($i = 0; $i < strlen($attributes); $i++) + { + $x[] = substr($attributes, $i, 1); + } + } + } + + $x[] = '>'; + + $temp = array(); + for ($i = 0; $i < strlen($title); $i++) + { + $ordinal = ord($title[$i]); + + if ($ordinal < 128) + { + $x[] = "|".$ordinal; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + $x[] = "|".$number; + $count = 1; + $temp = array(); + } + } + } + + $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>'; + + $x = array_reverse($x); + ob_start(); + + ?>http'. + $matches['4'][$i].'://'. + $matches['5'][$i]. + $matches['6'][$i].''. + $period, $str); + } + } + } + + if ($type != 'url') + { + if (preg_match_all("/([a-zA-Z0-9_\.\-]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches)) + { + for ($i = 0; $i < sizeof($matches['0']); $i++) + { + $period = ''; + if (preg_match("|\.$|", $matches['3'][$i])) + { + $period = '.'; + $matches['3'][$i] = substr($matches['3'][$i], 0, -1); + } + + $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str); + } + + } + } + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Prep URL + * + * Simply adds the http:// part if missing + * + * @access public + * @param string the URL + * @return string + */ +if (! function_exists('prep_url')) +{ + function prep_url($str = '') + { + if ($str == 'http://' OR $str == '') + { + return ''; + } + + if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') + { + $str = 'http://'.$str; + } + + return $str; + } +} + +// ------------------------------------------------------------------------ + +/** + * Create URL Title + * + * Takes a "title" string as input and creates a + * human-friendly URL string with either a dash + * or an underscore as the word separator. + * + * @access public + * @param string the string + * @param string the separator: dash, or underscore + * @return string + */ +if (! function_exists('url_title')) +{ + function url_title($str, $separator = 'dash') + { + if ($separator == 'dash') + { + $search = '_'; + $replace = '-'; + } + else + { + $search = '-'; + $replace = '_'; + } + + /* debut modif */ + $caracteres_speciaux = array( + "¥" => "Y", "µ" => "u", "À" => "A", "Á" => "A", "Â" => "A", "Ã" => "A", "Ä" => "A", "Å" => "A", "Æ" => "A", "Ç" => "C", "È" => "E", "É" => "E", "Ê" => "E", "Ë" => "E", "Ì" => "I", "Í" => "I", "Î" => "I", "Ï" => "I", "Ð" => "D", "Ñ" => "N", "Ò" => "O", "Ó" => "O", "Ô" => "O", "Õ" => "O", "Ö" => "O", "Ø" => "O", "Ù" => "U", "Ú" => "U", "Û" => "U", "Ü" => "U", "Ý" => "Y", "ß" => "s", "à" => "a", "á" => "a", "â" => "a", "ã" => "a", "ä" => "a", "å" => "a", "æ" => "a", "ç" => "c", "è" => "e", "é" => "e", "ê" => "e", "ë" => "e", "ì" => "i", "í" => "i", "î" => "i", "ï" => "i", "ð" => "o", "ñ" => "n", "ò" => "o", "ó" => "o", "ô" => "o", "õ" => "o", "ö" => "o", "ø" => "o", "ù" => "u", "ú" => "u", "û" => "u", "ü" => "u", "ý" => "y", "ÿ" => "y", "€" => "e"); + + $str = strtr($str, $caracteres_speciaux); + + /* fin modif */ + + $trans = array( + $search => $replace, + "\s+" => $replace, + "[^a-z0-9".$replace."]" => '', + $replace."+" => $replace, + $replace."$" => '', + "^".$replace => '' + ); + + $str = strip_tags(strtolower($str)); + + foreach ($trans as $key => $val) + { + $str = preg_replace("#".$key."#", $val, $str); + } + + return trim(stripslashes($str)); + } +} + +// ------------------------------------------------------------------------ + +/** + * Header Redirect + * + * Header redirect in two flavors + * + * @access public + * @param string the URL + * @param string the method: location or redirect + * @return string + */ +if (! function_exists('redirect')) +{ + function redirect($uri = '', $method = 'location') + { + switch($method) + { + case 'refresh' : header("Refresh:0;url=".site_url($uri)); + break; + default : header("Location: ".site_url($uri)); + break; + } + exit; + } +} + +// ------------------------------------------------------------------------ + +/** + * Parse out the attributes + * + * Some of the functions use this + * + * @access private + * @param array + * @param bool + * @return string + */ +if (! function_exists('_parse_attributes')) +{ + function _parse_attributes($attributes, $javascript = FALSE) + { + if (is_string($attributes)) + { + return ($attributes != '') ? ' '.$attributes : ''; + } + + $att = ''; + foreach ($attributes as $key => $val) + { + if ($javascript == TRUE) + { + $att .= $key . '=' . $val . ','; + } + else + { + $att .= ' ' . $key . '="' . $val . '"'; + } + } + + if ($javascript == TRUE AND $att != '') + { + $att = substr($att, 0, -1); + } + + return $att; + } +} + +?> \ No newline at end of file diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php new file mode 100755 index 0000000..5aa6de9 --- /dev/null +++ b/system/helpers/xml_helper.php @@ -0,0 +1,60 @@ +","\"", "'", "-"), + array("&", "<", ">", """, "'", "-"), + $str); + + // Decode the temp markers back to entities + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;", $str); + + return $str; + } +} + +?> \ No newline at end of file diff --git a/system/language/.svn/all-wcprops b/system/language/.svn/all-wcprops new file mode 100644 index 0000000..65677ce --- /dev/null +++ b/system/language/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/!svn/ver/18/trunk/system/language +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/language/index.html +END diff --git a/system/language/.svn/entries b/system/language/.svn/entries new file mode 100644 index 0000000..10b118b --- /dev/null +++ b/system/language/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/language +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +english +dir + +index.html +file + + + + +2009-09-15T00:18:05.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/language/.svn/prop-base/index.html.svn-base b/system/language/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/.svn/text-base/index.html.svn-base b/system/language/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/language/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/language/english/.svn/all-wcprops b/system/language/english/.svn/all-wcprops new file mode 100644 index 0000000..d405fa2 --- /dev/null +++ b/system/language/english/.svn/all-wcprops @@ -0,0 +1,77 @@ +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/!svn/ver/18/trunk/system/language/english +END +calendar_lang.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/language/english/calendar_lang.php +END +ftp_lang.php +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/language/english/ftp_lang.php +END +validation_lang.php +K 25 +svn:wc:ra_dav:version-url +V 66 +/svn/!svn/ver/18/trunk/system/language/english/validation_lang.php +END +date_lang.php +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/!svn/ver/18/trunk/system/language/english/date_lang.php +END +unit_test_lang.php +K 25 +svn:wc:ra_dav:version-url +V 65 +/svn/!svn/ver/18/trunk/system/language/english/unit_test_lang.php +END +scaffolding_lang.php +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/18/trunk/system/language/english/scaffolding_lang.php +END +profiler_lang.php +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/18/trunk/system/language/english/profiler_lang.php +END +imglib_lang.php +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/language/english/imglib_lang.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/language/english/index.html +END +upload_lang.php +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/language/english/upload_lang.php +END +db_lang.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/language/english/db_lang.php +END +email_lang.php +K 25 +svn:wc:ra_dav:version-url +V 61 +/svn/!svn/ver/18/trunk/system/language/english/email_lang.php +END diff --git a/system/language/english/.svn/entries b/system/language/english/.svn/entries new file mode 100644 index 0000000..1aa330d --- /dev/null +++ b/system/language/english/.svn/entries @@ -0,0 +1,436 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/language/english +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +calendar_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +fd0993d014c36c9907ce418763a211ad +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1418 + +ftp_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +923ec198d1a138a60e29a635283d99dd +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1121 + +validation_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +39343b81e9715d8977a2167fae820d82 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1029 + +date_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +efbf943a9a462627ac826520835abd43 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2306 + +unit_test_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +936cccf21ec22d7788ee8e8ac02bbaa6 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +701 + +scaffolding_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +570fb60b9d85415046a7b2a5b9b4f14a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +501 + +profiler_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +3fdf76d3953e12a6436250a79cb4841e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +610 + +imglib_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +b2275ea04532eeef5e41bc30eb6c56af +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1821 + +index.html +file + + + + +2009-09-15T00:18:05.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +upload_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +6fe6b58d4f85e359f456d6b018d977d3 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1548 + +db_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +5e5fe76cc013fbc605e1971530a1226e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1955 + +email_lang.php +file + + + + +2009-09-15T00:18:05.000000Z +a00264a63166c40f5c4c5f18a6751c8f +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1586 + diff --git a/system/language/english/.svn/prop-base/calendar_lang.php.svn-base b/system/language/english/.svn/prop-base/calendar_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/calendar_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/date_lang.php.svn-base b/system/language/english/.svn/prop-base/date_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/date_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/db_lang.php.svn-base b/system/language/english/.svn/prop-base/db_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/db_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/email_lang.php.svn-base b/system/language/english/.svn/prop-base/email_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/email_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/ftp_lang.php.svn-base b/system/language/english/.svn/prop-base/ftp_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/ftp_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/imglib_lang.php.svn-base b/system/language/english/.svn/prop-base/imglib_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/imglib_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/index.html.svn-base b/system/language/english/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/profiler_lang.php.svn-base b/system/language/english/.svn/prop-base/profiler_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/profiler_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/scaffolding_lang.php.svn-base b/system/language/english/.svn/prop-base/scaffolding_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/scaffolding_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/unit_test_lang.php.svn-base b/system/language/english/.svn/prop-base/unit_test_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/unit_test_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/upload_lang.php.svn-base b/system/language/english/.svn/prop-base/upload_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/upload_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/prop-base/validation_lang.php.svn-base b/system/language/english/.svn/prop-base/validation_lang.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/language/english/.svn/prop-base/validation_lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/language/english/.svn/text-base/calendar_lang.php.svn-base b/system/language/english/.svn/text-base/calendar_lang.php.svn-base new file mode 100644 index 0000000..9ee4a5e --- /dev/null +++ b/system/language/english/.svn/text-base/calendar_lang.php.svn-base @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/date_lang.php.svn-base b/system/language/english/.svn/text-base/date_lang.php.svn-base new file mode 100644 index 0000000..6b18aa7 --- /dev/null +++ b/system/language/english/.svn/text-base/date_lang.php.svn-base @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/db_lang.php.svn-base b/system/language/english/.svn/text-base/db_lang.php.svn-base new file mode 100644 index 0000000..1e79a70 --- /dev/null +++ b/system/language/english/.svn/text-base/db_lang.php.svn-base @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/email_lang.php.svn-base b/system/language/english/.svn/text-base/email_lang.php.svn-base new file mode 100644 index 0000000..f026865 --- /dev/null +++ b/system/language/english/.svn/text-base/email_lang.php.svn-base @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/ftp_lang.php.svn-base b/system/language/english/.svn/text-base/ftp_lang.php.svn-base new file mode 100644 index 0000000..da744fe --- /dev/null +++ b/system/language/english/.svn/text-base/ftp_lang.php.svn-base @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/imglib_lang.php.svn-base b/system/language/english/.svn/text-base/imglib_lang.php.svn-base new file mode 100644 index 0000000..520f17f --- /dev/null +++ b/system/language/english/.svn/text-base/imglib_lang.php.svn-base @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/index.html.svn-base b/system/language/english/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/language/english/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/profiler_lang.php.svn-base b/system/language/english/.svn/text-base/profiler_lang.php.svn-base new file mode 100644 index 0000000..219a838 --- /dev/null +++ b/system/language/english/.svn/text-base/profiler_lang.php.svn-base @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base b/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base new file mode 100644 index 0000000..96fe167 --- /dev/null +++ b/system/language/english/.svn/text-base/scaffolding_lang.php.svn-base @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/unit_test_lang.php.svn-base b/system/language/english/.svn/text-base/unit_test_lang.php.svn-base new file mode 100644 index 0000000..a33cad5 --- /dev/null +++ b/system/language/english/.svn/text-base/unit_test_lang.php.svn-base @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/upload_lang.php.svn-base b/system/language/english/.svn/text-base/upload_lang.php.svn-base new file mode 100644 index 0000000..fa6d7c9 --- /dev/null +++ b/system/language/english/.svn/text-base/upload_lang.php.svn-base @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/system/language/english/.svn/text-base/validation_lang.php.svn-base b/system/language/english/.svn/text-base/validation_lang.php.svn-base new file mode 100644 index 0000000..1e9ec2c --- /dev/null +++ b/system/language/english/.svn/text-base/validation_lang.php.svn-base @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php new file mode 100755 index 0000000..9ee4a5e --- /dev/null +++ b/system/language/english/calendar_lang.php @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php new file mode 100755 index 0000000..6b18aa7 --- /dev/null +++ b/system/language/english/date_lang.php @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php new file mode 100755 index 0000000..1e79a70 --- /dev/null +++ b/system/language/english/db_lang.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php new file mode 100755 index 0000000..f026865 --- /dev/null +++ b/system/language/english/email_lang.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php new file mode 100755 index 0000000..da744fe --- /dev/null +++ b/system/language/english/ftp_lang.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php new file mode 100755 index 0000000..520f17f --- /dev/null +++ b/system/language/english/imglib_lang.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/system/language/english/index.html b/system/language/english/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/language/english/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php new file mode 100755 index 0000000..219a838 --- /dev/null +++ b/system/language/english/profiler_lang.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/scaffolding_lang.php b/system/language/english/scaffolding_lang.php new file mode 100755 index 0000000..96fe167 --- /dev/null +++ b/system/language/english/scaffolding_lang.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php new file mode 100755 index 0000000..a33cad5 --- /dev/null +++ b/system/language/english/unit_test_lang.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php new file mode 100755 index 0000000..fa6d7c9 --- /dev/null +++ b/system/language/english/upload_lang.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/system/language/english/validation_lang.php b/system/language/english/validation_lang.php new file mode 100755 index 0000000..1e9ec2c --- /dev/null +++ b/system/language/english/validation_lang.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/system/language/index.html b/system/language/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/language/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/libraries/.svn/all-wcprops b/system/libraries/.svn/all-wcprops new file mode 100644 index 0000000..da50aef --- /dev/null +++ b/system/libraries/.svn/all-wcprops @@ -0,0 +1,203 @@ +K 25 +svn:wc:ra_dav:version-url +V 39 +/svn/!svn/ver/18/trunk/system/libraries +END +Pagination.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/libraries/Pagination.php +END +Parser.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Parser.php +END +User_agent.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/libraries/User_agent.php +END +Sha1.php +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/18/trunk/system/libraries/Sha1.php +END +Output.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Output.php +END +Zip.php +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/libraries/Zip.php +END +Config.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Config.php +END +Loader.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Loader.php +END +Calendar.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/libraries/Calendar.php +END +Unit_test.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/libraries/Unit_test.php +END +Profiler.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/libraries/Profiler.php +END +Controller.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/libraries/Controller.php +END +Language.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/libraries/Language.php +END +Encrypt.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/libraries/Encrypt.php +END +Upload.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Upload.php +END +Email.php +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/libraries/Email.php +END +Xmlrpcs.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/libraries/Xmlrpcs.php +END +Ftp.php +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/libraries/Ftp.php +END +Benchmark.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/libraries/Benchmark.php +END +Validation.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/libraries/Validation.php +END +Input.php +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/libraries/Input.php +END +URI.php +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/libraries/URI.php +END +Model.php +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/libraries/Model.php +END +Xmlrpc.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Xmlrpc.php +END +Image_lib.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/libraries/Image_lib.php +END +Router.php +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/Router.php +END +Log.php +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/libraries/Log.php +END +Exceptions.php +K 25 +svn:wc:ra_dav:version-url +V 54 +/svn/!svn/ver/18/trunk/system/libraries/Exceptions.php +END +Session.php +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/18/trunk/system/libraries/Session.php +END +Hooks.php +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/libraries/Hooks.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/18/trunk/system/libraries/index.html +END +Trackback.php +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/!svn/ver/18/trunk/system/libraries/Trackback.php +END +Table.php +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/18/trunk/system/libraries/Table.php +END diff --git a/system/libraries/.svn/entries b/system/libraries/.svn/entries new file mode 100644 index 0000000..e97eb26 --- /dev/null +++ b/system/libraries/.svn/entries @@ -0,0 +1,1150 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/libraries +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +Pagination.php +file + + + + +2009-09-15T00:18:29.000000Z +c3cec0e3861782a7ac18f00b0fc72a92 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +6160 + +Parser.php +file + + + + +2009-09-15T00:18:29.000000Z +bf3eb659f1d3da6c61ce511899cf3b13 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3584 + +User_agent.php +file + + + + +2009-09-15T00:18:29.000000Z +eec51ddb5cf05ee85eb421f49efe70be +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9917 + +Sha1.php +file + + + + +2009-09-15T00:18:29.000000Z +bc3bd9001bfc564c998af1f36daef569 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5171 + +Output.php +file + + + + +2009-09-15T00:18:29.000000Z +1d554d8996b740066428f638e7f88398 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9458 + +Zip.php +file + + + + +2009-09-15T00:18:29.000000Z +ed67ce1d15f26bde167627c1d883f078 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +8895 + +Config.php +file + + + + +2009-09-15T00:18:29.000000Z +a23c17864641b049851823ce91719637 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +5441 + +Loader.php +file + + + + +2009-09-15T00:18:29.000000Z +69a83a085130f11c1db35cd3a7ede14a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +24835 + +Calendar.php +file + + + + +2009-09-15T00:18:29.000000Z +fa59ba7d3dd37ae52519d64038467c59 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +13204 + +Unit_test.php +file + + + + +2009-09-15T00:18:29.000000Z +3f0f2ecf18d8d96b9ba2ab080ab28e9c +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7304 + +Profiler.php +file + + + + +2009-09-15T00:18:29.000000Z +c78b96f5f6b99087657ec6312c603a25 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +11003 + +Controller.php +file + + + + +2009-09-15T00:18:29.000000Z +bf56145393fce00ab3baeab0e9092be3 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +3223 + +Language.php +file + + + + +2009-09-15T00:18:29.000000Z +c75526843efdaac21b3925ab5275459f +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2894 + +Encrypt.php +file + + + + +2009-09-15T00:18:29.000000Z +fa8de0243d636dcf4323b4b62a2efe6b +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +10518 + +Upload.php +file + + + + +2009-09-15T00:18:29.000000Z +6e85ac87e478206cd4dfd602e79e6d4e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +19035 + +Email.php +file + + + + +2009-09-15T00:18:29.000000Z +9f012fd005e5e394bf6bbab55cdfad0c +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +45201 + +Xmlrpcs.php +file + + + + +2009-09-15T00:18:29.000000Z +c63a99528a2fefcf0024fc1a95b5c806 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15035 + +Ftp.php +file + + + + +2009-09-15T00:18:29.000000Z +0931c73f8bd2ff39136cfce278d8c2b3 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +12457 + +Benchmark.php +file + + + + +2009-09-15T00:18:29.000000Z +c4c53618d4a734ed7e1fdacb7b689f63 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2900 + +Validation.php +file + + + + +2009-09-15T00:18:29.000000Z +f5550f458d769d0623a3078f572cab10 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +17086 + +Input.php +file + + + + +2009-09-15T00:18:29.000000Z +bd1af255d05aa330d17f18296cb072f7 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +23483 + +URI.php +file + + + + +2009-09-15T00:18:29.000000Z +9103889c3d35fff449971c7560f11714 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +13254 + +Model.php +file + + + + +2009-09-15T00:18:29.000000Z +0f42ba9f0dcb021301f57fad83babc56 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2156 + +Xmlrpc.php +file + + + + +2009-09-15T00:18:29.000000Z +ad5919b528c53143c3974b1d63dc7fc6 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +34840 + +Image_lib.php +file + + + + +2009-09-15T00:18:29.000000Z +973ea07f40c12290186cc2278463c7f1 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +38526 + +Router.php +file + + + + +2009-09-15T00:18:29.000000Z +9fc781977e4df8723cbfef70669d9a49 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9740 + +Log.php +file + + + + +2009-09-15T00:18:29.000000Z +ef5f4770780dc77a170d58f848980a15 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +2844 + +Exceptions.php +file + + + + +2009-09-15T00:18:29.000000Z +2fff23648d1f0e74408f07a455d59ea7 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4372 + +Session.php +file + + + + +2009-09-15T00:18:29.000000Z +9cffa206fad08fa4dfe424df51122723 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15265 + +Hooks.php +file + + + + +2009-09-15T00:18:29.000000Z +984946a3584f6aa302998c1e499fe30d +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4528 + +index.html +file + + + + +2009-09-15T00:18:29.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +Trackback.php +file + + + + +2009-09-15T00:18:29.000000Z +bc08387c3a711379b256d9211ae6312f +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +12688 + +Table.php +file + + + + +2009-09-15T00:18:29.000000Z +ef3d633fbe5a9466b8b79922315a9593 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9584 + diff --git a/system/libraries/.svn/prop-base/Benchmark.php.svn-base b/system/libraries/.svn/prop-base/Benchmark.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Benchmark.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Calendar.php.svn-base b/system/libraries/.svn/prop-base/Calendar.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Calendar.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Config.php.svn-base b/system/libraries/.svn/prop-base/Config.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Config.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Controller.php.svn-base b/system/libraries/.svn/prop-base/Controller.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Controller.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Email.php.svn-base b/system/libraries/.svn/prop-base/Email.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Email.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Encrypt.php.svn-base b/system/libraries/.svn/prop-base/Encrypt.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Encrypt.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Exceptions.php.svn-base b/system/libraries/.svn/prop-base/Exceptions.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Exceptions.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Ftp.php.svn-base b/system/libraries/.svn/prop-base/Ftp.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Ftp.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Hooks.php.svn-base b/system/libraries/.svn/prop-base/Hooks.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Hooks.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Image_lib.php.svn-base b/system/libraries/.svn/prop-base/Image_lib.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Image_lib.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Input.php.svn-base b/system/libraries/.svn/prop-base/Input.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Input.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Language.php.svn-base b/system/libraries/.svn/prop-base/Language.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Language.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Loader.php.svn-base b/system/libraries/.svn/prop-base/Loader.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Loader.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Log.php.svn-base b/system/libraries/.svn/prop-base/Log.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Log.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Model.php.svn-base b/system/libraries/.svn/prop-base/Model.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Model.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Output.php.svn-base b/system/libraries/.svn/prop-base/Output.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Output.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Pagination.php.svn-base b/system/libraries/.svn/prop-base/Pagination.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Pagination.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Parser.php.svn-base b/system/libraries/.svn/prop-base/Parser.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Parser.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Profiler.php.svn-base b/system/libraries/.svn/prop-base/Profiler.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Profiler.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Router.php.svn-base b/system/libraries/.svn/prop-base/Router.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Router.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Session.php.svn-base b/system/libraries/.svn/prop-base/Session.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Session.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Sha1.php.svn-base b/system/libraries/.svn/prop-base/Sha1.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Sha1.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Table.php.svn-base b/system/libraries/.svn/prop-base/Table.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Table.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Trackback.php.svn-base b/system/libraries/.svn/prop-base/Trackback.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Trackback.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/URI.php.svn-base b/system/libraries/.svn/prop-base/URI.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/URI.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Unit_test.php.svn-base b/system/libraries/.svn/prop-base/Unit_test.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Unit_test.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Upload.php.svn-base b/system/libraries/.svn/prop-base/Upload.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Upload.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/User_agent.php.svn-base b/system/libraries/.svn/prop-base/User_agent.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/User_agent.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Validation.php.svn-base b/system/libraries/.svn/prop-base/Validation.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Validation.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Xmlrpc.php.svn-base b/system/libraries/.svn/prop-base/Xmlrpc.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Xmlrpc.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Xmlrpcs.php.svn-base b/system/libraries/.svn/prop-base/Xmlrpcs.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Xmlrpcs.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/Zip.php.svn-base b/system/libraries/.svn/prop-base/Zip.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/Zip.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/prop-base/index.html.svn-base b/system/libraries/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/libraries/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/libraries/.svn/text-base/Benchmark.php.svn-base b/system/libraries/.svn/text-base/Benchmark.php.svn-base new file mode 100644 index 0000000..bca3782 --- /dev/null +++ b/system/libraries/.svn/text-base/Benchmark.php.svn-base @@ -0,0 +1,111 @@ +marker[$name] = microtime(); + } + + // -------------------------------------------------------------------- + + /** + * Calculates the time difference between two marked points. + * + * If the first parameter is empty this function instead returns the + * {elapsed_time} pseudo-variable. This permits the full system + * execution time to be shown in a template. The output class will + * swap the real value for this variable. + * + * @access public + * @param string a particular marked point + * @param string a particular marked point + * @param integer the number of decimal places + * @return mixed + */ + function elapsed_time($point1 = '', $point2 = '', $decimals = 4) + { + if ($point1 == '') + { + return '{elapsed_time}'; + } + + if ( ! isset($this->marker[$point1])) + { + return ''; + } + + if ( ! isset($this->marker[$point2])) + { + $this->marker[$point2] = microtime(); + } + + list($sm, $ss) = explode(' ', $this->marker[$point1]); + list($em, $es) = explode(' ', $this->marker[$point2]); + + return number_format(($em + $es) - ($sm + $ss), $decimals); + } + + // -------------------------------------------------------------------- + + /** + * Memory Usage + * + * This function returns the {memory_usage} pseudo-variable. + * This permits it to be put it anywhere in a template + * without the memory being calculated until the end. + * The output class will swap the real value for this variable. + * + * @access public + * @return string + */ + function memory_usage() + { + return '{memory_usage}'; + } + +} + +// END CI_Benchmark class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Calendar.php.svn-base b/system/libraries/.svn/text-base/Calendar.php.svn-base new file mode 100644 index 0000000..a85c183 --- /dev/null +++ b/system/libraries/.svn/text-base/Calendar.php.svn-base @@ -0,0 +1,475 @@ +CI =& get_instance(); + + if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE)) + { + $this->CI->lang->load('calendar'); + } + + $this->local_time = time(); + + if (count($config) > 0) + { + $this->initialize($config); + } + + log_message('debug', "Calendar Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the user preferences + * + * Accepts an associative array as input, containing display preferences + * + * @access public + * @param array config preferences + * @return void + */ + function initialize($config = array()) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Generate the calendar + * + * @access public + * @param integer the year + * @param integer the month + * @param array the data to be shown in the calendar cells + * @return string + */ + function generate($year = '', $month = '', $data = array()) + { + // Set and validate the supplied month/year + if ($year == '') + $year = date("Y", $this->local_time); + + if ($month == '') + $month = date("m", $this->local_time); + + if (strlen($year) == 1) + $year = '200'.$year; + + if (strlen($year) == 2) + $year = '20'.$year; + + if (strlen($month) == 1) + $month = '0'.$month; + + $adjusted_date = $this->adjust_date($month, $year); + + $month = $adjusted_date['month']; + $year = $adjusted_date['year']; + + // Determine the total days in the month + $total_days = $this->get_total_days($month, $year); + + // Set the starting day of the week + $start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6); + $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day]; + + // Set the starting day number + $local_date = mktime(12, 0, 0, $month, 1, $year); + $date = getdate($local_date); + $day = $start_day + 1 - $date["wday"]; + + while ($day > 1) + { + $day -= 7; + } + + // Set the current month/year/day + // We use this to determine the "today" date + $cur_year = date("Y", $this->local_time); + $cur_month = date("m", $this->local_time); + $cur_day = date("j", $this->local_time); + + $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE; + + // Generate the template data array + $this->parse_template(); + + // Begin building the calendar output + $out = $this->temp['table_open']; + $out .= "\n"; + + $out .= "\n"; + $out .= $this->temp['heading_row_start']; + $out .= "\n"; + + // "previous" month link + if ($this->show_next_prev == TRUE) + { + // Add a trailing slash to the URL if needed + $this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url); + + $adjusted_date = $this->adjust_date($month - 1, $year); + $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']); + $out .= "\n"; + } + + // Heading containing the month/year + $colspan = ($this->show_next_prev == TRUE) ? 5 : 7; + + $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']); + $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)." ".$year, $this->temp['heading_title_cell']); + + $out .= $this->temp['heading_title_cell']; + $out .= "\n"; + + // "next" month link + if ($this->show_next_prev == TRUE) + { + $adjusted_date = $this->adjust_date($month + 1, $year); + $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']); + } + + $out .= "\n"; + $out .= $this->temp['heading_row_end']; + $out .= "\n"; + + // Write the cells containing the days of the week + $out .= "\n"; + $out .= $this->temp['week_row_start']; + $out .= "\n"; + + $day_names = $this->get_day_names(); + + for ($i = 0; $i < 7; $i ++) + { + $out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']); + } + + $out .= "\n"; + $out .= $this->temp['week_row_end']; + $out .= "\n"; + + // Build the main body of the calendar + while ($day <= $total_days) + { + $out .= "\n"; + $out .= $this->temp['cal_row_start']; + $out .= "\n"; + + for ($i = 0; $i < 7; $i++) + { + $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start']; + + if ($day > 0 AND $day <= $total_days) + { + if (isset($data[$day])) + { + // Cells with content + $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content']; + $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp)); + } + else + { + // Cells with no content + $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content']; + $out .= str_replace('{day}', $day, $temp); + } + } + else + { + // Blank cells + $out .= $this->temp['cal_cell_blank']; + } + + $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; + $day++; + } + + $out .= "\n"; + $out .= $this->temp['cal_row_end']; + $out .= "\n"; + } + + $out .= "\n"; + $out .= $this->temp['table_close']; + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Get Month Name + * + * Generates a textual month name based on the numeric + * month provided. + * + * @access public + * @param integer the month + * @return string + */ + function get_month_name($month) + { + if ($this->month_type == 'short') + { + $month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec'); + } + else + { + $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_may', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december'); + } + + $month = $month_names[$month]; + + if ($this->CI->lang->line($month) === FALSE) + { + return ucfirst(str_replace('cal_', '', $month)); + } + + return $this->CI->lang->line($month); + } + + // -------------------------------------------------------------------- + + /** + * Get Day Names + * + * Returns an array of day names (Sunday, Monday, etc.) based + * on the type. Options: long, short, abrev + * + * @access public + * @param string + * @return array + */ + function get_day_names($day_type = '') + { + if ($day_type != '') + $this->day_type = $day_type; + + if ($this->day_type == 'long') + { + $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); + } + elseif ($this->day_type == 'short') + { + $day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'); + } + else + { + $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'); + } + + $days = array(); + foreach ($day_names as $val) + { + $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val); + } + + return $days; + } + + // -------------------------------------------------------------------- + + /** + * Adjust Date + * + * This function makes sure that we have a valid month/year. + * For example, if you submit 13 as the month, the year will + * increment and the month will become January. + * + * @access public + * @param integer the month + * @param integer the year + * @return array + */ + function adjust_date($month, $year) + { + $date = array(); + + $date['month'] = $month; + $date['year'] = $year; + + while ($date['month'] > 12) + { + $date['month'] -= 12; + $date['year']++; + } + + while ($date['month'] <= 0) + { + $date['month'] += 12; + $date['year']--; + } + + if (strlen($date['month']) == 1) + { + $date['month'] = '0'.$date['month']; + } + + return $date; + } + + // -------------------------------------------------------------------- + + /** + * Total days in a given month + * + * @access public + * @param integer the month + * @param integer the year + * @return integer + */ + function get_total_days($month, $year) + { + $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + + if ($month < 1 OR $month > 12) + { + return 0; + } + + // Is the year a leap year? + if ($month == 2) + { + if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0)) + { + return 29; + } + } + + return $days_in_month[$month - 1]; + } + + // -------------------------------------------------------------------- + + /** + * Set Default Template Data + * + * This is used in the event that the user has not created their own template + * + * @access public + * @return array + */ + function default_template() + { + return array ( + 'table_open' => '

    ', + 'heading_row_start' => '', + 'heading_previous_cell' => '', + 'heading_title_cell' => '', + 'heading_next_cell' => '', + 'heading_row_end' => '', + 'week_row_start' => '', + 'week_day_cell' => '', + 'week_row_end' => '', + 'cal_row_start' => '', + 'cal_cell_start' => '', + 'cal_cell_end_today' => '', + 'cal_row_end' => '', + 'table_close' => '
    <<{heading}>>
    {week_day}
    ', + 'cal_cell_start_today' => '', + 'cal_cell_content' => '{day}', + 'cal_cell_content_today' => '{day}', + 'cal_cell_no_content' => '{day}', + 'cal_cell_no_content_today' => '{day}', + 'cal_cell_blank' => ' ', + 'cal_cell_end' => '
    ' + ); + } + + // -------------------------------------------------------------------- + + /** + * Parse Template + * + * Harvests the data within the template {pseudo-variables} + * used to display the calendar + * + * @access public + * @return void + */ + function parse_template() + { + $this->temp = $this->default_template(); + + if ($this->template == '') + { + return; + } + + $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today'); + + foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val) + { + if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match)) + { + $this->temp[$val] = $match['1']; + } + else + { + if (in_array($val, $today, TRUE)) + { + $this->temp[$val] = $this->temp[str_replace('_today', '', $val)]; + } + } + } + } + +} + +// END CI_Calendar class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Config.php.svn-base b/system/libraries/.svn/text-base/Config.php.svn-base new file mode 100644 index 0000000..9b8b07c --- /dev/null +++ b/system/libraries/.svn/text-base/Config.php.svn-base @@ -0,0 +1,245 @@ +config =& get_config(); + log_message('debug', "Config Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Load Config File + * + * @access public + * @param string the config file name + * @return boolean if the file was loaded correctly + */ + function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + { + $file = ($file == '') ? 'config' : str_replace(EXT, '', $file); + + if (in_array($file, $this->is_loaded, TRUE)) + { + return TRUE; + } + + if ( ! file_exists(APPPATH.'config/'.$file.EXT)) + { + if ($fail_gracefully === TRUE) + { + return FALSE; + } + show_error('The configuration file '.$file.EXT.' does not exist.'); + } + + include(APPPATH.'config/'.$file.EXT); + + if ( ! isset($config) OR ! is_array($config)) + { + if ($fail_gracefully === TRUE) + { + return FALSE; + } + show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.'); + } + + if ($use_sections === TRUE) + { + if (isset($this->config[$file])) + { + $this->config[$file] = array_merge($this->config[$file], $config); + } + else + { + $this->config[$file] = $config; + } + } + else + { + $this->config = array_merge($this->config, $config); + } + + $this->is_loaded[] = $file; + unset($config); + + log_message('debug', 'Config file loaded: config/'.$file.EXT); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a config file item + * + * + * @access public + * @param string the config item name + * @param string the index name + * @param bool + * @return string + */ + function item($item, $index = '') + { + if ($index == '') + { + if ( ! isset($this->config[$item])) + { + return FALSE; + } + + $pref = $this->config[$item]; + } + else + { + if ( ! isset($this->config[$index])) + { + return FALSE; + } + + if ( ! isset($this->config[$index][$item])) + { + return FALSE; + } + + $pref = $this->config[$index][$item]; + } + + return $pref; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a config file item - adds slash after item + * + * The second parameter allows a slash to be added to the end of + * the item, in the case of a path. + * + * @access public + * @param string the config item name + * @param bool + * @return string + */ + function slash_item($item) + { + if ( ! isset($this->config[$item])) + { + return FALSE; + } + + $pref = $this->config[$item]; + + if ($pref != '') + { + if (ereg("/$", $pref) === FALSE) + { + $pref .= '/'; + } + } + + return $pref; + } + + // -------------------------------------------------------------------- + + /** + * Site URL + * + * @access public + * @param string the URI string + * @return string + */ + function site_url($uri = '') + { + if (is_array($uri)) + { + $uri = implode('/', $uri); + } + + if ($uri == '') + { + return $this->slash_item('base_url').$this->item('index_page'); + } + else + { + $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); + return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix; + } + } + + // -------------------------------------------------------------------- + + /** + * System URL + * + * @access public + * @return string + */ + function system_url() + { + $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH)); + return $this->slash_item('base_url').end($x).'/'; + } + + // -------------------------------------------------------------------- + + /** + * Set a config file item + * + * @access public + * @param string the config item key + * @param string the config item value + * @return void + */ + function set_item($item, $value) + { + $this->config[$item] = $value; + } + +} + +// END CI_Config class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Controller.php.svn-base b/system/libraries/.svn/text-base/Controller.php.svn-base new file mode 100644 index 0000000..ad9c668 --- /dev/null +++ b/system/libraries/.svn/text-base/Controller.php.svn-base @@ -0,0 +1,124 @@ +_ci_initialize(); + log_message('debug', "Controller Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize + * + * Assigns all the bases classes loaded by the front controller to + * variables in this class. Also calls the autoload routine. + * + * @access private + * @return void + */ + function _ci_initialize() + { + // Assign all the class objects that were instantiated by the + // front controller to local class variables so that CI can be + // run as one big super object. + $classes = array( + 'config' => 'Config', + 'input' => 'Input', + 'benchmark' => 'Benchmark', + 'uri' => 'URI', + 'output' => 'Output', + 'lang' => 'Language' + ); + + foreach ($classes as $var => $class) + { + $this->$var =& load_class($class); + } + + // In PHP 5 the Loader class is run as a discreet + // class. In PHP 4 it extends the Controller + if (floor(phpversion()) >= 5) + { + $this->load =& load_class('Loader'); + $this->load->_ci_autoloader(); + } + else + { + $this->_ci_autoloader(); + + // sync up the objects since PHP4 was working from a copy + foreach (array_keys(get_object_vars($this)) as $attribute) + { + if (is_object($this->$attribute)) + { + $this->load->$attribute =& $this->$attribute; + } + } + } + } + + // -------------------------------------------------------------------- + + /** + * Run Scaffolding + * + * @access private + * @return void + */ + function _ci_scaffolding() + { + if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE) + { + show_404('Scaffolding unavailable'); + } + + $method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3); + + require_once(BASEPATH.'scaffolding/Scaffolding'.EXT); + $scaff = new Scaffolding($this->_ci_scaff_table); + $scaff->$method(); + } + + +} +// END _Controller class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Email.php.svn-base b/system/libraries/.svn/text-base/Email.php.svn-base new file mode 100644 index 0000000..25e5963 --- /dev/null +++ b/system/libraries/.svn/text-base/Email.php.svn-base @@ -0,0 +1,1828 @@ + 0) + { + $this->initialize($config); + } + + log_message('debug', "Email Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + $this->clear(); + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $method = 'set_'.$key; + + if (method_exists($this, $method)) + { + $this->$method($val); + } + else + { + $this->$key = $val; + } + } + } + $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; + $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Email Data + * + * @access public + * @return void + */ + function clear($clear_attachments = FALSE) + { + $this->_subject = ""; + $this->_body = ""; + $this->_finalbody = ""; + $this->_header_str = ""; + $this->_replyto_flag = FALSE; + $this->_recipients = array(); + $this->_headers = array(); + $this->_debug_msg = array(); + + $this->_set_header('User-Agent', $this->useragent); + $this->_set_header('Date', $this->_set_date()); + + if ($clear_attachments !== FALSE) + { + $this->_attach_name = array(); + $this->_attach_type = array(); + $this->_attach_disp = array(); + } + } + + // -------------------------------------------------------------------- + + /** + * Set FROM + * + * @access public + * @param string + * @param string + * @return void + */ + function from($from, $name = '') + { + if (preg_match( '/\<(.*)\>/', $from, $match)) + $from = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($from)); + + if ($name != '' && substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('From', $name.' <'.$from.'>'); + $this->_set_header('Return-Path', '<'.$from.'>'); + } + + // -------------------------------------------------------------------- + + /** + * Set Reply-to + * + * @access public + * @param string + * @param string + * @return void + */ + function reply_to($replyto, $name = '') + { + if (preg_match( '/\<(.*)\>/', $replyto, $match)) + $replyto = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($replyto)); + + if ($name == '') + { + $name = $replyto; + } + + if (substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('Reply-To', $name.' <'.$replyto.'>'); + $this->_replyto_flag = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Recipients + * + * @access public + * @param string + * @return void + */ + function to($to) + { + $to = $this->_str_to_array($to); + $to = $this->clean_email($to); + + if ($this->validate) + $this->validate_email($to); + + if ($this->_get_protocol() != 'mail') + $this->_set_header('To', implode(", ", $to)); + + switch ($this->_get_protocol()) + { + case 'smtp' : $this->_recipients = $to; + break; + case 'sendmail' : $this->_recipients = implode(", ", $to); + break; + case 'mail' : $this->_recipients = implode(", ", $to); + break; + } + } + + // -------------------------------------------------------------------- + + /** + * Set CC + * + * @access public + * @param string + * @return void + */ + function cc($cc) + { + $cc = $this->_str_to_array($cc); + $cc = $this->clean_email($cc); + + if ($this->validate) + $this->validate_email($cc); + + $this->_set_header('Cc', implode(", ", $cc)); + + if ($this->_get_protocol() == "smtp") + $this->_cc_array = $cc; + } + + // -------------------------------------------------------------------- + + /** + * Set BCC + * + * @access public + * @param string + * @param string + * @return void + */ + function bcc($bcc, $limit = '') + { + if ($limit != '' && is_numeric($limit)) + { + $this->bcc_batch_mode = TRUE; + $this->bcc_batch_size = $limit; + } + + $bcc = $this->_str_to_array($bcc); + $bcc = $this->clean_email($bcc); + + if ($this->validate) + $this->validate_email($bcc); + + if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size)) + $this->_bcc_array = $bcc; + else + $this->_set_header('Bcc', implode(", ", $bcc)); + } + + // -------------------------------------------------------------------- + + /** + * Set Email Subject + * + * @access public + * @param string + * @return void + */ + function subject($subject) + { + $subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject); + $subject = preg_replace("/(\t)/", " ", $subject); + + $this->_set_header('Subject', trim($subject)); + } + + // -------------------------------------------------------------------- + + /** + * Set Body + * + * @access public + * @param string + * @return void + */ + function message($body) + { + $this->_body = stripslashes(rtrim(str_replace("\r", "", $body))); + } + + // -------------------------------------------------------------------- + + /** + * Assign file attachments + * + * @access public + * @param string + * @return string + */ + function attach($filename, $disposition = 'attachment') + { + $this->_attach_name[] = $filename; + $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); + $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters + } + + // -------------------------------------------------------------------- + + /** + * Add a Header Item + * + * @access public + * @param string + * @param string + * @return void + */ + function _set_header($header, $value) + { + $this->_headers[$header] = $value; + } + + // -------------------------------------------------------------------- + + /** + * Convert a String to an Array + * + * @access public + * @param string + * @return array + */ + function _str_to_array($email) + { + if ( ! is_array($email)) + { + if (ereg(',$', $email)) + $email = substr($email, 0, -1); + + if (ereg('^,', $email)) + $email = substr($email, 1); + + if (ereg(',', $email)) + { + $x = explode(',', $email); + $email = array(); + + for ($i = 0; $i < count($x); $i ++) + $email[] = trim($x[$i]); + } + else + { + $email = trim($email); + settype($email, "array"); + } + } + return $email; + } + + // -------------------------------------------------------------------- + + /** + * Set Multipart Value + * + * @access public + * @param string + * @return void + */ + function set_alt_message($str = '') + { + $this->alt_message = ($str == '') ? '' : $str; + } + + // -------------------------------------------------------------------- + + /** + * Set Mailtype + * + * @access public + * @param string + * @return void + */ + function set_mailtype($type = 'text') + { + $this->mailtype = ($type == 'html') ? 'html' : 'text'; + } + + // -------------------------------------------------------------------- + + /** + * Set Wordwrap + * + * @access public + * @param string + * @return void + */ + function set_wordwrap($wordwrap = TRUE) + { + $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Protocol + * + * @access public + * @param string + * @return void + */ + function set_protocol($protocol = 'mail') + { + $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol); + } + + // -------------------------------------------------------------------- + + /** + * Set Priority + * + * @access public + * @param integer + * @return void + */ + function set_priority($n = 3) + { + if ( ! is_numeric($n)) + { + $this->priority = 3; + return; + } + + if ($n < 1 OR $n > 5) + { + $this->priority = 3; + return; + } + + $this->priority = $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Newline Character + * + * @access public + * @param string + * @return void + */ + function set_newline($newline = "\n") + { + if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r") + { + $this->newline = "\n"; + return; + } + + $this->newline = $newline; + } + + // -------------------------------------------------------------------- + + /** + * Set Message Boundary + * + * @access private + * @return void + */ + function _set_boundaries() + { + $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative + $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary + } + + // -------------------------------------------------------------------- + + /** + * Get the Message ID + * + * @access private + * @return string + */ + function _get_message_id() + { + $from = $this->_headers['Return-Path']; + $from = str_replace(">", "", $from); + $from = str_replace("<", "", $from); + + return "<".uniqid('').strstr($from, '@').">"; + } + + // -------------------------------------------------------------------- + + /** + * Get Mail Protocol + * + * @access private + * @param bool + * @return string + */ + function _get_protocol($return = TRUE) + { + $this->protocol = strtolower($this->protocol); + $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol; + + if ($return == TRUE) + return $this->protocol; + } + + // -------------------------------------------------------------------- + + /** + * Get Mail Encoding + * + * @access private + * @param bool + * @return string + */ + function _get_encoding($return = TRUE) + { + $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding; + + foreach ($this->_base_charsets as $charset) + { + if (strncmp($charset, $this->charset, strlen($charset)) == 0) + { + $this->_encoding = '7bit'; + } + } + + if ($return == TRUE) + { + return $this->_encoding; + } + } + + // -------------------------------------------------------------------- + + /** + * Get content type (text/html/attachment) + * + * @access private + * @return string + */ + function _get_content_type() + { + if ($this->mailtype == 'html' && count($this->_attach_name) == 0) + return 'html'; + + elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0) + return 'html-attach'; + + elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0) + return 'plain-attach'; + + else return 'plain'; + } + + // -------------------------------------------------------------------- + + /** + * Set RFC 822 Date + * + * @access public + * @return string + */ + function _set_date() + { + $timezone = date("Z"); + $operator = (substr($timezone, 0, 1) == '-') ? '-' : '+'; + $timezone = abs($timezone); + $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60; + + return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone); + } + + // -------------------------------------------------------------------- + + /** + * Mime message + * + * @access private + * @return string + */ + function _get_mime_message() + { + return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format."; + } + + // -------------------------------------------------------------------- + + /** + * Validate Email Address + * + * @access public + * @param string + * @return bool + */ + function validate_email($email) + { + if ( ! is_array($email)) + { + $this->_set_error_message('email_must_be_array'); + return FALSE; + } + + foreach ($email as $val) + { + if ( ! $this->valid_email($val)) + { + $this->_set_error_message('email_invalid_address', $val); + return FALSE; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Email Validation + * + * @access public + * @param string + * @return bool + */ + function valid_email($address) + { + if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) + return FALSE; + else + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Clean Extended Email Address: Joe Smith + * + * @access public + * @param string + * @return string + */ + function clean_email($email) + { + if ( ! is_array($email)) + { + if (preg_match('/\<(.*)\>/', $email, $match)) + return $match['1']; + else + return $email; + } + + $clean_email = array(); + + foreach ($email as $addy) + { + if (preg_match( '/\<(.*)\>/', $addy, $match)) + { + $clean_email[] = $match['1']; + } + else + { + $clean_email[] = $addy; + } + } + + return $clean_email; + } + + // -------------------------------------------------------------------- + + /** + * Build alternative plain text message + * + * This function provides the raw message for use + * in plain-text headers of HTML-formatted emails. + * If the user hasn't specified his own alternative message + * it creates one by stripping the HTML + * + * @access private + * @return string + */ + function _get_alt_message() + { + if ($this->alt_message != "") + { + return $this->word_wrap($this->alt_message, '76'); + } + + if (eregi( '\', $this->_body, $match)) + { + $body = $match['1']; + $body = substr($body, strpos($body, ">") + 1); + } + else + { + $body = $this->_body; + } + + $body = trim(strip_tags($body)); + $body = preg_replace( '# '.$message. ' '.$filepath.' '.$line, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * 404 Page Not Found Handler + * + * @access private + * @param string + * @return string + */ + function show_404($page = '') + { + $heading = "404 Page Not Found"; + $message = "The page you requested was not found."; + + log_message('error', '404 Page Not Found --> '.$page); + echo $this->show_error($heading, $message, 'error_404'); + exit; + } + + // -------------------------------------------------------------------- + + /** + * General Error Page + * + * This function takes an error message as input + * (either as a string or an array) and displays + * it using the specified template. + * + * @access private + * @param string the heading + * @param string the message + * @param string the template name + * @return string + */ + function show_error($heading, $message, $template = 'error_general') + { + $message = '

    '.implode('

    ', ( ! is_array($message)) ? array($message) : $message).'

    '; + + if (ob_get_level() > $this->ob_level + 1) + { + ob_end_flush(); + } + ob_start(); + include(APPPATH.'errors/'.$template.EXT); + $buffer = ob_get_contents(); + ob_end_clean(); + return $buffer; + } + + // -------------------------------------------------------------------- + + /** + * Native PHP error handler + * + * @access private + * @param string the error severity + * @param string the error string + * @param string the error filepath + * @param string the error line number + * @return string + */ + function show_php_error($severity, $message, $filepath, $line) + { + $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity]; + + $filepath = str_replace("\\", "/", $filepath); + + // For safety reasons we do not show the full file path + if (FALSE !== strpos($filepath, '/')) + { + $x = explode('/', $filepath); + $filepath = $x[count($x)-2].'/'.end($x); + } + + if (ob_get_level() > $this->ob_level + 1) + { + ob_end_flush(); + } + ob_start(); + include(APPPATH.'errors/error_php'.EXT); + $buffer = ob_get_contents(); + ob_end_clean(); + echo $buffer; + } + + +} +// END Exceptions Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Ftp.php.svn-base b/system/libraries/.svn/text-base/Ftp.php.svn-base new file mode 100644 index 0000000..ed934b5 --- /dev/null +++ b/system/libraries/.svn/text-base/Ftp.php.svn-base @@ -0,0 +1,616 @@ + 0) + { + $this->initialize($config); + } + + log_message('debug', "FTP Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + + // Prep the hostname + $this->hostname = preg_replace('|.+?://|', '', $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * FTP Connect + * + * @access public + * @param array the connection values + * @return bool + */ + function connect($config = array()) + { + if (count($config) > 0) + { + $this->initialize($config); + } + + if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port))) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_connect'); + } + return FALSE; + } + + if ( ! $this->_login()) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_login'); + } + return FALSE; + } + + // Set passive mode if needed + if ($this->passive == TRUE) + { + ftp_pasv($this->conn_id, TRUE); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * FTP Login + * + * @access private + * @return bool + */ + function _login() + { + return @ftp_login($this->conn_id, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Validates the connection ID + * + * @access private + * @return bool + */ + function _is_conn() + { + if ( ! is_resource($this->conn_id)) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_no_connection'); + } + return FALSE; + } + return TRUE; + } + + // -------------------------------------------------------------------- + + + /** + * Change direcotry + * + * The second parameter lets us momentarily turn off debugging so that + * this function can be used to test for the existance of a folder + * without throwing an error. There's no FTP equivalent to is_dir() + * so we do it by trying to change to a particular directory. + * Internally, this paramter is only used by the "mirror" function below. + * + * @access public + * @param string + * @param bool + * @return bool + */ + function changedir($path = '', $supress_debug = FALSE) + { + if ($path == '' OR ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_chdir($this->conn_id, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE AND $supress_debug == FALSE) + { + $this->_error('ftp_unable_to_changedir'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Create a directory + * + * @access public + * @param string + * @return bool + */ + function mkdir($path = '', $permissions = NULL) + { + if ($path == '' OR ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_mkdir($this->conn_id, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_makdir'); + } + return FALSE; + } + + // Set file permissions if needed + if ( ! is_null($permissions)) + { + $this->chmod($path, (int)$permissions); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Upload a file to the server + * + * @access public + * @param string + * @param string + * @param string + * @return bool + */ + function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + if ( ! file_exists($locpath)) + { + $this->_error('ftp_no_source_file'); + return FALSE; + } + + // Set the mode if not specified + if ($mode == 'auto') + { + // Get the file extension so we can set the upload type + $ext = $this->_getext($locpath); + $mode = $this->_settype($ext); + } + + $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; + + $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_upload'); + } + return FALSE; + } + + // Set file permissions if needed + if ( ! is_null($permissions)) + { + $this->chmod($rempath, (int)$permissions); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rename (or move) a file + * + * @access public + * @param string + * @param string + * @param bool + * @return bool + */ + function rename($old_file, $new_file, $move = FALSE) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_rename($this->conn_id, $old_file, $new_file); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move'; + + $this->_error($msg); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Move a file + * + * @access public + * @param string + * @param string + * @return bool + */ + function move($old_file, $new_file) + { + return $this->rename($old_file, $new_file, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Rename (or move) a file + * + * @access public + * @param string + * @return bool + */ + function delete_file($filepath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_delete($this->conn_id, $filepath); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_delete'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Delete a folder and recursively delete everything (including sub-folders) + * containted within it. + * + * @access public + * @param string + * @return bool + */ + function delete_dir($filepath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Add a trailing slash to the file path if needed + $filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath); + + $list = $this->list_files($filepath); + + if ($list !== FALSE AND count($list) > 0) + { + foreach ($list as $item) + { + // If we can't delete the item it's probaly a folder so + // we'll recursively call delete_dir() + if ( ! @ftp_delete($this->conn_id, $filepath.$item)) + { + $this->delete_dir($filepath.$item); + } + } + } + + $result = @ftp_rmdir($this->conn_id, $filepath); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_delete'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set file permissions + * + * @access public + * @param string the file path + * @param string the permissions + * @return bool + */ + function chmod($path, $perm) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Permissions can only be set when running PHP 5 + if ( ! function_exists('ftp_chmod')) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_chmod'); + } + return FALSE; + } + + $result = @ftp_chmod($this->conn_id, $perm, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_chmod'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * FTP List files in the specified directory + * + * @access public + * @return array + */ + function list_files($path = '.') + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + return ftp_nlist($this->conn_id, $path); + } + + // ------------------------------------------------------------------------ + + /** + * Read a directory and recreate it remotely + * + * This function recursively reads a folder and everything it contains (including + * sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure + * of the original file path will be recreated on the server. + * + * @access public + * @param string path to source with trailing slash + * @param string path to destination - include the base folder with trailing slash + * @return bool + */ + function mirror($locpath, $rempath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Open the local file path + if ($fp = @opendir($locpath)) + { + // Attempt to open the remote file path. + if ( ! $this->changedir($rempath, TRUE)) + { + // If it doesn't exist we'll attempt to create the direcotory + if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath)) + { + return FALSE; + } + } + + // Recursively read the local directory + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.') + { + $this->mirror($locpath.$file."/", $rempath.$file."/"); + } + elseif (substr($file, 0, 1) != ".") + { + // Get the file extension so we can se the upload type + $ext = $this->_getext($file); + $mode = $this->_settype($ext); + + $this->upload($locpath.$file, $rempath.$file, $mode); + } + } + return TRUE; + } + + return FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Extract the file extension + * + * @access private + * @param string + * @return string + */ + function _getext($filename) + { + if (FALSE === strpos($filename, '.')) + { + return 'txt'; + } + + $x = explode('.', $filename); + return end($x); + } + + + // -------------------------------------------------------------------- + + /** + * Set the upload type + * + * @access private + * @param string + * @return string + */ + function _settype($ext) + { + $text_types = array( + 'txt', + 'text', + 'php', + 'phps', + 'php4', + 'js', + 'css', + 'htm', + 'html', + 'phtml', + 'shtml', + 'log', + 'xml' + ); + + + return (in_array($ext, $text_types)) ? 'ascii' : 'binary'; + } + + // ------------------------------------------------------------------------ + + /** + * Close the connection + * + * @access public + * @param string path to source + * @param string path to destination + * @return bool + */ + function close() + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + @ftp_close($this->conn_id); + } + + // ------------------------------------------------------------------------ + + /** + * Display error message + * + * @access private + * @param string + * @return bool + */ + function _error($line) + { + $CI =& get_instance(); + $CI->lang->load('ftp'); + show_error($CI->lang->line($line)); + } + + +} +// END FTP Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Hooks.php.svn-base b/system/libraries/.svn/text-base/Hooks.php.svn-base new file mode 100644 index 0000000..49cb230 --- /dev/null +++ b/system/libraries/.svn/text-base/Hooks.php.svn-base @@ -0,0 +1,224 @@ +_initialize(); + log_message('debug', "Hooks Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Hooks Preferences + * + * @access private + * @return void + */ + function _initialize() + { + $CFG =& load_class('Config'); + + // If hooks are not enabled in the config file + // there is nothing else to do + + if ($CFG->item('enable_hooks') == FALSE) + { + return; + } + + // Grab the "hooks" definition file. + // If there are no hooks, we're done. + + @include(APPPATH.'config/hooks'.EXT); + + if ( ! isset($hook) OR ! is_array($hook)) + { + return; + } + + $this->hooks =& $hook; + $this->enabled = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Call Hook + * + * Calls a particular hook + * + * @access private + * @param string the hook name + * @return mixed + */ + function _call_hook($which = '') + { + if ( ! $this->enabled OR ! isset($this->hooks[$which])) + { + return FALSE; + } + + if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) + { + foreach ($this->hooks[$which] as $val) + { + $this->_run_hook($val); + } + } + else + { + $this->_run_hook($this->hooks[$which]); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Run Hook + * + * Runs a particular hook + * + * @access private + * @param array the hook details + * @return bool + */ + function _run_hook($data) + { + if ( ! is_array($data)) + { + return FALSE; + } + + // ----------------------------------- + // Safety - Prevents run-away loops + // ----------------------------------- + + // If the script being called happens to have the same + // hook call within it a loop can happen + + if ($this->in_progress == TRUE) + { + return; + } + + // ----------------------------------- + // Set file path + // ----------------------------------- + + if ( ! isset($data['filepath']) OR ! isset($data['filename'])) + { + return FALSE; + } + + $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; + + if ( ! file_exists($filepath)) + { + return FALSE; + } + + // ----------------------------------- + // Set class/function name + // ----------------------------------- + + $class = FALSE; + $function = FALSE; + $params = ''; + + if (isset($data['class']) AND $data['class'] != '') + { + $class = $data['class']; + } + + if (isset($data['function'])) + { + $function = $data['function']; + } + + if (isset($data['params'])) + { + $params = $data['params']; + } + + if ($class === FALSE AND $function === FALSE) + { + return FALSE; + } + + // ----------------------------------- + // Set the in_progress flag + // ----------------------------------- + + $this->in_progress = TRUE; + + // ----------------------------------- + // Call the requested class and/or function + // ----------------------------------- + + if ($class !== FALSE) + { + if ( ! class_exists($class)) + { + require($filepath); + } + + $HOOK = new $class; + $HOOK->$function($params); + } + else + { + if ( ! function_exists($function)) + { + require($filepath); + } + + $function($params); + } + + $this->in_progress = FALSE; + return TRUE; + } + +} + +// END CI_Hooks class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Image_lib.php.svn-base b/system/libraries/.svn/text-base/Image_lib.php.svn-base new file mode 100644 index 0000000..dbb6f82 --- /dev/null +++ b/system/libraries/.svn/text-base/Image_lib.php.svn-base @@ -0,0 +1,1530 @@ + 0) + { + $this->initialize($props); + } + + log_message('debug', "Image Lib Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize image properties + * + * Resets values in case this class is used in a loop + * + * @access public + * @return void + */ + function clear() + { + $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); + + foreach ($props as $val) + { + $this->$val = ''; + } + + // special consideration for master_dim + $this->master_dim = 'auto'; + } + + // -------------------------------------------------------------------- + + /** + * initialize image preferences + * + * @access public + * @param array + * @return void + */ + function initialize($props = array()) + { + /* + * Convert array elements into class variables + */ + if (count($props) > 0) + { + foreach ($props as $key => $val) + { + $this->$key = $val; + } + } + + /* + * Is there a source image? + * + * If not, there's no reason to continue + * + */ + if ($this->source_image == '') + { + $this->set_error('imglib_source_image_required'); + return FALSE; + } + + /* + * Is getimagesize() Available? + * + * We use it to determine the image properties (width/height). + * Note: We need to figure out how to determine image + * properties using ImageMagick and NetPBM + * + */ + if ( ! function_exists('getimagesize')) + { + $this->set_error('imglib_gd_required_for_props'); + return FALSE; + } + + $this->image_library = strtolower($this->image_library); + + /* + * Set the full server path + * + * The source image may or may not contain a path. + * Either way, we'll try use realpath to generate the + * full server path in order to more reliably read it. + * + */ + if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE) + { + $full_source_path = str_replace("\\", "/", realpath($this->source_image)); + } + else + { + $full_source_path = $this->source_image; + } + + $x = explode('/', $full_source_path); + $this->source_image = end($x); + $this->source_folder = str_replace($this->source_image, '', $full_source_path); + + // Set the Image Properties + if ( ! $this->get_image_properties($this->source_folder.$this->source_image)) + { + return FALSE; + } + + /* + * Assign the "new" image name/path + * + * If the user has set a "new_image" name it means + * we are making a copy of the source image. If not + * it means we are altering the original. We'll + * set the destination filename and path accordingly. + * + */ + if ($this->new_image == '') + { + $this->dest_image = $this->source_image; + $this->dest_folder = $this->source_folder; + } + else + { + if (strpos($this->new_image, '/') === FALSE) + { + $this->dest_folder = $this->source_folder; + $this->dest_image = $this->new_image; + } + else + { + if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE) + { + $full_dest_path = str_replace("\\", "/", realpath($this->new_image)); + } + else + { + $full_dest_path = $this->new_image; + } + + // Is there a file name? + if ( ! preg_match("#[\.jpg|\.jpeg|\.gif|\.png]$#i", $full_dest_path)) + { + $this->dest_folder = $full_dest_path.'/'; + $this->dest_image = $this->source_image; + } + else + { + $x = explode('/', $full_dest_path); + $this->dest_image = end($x); + $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path); + } + } + } + + /* + * Compile the finalized filenames/paths + * + * We'll create two master strings containing the + * full server path to the source image and the + * full server path to the destination image. + * We'll also split the destination image name + * so we can insert the thumbnail marker if needed. + * + */ + if ($this->create_thumb === FALSE OR $this->thumb_marker == '') + { + $this->thumb_marker = ''; + } + + $xp = $this->explode_name($this->dest_image); + + $filename = $xp['name']; + $file_ext = $xp['ext']; + + $this->full_src_path = $this->source_folder.$this->source_image; + $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext; + + /* + * Should we maintain image proportions? + * + * When creating thumbs or copies, the target width/height + * might not be in correct proportion with the source + * image's width/height. We'll recalculate it here. + * + */ + if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != '')) + { + $this->image_reproportion(); + } + + /* + * Was a width and height specified? + * + * If the destination width/height was + * not submitted we will use the values + * from the actual file + * + */ + if ($this->width == '') + $this->width = $this->orig_width; + + if ($this->height == '') + $this->height = $this->orig_height; + + // Set the quality + $this->quality = trim(str_replace("%", "", $this->quality)); + + if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality)) + $this->quality = 90; + + // Set the x/y coordinates + $this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis; + $this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis; + + // Watermark-related Stuff... + if ($this->wm_font_color != '') + { + if (strlen($this->wm_font_color) == 6) + { + $this->wm_font_color = '#'.$this->wm_font_color; + } + } + + if ($this->wm_shadow_color != '') + { + if (strlen($this->wm_shadow_color) == 6) + { + $this->wm_shadow_color = '#'.$this->wm_shadow_color; + } + } + + if ($this->wm_overlay_path != '') + { + $this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path)); + } + + if ($this->wm_shadow_color != '') + { + $this->wm_use_drop_shadow = TRUE; + } + + if ($this->wm_font_path != '') + { + $this->wm_use_truetype = TRUE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Resize + * + * This is a wrapper function that chooses the proper + * resize function based on the protocol specified + * + * @access public + * @return bool + */ + function resize() + { + $protocol = 'image_process_'.$this->image_library; + + if (eregi("gd2$", $protocol)) + { + $protocol = 'image_process_gd'; + } + + return $this->$protocol('resize'); + } + + // -------------------------------------------------------------------- + + /** + * Image Crop + * + * This is a wrapper function that chooses the proper + * cropping function based on the protocol specified + * + * @access public + * @return bool + */ + function crop() + { + $protocol = 'image_process_'.$this->image_library; + + if (eregi("gd2$", $protocol)) + { + $protocol = 'image_process_gd'; + } + + return $this->$protocol('crop'); + } + + // -------------------------------------------------------------------- + + /** + * Image Rotate + * + * This is a wrapper function that chooses the proper + * rotation function based on the protocol specified + * + * @access public + * @return bool + */ + function rotate() + { + // Allowed rotation values + $degs = array(90, 180, 270, 'vrt', 'hor'); + + if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE)) + { + $this->set_error('imglib_rotation_angle_required'); + return FALSE; + } + + // Reassign the width and height + if ($this->rotation_angle == 90 OR $this->rotation_angle == 270) + { + $this->width = $this->orig_height; + $this->height = $this->orig_width; + } + else + { + $this->width = $this->orig_width; + $this->height = $this->orig_height; + } + + + // Choose resizing function + if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm') + { + $protocol = 'image_process_'.$this->image_library; + + return $this->$protocol('rotate'); + } + + if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt') + { + return $this->image_mirror_gd(); + } + else + { + return $this->image_rotate_gd(); + } + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using GD/GD2 + * + * This function will resize or crop + * + * @access public + * @param string + * @return bool + */ + function image_process_gd($action = 'resize') + { + $v2_override = FALSE; + + if ($action == 'crop') + { + // If the target width/height match the source then it's pointless to crop, right? + // So if dynamic output isn't on, then we'll return true so the user thinks + // the process succeeded. It'll be our little secret... + + if ($this->width >= $this->orig_width AND $this->height >= $this->orig_height AND $this->dynamic_output !== TRUE) + { + return TRUE; + } + + // Reassign the source width/height if cropping + $this->orig_width = $this->width; + $this->orig_height = $this->height; + + // GD 2.0 has a cropping bug so we'll test for it + if ($this->gd_version() !== FALSE) + { + $gd_version = str_replace('0', '', $this->gd_version()); + $v2_override = ($gd_version == 2) ? TRUE : FALSE; + } + } + else + { + // If the target width/height match the source, AND if + // the new file name is not equal to the old file name + // we'll simply make a copy of the original with the new name + if (($this->orig_width == $this->width AND $this->orig_height == $this->height) AND ($this->source_image != $this->new_image)) + { + if ( ! @copy($this->full_src_path, $this->full_dst_path)) + { + $this->set_error('imglib_copy_failed'); + return FALSE; + } + + @chmod($this->full_dst_path, 0777); + return TRUE; + } + + // If resizing the x/y axis must be zero + $this->x_axis = 0; + $this->y_axis = 0; + } + + // Create the image handle + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + // Create The Image + if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) + { + $create = 'imagecreatetruecolor'; + $copy = 'imagecopyresampled'; + } + else + { + $create = 'imagecreate'; + $copy = 'imagecopyresized'; + } + + $dst_img = $create($this->width, $this->height); + $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height); + + // Show the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($dst_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($dst_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($dst_img); + imagedestroy($src_img); + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using ImageMagick + * + * This function will resize, crop or rotate + * + * @access public + * @param string + * @return bool + */ + function image_process_imagemagick($action = 'resize') + { + // Do we have a vaild library path? + if ($this->library_path == '') + { + $this->set_error('imglib_libpath_invalid'); + return FALSE; + } + + if ( ! eregi("convert$", $this->library_path)) + { + if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/"; + + $this->library_path .= 'convert'; + } + + // Execute the command + $cmd = $this->library_path." -quality ".$this->quality; + + if ($action == 'crop') + { + $cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + elseif ($action == 'rotate') + { + switch ($this->rotation_angle) + { + case 'hor' : $angle = '-flop'; + break; + case 'vrt' : $angle = '-flip'; + break; + default : $angle = '-rotate '.$this->rotation_angle; + break; + } + + $cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + else // Resize + { + $cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + + $retval = 1; + + @exec($cmd, $output, $retval); + + // Did it work? + if ($retval > 0) + { + $this->set_error('imglib_image_process_failed'); + return FALSE; + } + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using NetPBM + * + * This function will resize, crop or rotate + * + * @access public + * @param string + * @return bool + */ + function image_process_netpbm($action = 'resize') + { + if ($this->library_path == '') + { + $this->set_error('imglib_libpath_invalid'); + return FALSE; + } + + // Build the resizing command + switch ($this->image_type) + { + case 1 : + $cmd_in = 'giftopnm'; + $cmd_out = 'ppmtogif'; + break; + case 2 : + $cmd_in = 'jpegtopnm'; + $cmd_out = 'ppmtojpeg'; + break; + case 3 : + $cmd_in = 'pngtopnm'; + $cmd_out = 'ppmtopng'; + break; + } + + if ($action == 'crop') + { + $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height; + } + elseif ($action == 'rotate') + { + switch ($this->rotation_angle) + { + case 90 : $angle = 'r270'; + break; + case 180 : $angle = 'r180'; + break; + case 270 : $angle = 'r90'; + break; + case 'vrt' : $angle = 'tb'; + break; + case 'hor' : $angle = 'lr'; + break; + } + + $cmd_inner = 'pnmflip -'.$angle.' '; + } + else // Resize + { + $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height; + } + + $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; + + $retval = 1; + + @exec($cmd, $output, $retval); + + // Did it work? + if ($retval > 0) + { + $this->set_error('imglib_image_process_failed'); + return FALSE; + } + + // With NetPBM we have to create a temporary image. + // If you try manipulating the original it fails so + // we have to rename the temp file. + copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path); + unlink ($this->dest_folder.'netpbm.tmp'); + @chmod($dst_image, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Rotate Using GD + * + * @access public + * @return bool + */ + function image_rotate_gd() + { + // Is Image Rotation Supported? + // this function is only supported as of PHP 4.3 + if ( ! function_exists('imagerotate')) + { + $this->set_error('imglib_rotate_unsupported'); + return FALSE; + } + + // Create the image handle + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + // Set the background color + // This won't work with transparent PNG files so we are + // going to have to figure out how to determine the color + // of the alpha channel in a future release. + + $white = imagecolorallocate($src_img, 255, 255, 255); + + // Rotate it! + $dst_img = imagerotate($src_img, $this->rotation_angle, $white); + + // Save the Image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($dst_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($dst_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($dst_img); + imagedestroy($src_img); + + // Set the file to 777 + + @chmod($this->full_dst_path, 0777); + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Create Mirror Image using GD + * + * This function will flip horizontal or vertical + * + * @access public + * @return bool + */ + function image_mirror_gd() + { + if ( ! $src_img = $this->image_create_gd()) + { + return FALSE; + } + + $width = $this->orig_width; + $height = $this->orig_height; + + if ($this->rotation_angle == 'hor') + { + for ($i = 0; $i < $height; $i++) + { + $left = 0; + $right = $width-1; + + while ($left < $right) + { + $cl = imagecolorat($src_img, $left, $i); + $cr = imagecolorat($src_img, $right, $i); + + imagesetpixel($src_img, $left, $i, $cr); + imagesetpixel($src_img, $right, $i, $cl); + + $left++; + $right--; + } + } + } + else + { + for ($i = 0; $i < $width; $i++) + { + $top = 0; + $bot = $height-1; + + while ($top < $bot) + { + $ct = imagecolorat($src_img, $i, $top); + $cb = imagecolorat($src_img, $i, $bot); + + imagesetpixel($src_img, $i, $top, $cb); + imagesetpixel($src_img, $i, $bot, $ct); + + $top++; + $bot--; + } + } + } + + // Show the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($src_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($src_img); + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Watermark + * + * This is a wrapper function that chooses the type + * of watermarking based on the specified preference. + * + * @access public + * @param string + * @return bool + */ + function watermark() + { + if ($this->wm_type == 'overlay') + { + return $this->overlay_watermark(); + } + else + { + return $this->text_watermark(); + } + } + + // -------------------------------------------------------------------- + + /** + * Watermark - Graphic Version + * + * @access public + * @return bool + */ + function overlay_watermark() + { + if ( ! function_exists('imagecolortransparent')) + { + $this->set_error('imglib_gd_required'); + return FALSE; + } + + // Fetch source image properties + $this->get_image_properties(); + + // Fetch watermark image properties + $props = $this->get_image_properties($this->wm_overlay_path, TRUE); + $wm_img_type = $props['image_type']; + $wm_width = $props['width']; + $wm_height = $props['height']; + + // Create two image resources + $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type); + $src_img = $this->image_create_gd($this->full_src_path); + + // Reverse the offset if necessary + // When the image is positioned at the bottom + // we don't want the vertical offset to push it + // further down. We want the reverse, so we'll + // invert the offset. Same with the horizontal + // offset when the image is at the right + + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); + $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); + + if ($this->wm_vrt_alignment == 'B') + $this->wm_vrt_offset = $this->wm_vrt_offset * -1; + + if ($this->wm_hor_alignment == 'R') + $this->wm_hor_offset = $this->wm_hor_offset * -1; + + // Set the base x and y axis values + $x_axis = $this->wm_hor_offset + $this->wm_padding; + $y_axis = $this->wm_vrt_offset + $this->wm_padding; + + // Set the vertical position + switch ($this->wm_vrt_alignment) + { + case 'T': + break; + case 'M': $y_axis += ($this->orig_height / 2) - ($wm_height / 2); + break; + case 'B': $y_axis += $this->orig_height - $wm_height; + break; + } + + // Set the horizontal position + switch ($this->wm_hor_alignment) + { + case 'L': + break; + case 'C': $x_axis += ($this->orig_width / 2) - ($wm_width / 2); + break; + case 'R': $x_axis += $this->orig_width - $wm_width; + break; + } + + // Build the finalized image + if ($wm_img_type == 3 AND function_exists('imagealphablending')) + { + @imagealphablending($src_img, TRUE); + } + + // Set RGB values for text and shadow + imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp)); + imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity); + + // Output the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + if ( ! $this->image_save_gd($src_img)) + { + return FALSE; + } + } + + imagedestroy($src_img); + imagedestroy($wm_img); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Watermark - Text Version + * + * @access public + * @return bool + */ + function text_watermark() + { + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path)) + { + $this->set_error('imglib_missing_font'); + return FALSE; + } + + // Fetch source image properties + $this->get_image_properties(); + + // Set RGB values for text and shadow + $this->wm_font_color = str_replace('#', '', $this->wm_font_color); + $this->wm_shadow_color = str_replace('#', '', $this->wm_shadow_color); + + $R1 = hexdec(substr($this->wm_font_color, 0, 2)); + $G1 = hexdec(substr($this->wm_font_color, 2, 2)); + $B1 = hexdec(substr($this->wm_font_color, 4, 2)); + + $R2 = hexdec(substr($this->wm_shadow_color, 0, 2)); + $G2 = hexdec(substr($this->wm_shadow_color, 2, 2)); + $B2 = hexdec(substr($this->wm_shadow_color, 4, 2)); + + $txt_color = imagecolorclosest($src_img, $R1, $G1, $B1); + $drp_color = imagecolorclosest($src_img, $R2, $G2, $B2); + + // Reverse the vertical offset + // When the image is positioned at the bottom + // we don't want the vertical offset to push it + // further down. We want the reverse, so we'll + // invert the offset. Note: The horizontal + // offset flips itself automatically + + if ($this->wm_vrt_alignment == 'B') + $this->wm_vrt_offset = $this->wm_vrt_offset * -1; + + if ($this->wm_hor_alignment == 'R') + $this->wm_hor_offset = $this->wm_hor_offset * -1; + + // Set font width and height + // These are calculated differently depending on + // whether we are using the true type font or not + if ($this->wm_use_truetype == TRUE) + { + if ($this->wm_font_size == '') + $this->wm_font_size = '17'; + + $fontwidth = $this->wm_font_size-($this->wm_font_size/4); + $fontheight = $this->wm_font_size; + $this->wm_vrt_offset += $this->wm_font_size; + } + else + { + $fontwidth = imagefontwidth($this->wm_font_size); + $fontheight = imagefontheight($this->wm_font_size); + } + + // Set base X and Y axis values + $x_axis = $this->wm_hor_offset + $this->wm_padding; + $y_axis = $this->wm_vrt_offset + $this->wm_padding; + + // Set verticle alignment + if ($this->wm_use_drop_shadow == FALSE) + $this->wm_shadow_distance = 0; + + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); + $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); + + switch ($this->wm_vrt_alignment) + { + case "T" : + break; + case "M": $y_axis += ($this->orig_height/2)+($fontheight/2); + break; + case "B": $y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2)); + break; + } + + $x_shad = $x_axis + $this->wm_shadow_distance; + $y_shad = $y_axis + $this->wm_shadow_distance; + + // Set horizontal alignment + switch ($this->wm_hor_alignment) + { + case "L": + break; + case "R": + if ($this->wm_use_drop_shadow) + $x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text)); + $x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text)); + break; + case "C": + if ($this->wm_use_drop_shadow) + $x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2); + $x_axis += floor(($this->orig_width -$fontwidth*strlen($this->wm_text))/2); + break; + } + + // Add the text to the source image + if ($this->wm_use_truetype) + { + if ($this->wm_use_drop_shadow) + imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text); + imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text); + } + else + { + if ($this->wm_use_drop_shadow) + imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color); + imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color); + } + + // Output the final image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + $this->image_save_gd($src_img); + } + + imagedestroy($src_img); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Create Image - GD + * + * This simply creates an image resource handle + * based on the type of image being processed + * + * @access public + * @param string + * @return resource + */ + function image_create_gd($path = '', $image_type = '') + { + if ($path == '') + $path = $this->full_src_path; + + if ($image_type == '') + $image_type = $this->image_type; + + + switch ($image_type) + { + case 1 : + if ( ! function_exists('imagecreatefromgif')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); + return FALSE; + } + + return imagecreatefromgif($path); + break; + case 2 : + if ( ! function_exists('imagecreatefromjpeg')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); + return FALSE; + } + + return imagecreatefromjpeg($path); + break; + case 3 : + if ( ! function_exists('imagecreatefrompng')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + return FALSE; + } + + return imagecreatefrompng($path); + break; + + } + + $this->set_error(array('imglib_unsupported_imagecreate')); + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Write image file to disk - GD + * + * Takes an image resource as input and writes the file + * to the specified destination + * + * @access public + * @param resource + * @return bool + */ + function image_save_gd($resource) + { + switch ($this->image_type) + { + case 1 : + if ( ! function_exists('imagegif')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); + return FALSE; + } + + @imagegif($resource, $this->full_dst_path); + break; + case 2 : + if ( ! function_exists('imagejpeg')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); + return FALSE; + } + + if (phpversion() == '4.4.1') + { + @touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround + } + + @imagejpeg($resource, $this->full_dst_path, $this->quality); + break; + case 3 : + if ( ! function_exists('imagepng')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + return FALSE; + } + + @imagepng($resource, $this->full_dst_path); + break; + default : + $this->set_error(array('imglib_unsupported_imagecreate')); + return FALSE; + break; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Dynamically outputs an image + * + * @access public + * @param resource + * @return void + */ + function image_display_gd($resource) + { + header("Content-Disposition: filename={$this->source_image};"); + header("Content-Type: {$this->mime_type}"); + header('Content-Transfer-Encoding: binary'); + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + + switch ($this->image_type) + { + case 1 : imagegif($resource); + break; + case 2 : imagejpeg($resource, '', $this->quality); + break; + case 3 : imagepng($resource); + break; + default : echo 'Unable to display the image'; + break; + } + } + + // -------------------------------------------------------------------- + + /** + * Re-proportion Image Width/Height + * + * When creating thumbs, the desired width/height + * can end up warping the image due to an incorrect + * ratio between the full-sized image and the thumb. + * + * This function lets us re-proportion the width/height + * if users choose to maintain the aspect ratio when resizing. + * + * @access public + * @return void + */ + function image_reproportion() + { + if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0) + return; + + if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0) + return; + + $new_width = ceil($this->orig_width*$this->height/$this->orig_height); + $new_height = ceil($this->width*$this->orig_height/$this->orig_width); + + $ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width)); + + if ($this->master_dim != 'width' AND $this->master_dim != 'height') + { + $this->master_dim = ($ratio < 0) ? 'width' : 'height'; + } + + if (($this->width != $new_width) AND ($this->height != $new_height)) + { + if ($this->master_dim == 'height') + { + $this->width = $new_width; + } + else + { + $this->height = $new_height; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Get image properties + * + * A helper function that gets info about the file + * + * @access public + * @param string + * @return mixed + */ + function get_image_properties($path = '', $return = FALSE) + { + // For now we require GD but we should + // find a way to determine this using IM or NetPBM + + if ($path == '') + $path = $this->full_src_path; + + if ( ! file_exists($path)) + { + $this->set_error('imglib_invalid_path'); + return FALSE; + } + + $vals = @getimagesize($path); + + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); + + $mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg'; + + if ($return == TRUE) + { + $v['width'] = $vals['0']; + $v['height'] = $vals['1']; + $v['image_type'] = $vals['2']; + $v['size_str'] = $vals['3']; + $v['mime_type'] = $mime; + + return $v; + } + + $this->orig_width = $vals['0']; + $this->orig_height = $vals['1']; + $this->image_type = $vals['2']; + $this->size_str = $vals['3']; + $this->mime_type = $mime; + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Size calculator + * + * This function takes a known width x height and + * recalculates it to a new size. Only one + * new variable needs to be known + * + * $props = array( + * 'width' => $width, + * 'height' => $height, + * 'new_width' => 40, + * 'new_height' => '' + * ); + * + * @access public + * @param array + * @return array + */ + function size_calculator($vals) + { + if ( ! is_array($vals)) + return; + + $allowed = array('new_width', 'new_height', 'width', 'height'); + + foreach ($allowed as $item) + { + if ( ! isset($vals[$item]) OR $vals[$item] == '') + $vals[$item] = 0; + } + + if ($vals['width'] == 0 OR $vals['height'] == 0) + { + return $vals; + } + + if ($vals['new_width'] == 0) + { + $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']); + } + elseif ($vals['new_height'] == 0) + { + $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']); + } + + return $vals; + } + + // -------------------------------------------------------------------- + + /** + * Explode source_image + * + * This is a helper function that extracts the extension + * from the source_image. This function lets us deal with + * source_images with multiple periods, like: my.cool.jpg + * It returns an associative array with two elements: + * $array['ext'] = '.jpg'; + * $array['name'] = 'my.cool'; + * + * @access public + * @param array + * @return array + */ + function explode_name($source_image) + { + $x = explode('.', $source_image); + $ret['ext'] = '.'.end($x); + + $name = ''; + + $ct = count($x)-1; + + for ($i = 0; $i < $ct; $i++) + { + $name .= $x[$i]; + + if ($i < ($ct - 1)) + { + $name .= '.'; + } + } + + $ret['name'] = $name; + + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Is GD Installed? + * + * @access public + * @return bool + */ + function gd_loaded() + { + if ( ! extension_loaded('gd')) + { + if ( ! dl('gd.so')) + { + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Get GD version + * + * @access public + * @return mixed + */ + function gd_version() + { + if (function_exists('gd_info')) + { + $gd_version = @gd_info(); + $gd_version = preg_replace("/\D/", "", $gd_version['GD Version']); + + return $gd_version; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + $CI =& get_instance(); + $CI->lang->load('imglib'); + + if (is_array($msg)) + { + foreach ($msg as $val) + { + + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + else + { + $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + + // -------------------------------------------------------------------- + + /** + * Show error messages + * + * @access public + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + +} +// END Image_lib Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Input.php.svn-base b/system/libraries/.svn/text-base/Input.php.svn-base new file mode 100644 index 0000000..1c5682e --- /dev/null +++ b/system/libraries/.svn/text-base/Input.php.svn-base @@ -0,0 +1,926 @@ +use_xss_clean = ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE; + $this->allow_get_array = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE; + $this->_sanitize_globals(); + } + + // -------------------------------------------------------------------- + + /** + * Sanitize Globals + * + * This function does the following: + * + * Unsets $_GET data (if query strings are not enabled) + * + * Unsets all globals if register_globals is enabled + * + * Standardizes newline characters to \n + * + * @access private + * @return void + */ + function _sanitize_globals() + { + // Would kind of be "wrong" to unset any of these GLOBALS + $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA', + 'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN'); + + // Unset globals for security. + // This is effectively the same as register_globals = off + foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global) + { + if ( ! is_array($global)) + { + if ( ! in_array($global, $protected)) + { + unset($GLOBALS[$global]); + } + } + else + { + foreach ($global as $key => $val) + { + if ( ! in_array($key, $protected)) + { + unset($GLOBALS[$key]); + } + + if (is_array($val)) + { + foreach($val as $k => $v) + { + if ( ! in_array($k, $protected)) + { + unset($GLOBALS[$k]); + } + } + } + } + } + } + + // Is $_GET data allowed? If not we'll set the $_GET to an empty array + if ($this->allow_get_array == FALSE) + { + $_GET = array(); + } + else + { + if (is_array($_GET) AND count($_GET) > 0) + { + foreach($_GET as $key => $val) + { + $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + } + + // Clean $_POST Data + if (is_array($_POST) AND count($_POST) > 0) + { + foreach($_POST as $key => $val) + { + $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + + // Clean $_COOKIE Data + if (is_array($_COOKIE) AND count($_COOKIE) > 0) + { + foreach($_COOKIE as $key => $val) + { + $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + + log_message('debug', "Global POST and COOKIE data sanitized"); + } + + // -------------------------------------------------------------------- + + /** + * Clean Input Data + * + * This is a helper function. It escapes data and + * standardizes newline characters to \n + * + * @access private + * @param string + * @return string + */ + function _clean_input_data($str) + { + if (is_array($str)) + { + $new_array = array(); + foreach ($str as $key => $val) + { + $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + return $new_array; + } + + // We strip slashes if magic quotes is on to keep things consistent + if (get_magic_quotes_gpc()) + { + $str = stripslashes($str); + } + + // Should we filter the input data? + if ($this->use_xss_clean === TRUE) + { + $str = $this->xss_clean($str); + } + + // Standardize newlines + return preg_replace("/\015\012|\015|\012/", "\n", $str); + } + + // -------------------------------------------------------------------- + + /** + * Clean Keys + * + * This is a helper function. To prevent malicious users + * from trying to exploit keys we make sure that keys are + * only named with alpha-numeric text and a few other items. + * + * @access private + * @param string + * @return string + */ + function _clean_input_keys($str) + { + if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) + { + exit('Disallowed Key Characters.'); + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the GET array + * + * @access public + * @param string + * @param bool + * @return string + */ + function get($index = '', $xss_clean = FALSE) + { + if ( ! isset($_GET[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_GET[$index])) + { + foreach($_GET[$index] as $key => $val) + { + $_GET[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_GET[$index]); + } + } + + return $_GET[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the POST array + * + * @access public + * @param string + * @param bool + * @return string + */ + function post($index = '', $xss_clean = FALSE) + { + if ( ! isset($_POST[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_POST[$index])) + { + foreach($_POST[$index] as $key => $val) + { + $_POST[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_POST[$index]); + } + } + + return $_POST[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the COOKIE array + * + * @access public + * @param string + * @param bool + * @return string + */ + function cookie($index = '', $xss_clean = FALSE) + { + if ( ! isset($_COOKIE[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_COOKIE[$index])) + { + $cookie = array(); + foreach($_COOKIE[$index] as $key => $val) + { + $cookie[$key] = $this->xss_clean($val); + } + + return $cookie; + } + else + { + return $this->xss_clean($_COOKIE[$index]); + } + } + else + { + return $_COOKIE[$index]; + } + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the SERVER array + * + * @access public + * @param string + * @param bool + * @return string + */ + function server($index = '', $xss_clean = FALSE) + { + if ( ! isset($_SERVER[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + return $this->xss_clean($_SERVER[$index]); + } + + return $_SERVER[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the IP Address + * + * @access public + * @return string + */ + function ip_address() + { + if ($this->ip_address !== FALSE) + { + return $this->ip_address; + } + + if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + elseif ($this->server('REMOTE_ADDR')) + { + $this->ip_address = $_SERVER['REMOTE_ADDR']; + } + elseif ($this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + elseif ($this->server('HTTP_X_FORWARDED_FOR')) + { + $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + + if ($this->ip_address === FALSE) + { + $this->ip_address = '0.0.0.0'; + return $this->ip_address; + } + + if (strstr($this->ip_address, ',')) + { + $x = explode(',', $this->ip_address); + $this->ip_address = end($x); + } + + if ( ! $this->valid_ip($this->ip_address)) + { + $this->ip_address = '0.0.0.0'; + } + + return $this->ip_address; + } + + // -------------------------------------------------------------------- + + /** + * Validate IP Address + * + * Updated version suggested by Geert De Deckere + * + * @access public + * @param string + * @return string + */ + function valid_ip($ip) + { + $ip_segments = explode('.', $ip); + + // Always 4 segments needed + if (count($ip_segments) != 4) + { + return FALSE; + } + // IP can not start with 0 + if (substr($ip_segments[0], 0, 1) == '0') + { + return FALSE; + } + // Check each segment + foreach ($ip_segments as $segment) + { + // IP segments must be digits and can not be + // longer than 3 digits or greater then 255 + if (preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) + { + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * User Agent + * + * @access public + * @return string + */ + function user_agent() + { + if ($this->user_agent !== FALSE) + { + return $this->user_agent; + } + + $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT']; + + return $this->user_agent; + } + + // -------------------------------------------------------------------- + + /** + * Filename Security + * + * @access public + * @param string + * @return string + */ + function filename_security($str) + { + $bad = array( + "../", + "./", + "", + "<", + ">", + "'", + '"', + '&', + '$', + '#', + '{', + '}', + '[', + ']', + '=', + ';', + '?', + "%20", + "%22", + "%3c", // < + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; + "%3d" // = + ); + + return stripslashes(str_replace($bad, '', $str)); + } + + // -------------------------------------------------------------------- + + /** + * XSS Clean + * + * Sanitizes data so that Cross Site Scripting Hacks can be + * prevented.  This function does a fair amount of work but + * it is extremely thorough, designed to prevent even the + * most obscure XSS attempts.  Nothing is ever 100% foolproof, + * of course, but I haven't been able to get anything passed + * the filter. + * + * Note: This function should only be used to deal with data + * upon submission.  It's not something that should + * be used for general runtime processing. + * + * This function was based in part on some code and ideas I + * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention + * + * To help develop this script I used this great list of + * vulnerabilities along with a few other hacks I've + * harvested from examining vulnerabilities in other programs: + * http://ha.ckers.org/xss.html + * + * @access public + * @param string + * @return string + */ + function xss_clean($str) + { + /* + * Remove Null Characters + * + * This prevents sandwiching null characters + * between ascii characters, like Java\0script. + * + */ + $str = preg_replace('/\0+/', '', $str); + $str = preg_replace('/(\\\\0)+/', '', $str); + + /* + * Validate standard character entities + * + * Add a semicolon if missing. We do this to enable + * the conversion of entities to ASCII later. + * + */ + $str = preg_replace('#(&\#?[0-9a-z]+)[\x00-\x20]*;?#i', "\\1;", $str); + + /* + * Validate UTF16 two byte encoding (x00) + * + * Just as above, adds a semicolon if missing. + * + */ + $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str); + + /* + * URL Decode + * + * Just in case stuff like this is submitted: + * + * Google + * + * Note: Use rawurldecode() so it does not remove plus signs + * + */ + $str = rawurldecode($str); + + /* + * Convert character entities to ASCII + * + * This permits our tests below to work reliably. + * We only convert entities that are within tags since + * these are the ones that will pose security problems. + * + */ + + $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_attribute_conversion'), $str); + + $str = preg_replace_callback("/<([\w]+)[^>]*>/si", array($this, '_html_entity_decode_callback'), $str); + + /* + + Old Code that when modified to use preg_replace()'s above became more efficient memory-wise + + if (preg_match_all("/[a-z]+=([\'\"]).*?\\1/si", $str, $matches)) + { + for ($i = 0; $i < count($matches[0]); $i++) + { + if (stristr($matches[0][$i], '>')) + { + $str = str_replace( $matches['0'][$i], + str_replace('>', '<', $matches[0][$i]), + $str); + } + } + } + + if (preg_match_all("/<([\w]+)[^>]*>/si", $str, $matches)) + { + for ($i = 0; $i < count($matches[0]); $i++) + { + $str = str_replace($matches[0][$i], + $this->_html_entity_decode($matches[0][$i], $charset), + $str); + } + } + */ + + /* + * Convert all tabs to spaces + * + * This prevents strings like this: ja vascript + * NOTE: we deal with spaces between characters later. + * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, + * so we use str_replace. + * + */ + + $str = str_replace("\t", " ", $str); + + /* + * Not Allowed Under Any Conditions + */ + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', // CSS and IE + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + /* + * Makes PHP tags safe + * + * Note: XML tags are inadvertently replaced too: + * + * '), array('<?php', '<?PHP', '<?', '?>'), $str); + + /* + * Compact any exploded words + * + * This corrects words like: j a v a s c r i p t + * These words are compacted back to their correct state. + * + */ + $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); + foreach ($words as $word) + { + $temp = ''; + for ($i = 0; $i < strlen($word); $i++) + { + $temp .= substr($word, $i, 1)."\s*"; + } + + // We only want to do this when it is followed by a non-word character + // That way valid stuff like "dealer to" does not become "dealerto" + $str = preg_replace('#('.substr($temp, 0, -3).')(\W)#ise', "preg_replace('/\s+/s', '', '\\1').'\\2'", $str); + } + + /* + * Remove disallowed Javascript in links or img tags + */ + do + { + $original = $str; + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '') !== FALSE) OR + preg_match("/<\/a>/i", $str)) + { + $str = preg_replace_callback("##si", array($this, '_js_link_removal'), $str); + } + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '#si", array($this, '_js_img_removal'), $str); + } + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && (stripos($str, 'script') !== FALSE OR stripos($str, 'xss') !== FALSE)) OR + preg_match("/(script|xss)/i", $str)) + { + $str = preg_replace("##si", "", $str); + } + } + while($original != $str); + + unset($original); + + /* + * Remove JavaScript Event Handlers + * + * Note: This code is a little blunt. It removes + * the event handler and anything up to the closing >, + * but it's unlikely to be a problem. + * + */ + $event_handlers = array('onblur','onchange','onclick','onfocus','onload','onmouseover','onmouseup','onmousedown','onselect','onsubmit','onunload','onkeypress','onkeydown','onkeyup','onresize', 'xmlns'); + $str = preg_replace("#<([^>]+)(".implode('|', $event_handlers).")([^>]*)>#iU", "<\\1\\2\\3>", $str); + + /* + * Sanitize naughty HTML elements + * + * If a tag containing any of the words in the list + * below is found, the tag gets converted to entities. + * + * So this: + * Becomes: <blink> + * + */ + $str = preg_replace('#<(/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>#is', "<\\1\\2\\3>", $str); + + /* + * Sanitize naughty scripting elements + * + * Similar to above, only instead of looking for + * tags it looks for PHP and JavaScript commands + * that are disallowed. Rather than removing the + * code, it simply converts the parenthesis to entities + * rendering the code un-executable. + * + * For example: eval('some code') + * Becomes: eval('some code') + * + */ + $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str); + + /* + * Final clean up + * + * This adds a bit of extra precaution in case + * something got through the above filters + * + */ + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', // CSS and IE + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + + log_message('debug', "XSS Filtering completed"); + return $str; + } + + // -------------------------------------------------------------------- + + /** + * JS Link Removal + * + * Callback function for xss_clean() to sanitize links + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on link-heavy strings + * + * @access private + * @param array + * @return string + */ + function _js_link_removal($match) + { + return preg_replace("#.*?#si", "", $match[0]); + } + + /** + * JS Image Removal + * + * Callback function for xss_clean() to sanitize image tags + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on image tag heavy strings + * + * @access private + * @param array + * @return string + */ + function _js_img_removal($match) + { + return preg_replace("##si", "", $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * Attribute Conversion + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ + function _attribute_conversion($match) + { + return str_replace('>', '<', $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * HTML Entity Decode Callback + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ + function _html_entity_decode_callback($match) + { + global $CFG; + $charset = $CFG->item('charset'); + + return $this->_html_entity_decode($match[0], strtoupper($charset)); + } + + // -------------------------------------------------------------------- + + /** + * HTML Entities Decode + * + * This function is a replacement for html_entity_decode() + * + * In some versions of PHP the native function does not work + * when UTF-8 is the specified character set, so this gives us + * a work-around. More info here: + * http://bugs.php.net/bug.php?id=25670 + * + * @access private + * @param string + * @param string + * @return string + */ + /* ------------------------------------------------- + /* Replacement for html_entity_decode() + /* -------------------------------------------------*/ + + /* + NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the + character set, and the PHP developers said they were not back porting the + fix to versions other than PHP 5.x. + */ + function _html_entity_decode($str, $charset='UTF-8') + { + if (stristr($str, '&') === FALSE) return $str; + + // The reason we are not using html_entity_decode() by itself is because + // while it is not technically correct to leave out the semicolon + // at the end of an entity most browsers will still interpret the entity + // correctly. html_entity_decode() does not convert entities without + // semicolons, so we are left with our own little solution here. Bummer. + + if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>='))) + { + $str = html_entity_decode($str, ENT_COMPAT, $charset); + $str = preg_replace('~&#x([0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); + return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); + } + + // Numeric Entities + $str = preg_replace('~&#x([0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str); + $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str); + + // Literal Entities - Slightly slow so we do another check + if (stristr($str, '&') === FALSE) + { + $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES))); + } + + return $str; + } + +} +// END Input class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Language.php.svn-base b/system/libraries/.svn/text-base/Language.php.svn-base new file mode 100644 index 0000000..3dac1a6 --- /dev/null +++ b/system/libraries/.svn/text-base/Language.php.svn-base @@ -0,0 +1,121 @@ +is_loaded, TRUE)) + { + return; + } + + if ($idiom == '') + { + $CI =& get_instance(); + $deft_lang = $CI->config->item('language'); + $idiom = ($deft_lang == '') ? 'english' : $deft_lang; + } + + // Determine where the language file is and load it + if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile)) + { + include(APPPATH.'language/'.$idiom.'/'.$langfile); + } + else + { + if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile)) + { + include(BASEPATH.'language/'.$idiom.'/'.$langfile); + } + else + { + show_error('Unable to load the requested language file: language/'.$langfile); + } + } + + + if ( ! isset($lang)) + { + log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); + return; + } + + if ($return == TRUE) + { + return $lang; + } + + $this->is_loaded[] = $langfile; + $this->language = array_merge($this->language, $lang); + unset($lang); + + log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a single line of text from the language array + * + * @access public + * @param string the language line + * @return string + */ + function line($line = '') + { + return ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; + } + +} +// END Language Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Loader.php.svn-base b/system/libraries/.svn/text-base/Loader.php.svn-base new file mode 100644 index 0000000..576cb11 --- /dev/null +++ b/system/libraries/.svn/text-base/Loader.php.svn-base @@ -0,0 +1,1028 @@ + 'unit', 'user_agent' => 'agent'); + + + /** + * Constructor + * + * Sets the path to the view files and gets the initial output buffering level + * + * @access public + */ + function CI_Loader() + { + $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE; + $this->_ci_view_path = APPPATH.'views/'; + $this->_ci_ob_level = ob_get_level(); + + log_message('debug', "Loader Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Class Loader + * + * This function lets users load and instantiate classes. + * It is designed to be called from a user's app controllers. + * + * @access public + * @param string the name of the class + * @param mixed the optional parameters + * @return void + */ + function library($library = '', $params = NULL) + { + if ($library == '') + { + return FALSE; + } + + if (is_array($library)) + { + foreach ($library as $class) + { + $this->_ci_load_class($class, $params); + } + } + else + { + $this->_ci_load_class($library, $params); + } + + $this->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Model Loader + * + * This function lets users load and instantiate models. + * + * @access public + * @param string the name of the class + * @param mixed any initialization parameters + * @return void + */ + function model($model, $name = '', $db_conn = FALSE) + { + if (is_array($model)) + { + foreach($model as $babe) + { + $this->model($babe); + } + return; + } + + if ($model == '') + { + return; + } + + // Is the model in a sub-folder? If so, parse out the filename and path. + if (strpos($model, '/') === FALSE) + { + $path = ''; + } + else + { + $x = explode('/', $model); + $model = end($x); + unset($x[count($x)-1]); + $path = implode('/', $x).'/'; + } + + if ($name == '') + { + $name = $model; + } + + if (in_array($name, $this->_ci_models, TRUE)) + { + return; + } + + $CI =& get_instance(); + if (isset($CI->$name)) + { + show_error('The model name you are loading is the name of a resource that is already being used: '.$name); + } + + $model = strtolower($model); + + if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT)) + { + show_error('Unable to locate the model you have specified: '.$model); + } + + if ($db_conn !== FALSE AND ! class_exists('CI_DB')) + { + if ($db_conn === TRUE) + $db_conn = ''; + + $CI->load->database($db_conn, FALSE, TRUE); + } + + if ( ! class_exists('Model')) + { + load_class('Model', FALSE); + } + + require_once(APPPATH.'models/'.$path.$model.EXT); + + $model = ucfirst($model); + + $CI->$name = new $model(); + $CI->$name->_assign_libraries(); + + $this->_ci_models[] = $name; + } + + // -------------------------------------------------------------------- + + /** + * Database Loader + * + * @access public + * @param string the DB credentials + * @param bool whether to return the DB object + * @param bool whether to enable active record (this allows us to override the config setting) + * @return object + */ + function database($params = '', $return = FALSE, $active_record = FALSE) + { + // Grab the super object + $CI =& get_instance(); + + // Do we even need to load the database class? + if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db)) + { + return FALSE; + } + + require_once(BASEPATH.'database/DB'.EXT); + + if ($return === TRUE) + { + return DB($params, $active_record); + } + + // Initialize the db variable. Needed to prevent + // reference errors with some configurations + $CI->db = ''; + + // Load the DB class + $CI->db =& DB($params, $active_record); + + // Assign the DB object to any existing models + $this->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Load the Utilities Class + * + * @access public + * @return string + */ + function dbutil() + { + if ( ! class_exists('CI_DB')) + { + $this->database(); + } + + $CI =& get_instance(); + + // for backwards compatibility, load dbforge so we can extend dbutils off it + // this use is deprecated and strongly discouraged + $CI->load->dbforge(); + + require_once(BASEPATH.'database/DB_utility'.EXT); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT); + $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; + + $CI->dbutil =& new $class(); + + $CI->load->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Forge Class + * + * @access public + * @return string + */ + function dbforge() + { + if ( ! class_exists('CI_DB')) + { + $this->database(); + } + + $CI =& get_instance(); + + require_once(BASEPATH.'database/DB_forge'.EXT); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT); + $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; + + $CI->dbforge = new $class(); + } + + // -------------------------------------------------------------------- + + /** + * Load View + * + * This function is used to load a "view" file. It has three parameters: + * + * 1. The name of the "view" file to be included. + * 2. An associative array of data to be extracted for use in the view. + * 3. TRUE/FALSE - whether to return the data or load it. In + * some cases it's advantageous to be able to return data so that + * a developer can process it in some way. + * + * @access public + * @param string + * @param array + * @param bool + * @return void + */ + function view($view, $vars = array(), $return = FALSE) + { + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Load File + * + * This is a generic file loader + * + * @access public + * @param string + * @param bool + * @return string + */ + function file($path, $return = FALSE) + { + return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Set Variables + * + * Once variables are set they become available within + * the controller class and its "view" files. + * + * @access public + * @param array + * @return void + */ + function vars($vars = array()) + { + $vars = $this->_ci_object_to_array($vars); + + if (is_array($vars) AND count($vars) > 0) + { + foreach ($vars as $key => $val) + { + $this->_ci_cached_vars[$key] = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Load Helper + * + * This function loads the specified helper file. + * + * @access public + * @param mixed + * @return void + */ + function helper($helpers = array()) + { + if ( ! is_array($helpers)) + { + $helpers = array($helpers); + } + + foreach ($helpers as $helper) + { + $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper'); + + if (isset($this->_ci_helpers[$helper])) + { + continue; + } + + $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT; + + // Is this a helper extension request? + if (file_exists($ext_helper)) + { + $base_helper = BASEPATH.'helpers/'.$helper.EXT; + + if ( ! file_exists($base_helper)) + { + show_error('Unable to load the requested file: helpers/'.$helper.EXT); + } + + include_once($ext_helper); + include_once($base_helper); + } + elseif (file_exists(APPPATH.'helpers/'.$helper.EXT)) + { + include_once(APPPATH.'helpers/'.$helper.EXT); + } + else + { + if (file_exists(BASEPATH.'helpers/'.$helper.EXT)) + { + include(BASEPATH.'helpers/'.$helper.EXT); + } + else + { + show_error('Unable to load the requested file: helpers/'.$helper.EXT); + } + } + + $this->_ci_helpers[$helper] = TRUE; + + } + + log_message('debug', 'Helpers loaded: '.implode(', ', $helpers)); + } + + // -------------------------------------------------------------------- + + /** + * Load Helpers + * + * This is simply an alias to the above function in case the + * user has written the plural form of this function. + * + * @access public + * @param array + * @return void + */ + function helpers($helpers = array()) + { + $this->helper($helpers); + } + + // -------------------------------------------------------------------- + + /** + * Load Plugin + * + * This function loads the specified plugin. + * + * @access public + * @param array + * @return void + */ + function plugin($plugins = array()) + { + if ( ! is_array($plugins)) + { + $plugins = array($plugins); + } + + foreach ($plugins as $plugin) + { + $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi'); + + if (isset($this->_ci_plugins[$plugin])) + { + continue; + } + + if (file_exists(APPPATH.'plugins/'.$plugin.EXT)) + { + include(APPPATH.'plugins/'.$plugin.EXT); + } + else + { + if (file_exists(BASEPATH.'plugins/'.$plugin.EXT)) + { + include(BASEPATH.'plugins/'.$plugin.EXT); + } + else + { + show_error('Unable to load the requested file: plugins/'.$plugin.EXT); + } + } + + $this->_ci_plugins[$plugin] = TRUE; + } + + log_message('debug', 'Plugins loaded: '.implode(', ', $plugins)); + } + + // -------------------------------------------------------------------- + + /** + * Load Plugins + * + * This is simply an alias to the above function in case the + * user has written the plural form of this function. + * + * @access public + * @param array + * @return void + */ + function plugins($plugins = array()) + { + $this->plugin($plugins); + } + + // -------------------------------------------------------------------- + + /** + * Load Script + * + * This function loads the specified include file from the + * application/scripts/ folder. + * + * NOTE: This feature has been deprecated but it will remain available + * for legacy users. + * + * @access public + * @param array + * @return void + */ + function script($scripts = array()) + { + if ( ! is_array($scripts)) + { + $scripts = array($scripts); + } + + foreach ($scripts as $script) + { + $script = strtolower(str_replace(EXT, '', $script)); + + if (isset($this->_ci_scripts[$script])) + { + continue; + } + + if ( ! file_exists(APPPATH.'scripts/'.$script.EXT)) + { + show_error('Unable to load the requested script: scripts/'.$script.EXT); + } + + include(APPPATH.'scripts/'.$script.EXT); + } + + log_message('debug', 'Scripts loaded: '.implode(', ', $scripts)); + } + + // -------------------------------------------------------------------- + + /** + * Loads a language file + * + * @access public + * @param array + * @param string + * @return void + */ + function language($file = array(), $lang = '') + { + $CI =& get_instance(); + + if ( ! is_array($file)) + { + $file = array($file); + } + + foreach ($file as $langfile) + { + $CI->lang->load($langfile, $lang); + } + } + + /** + * Loads language files for scaffolding + * + * @access public + * @param string + * @return arra + */ + function scaffold_language($file = '', $lang = '', $return = FALSE) + { + $CI =& get_instance(); + return $CI->lang->load($file, $lang, $return); + } + + // -------------------------------------------------------------------- + + /** + * Loads a config file + * + * @access public + * @param string + * @return void + */ + function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + { + $CI =& get_instance(); + $CI->config->load($file, $use_sections, $fail_gracefully); + } + + // -------------------------------------------------------------------- + + /** + * Scaffolding Loader + * + * This initializing function works a bit different than the + * others. It doesn't load the class. Instead, it simply + * sets a flag indicating that scaffolding is allowed to be + * used. The actual scaffolding function below is + * called by the front controller based on whether the + * second segment of the URL matches the "secret" scaffolding + * word stored in the application/config/routes.php + * + * @access public + * @param string + * @return void + */ + function scaffolding($table = '') + { + if ($table === FALSE) + { + show_error('You must include the name of the table you would like to access when you initialize scaffolding'); + } + + $CI =& get_instance(); + $CI->_ci_scaffolding = TRUE; + $CI->_ci_scaff_table = $table; + } + + // -------------------------------------------------------------------- + + /** + * Loader + * + * This function is used to load views and files. + * Variables are prefixed with _ci_ to avoid symbol collision with + * variables made available to view files + * + * @access private + * @param array + * @return void + */ + function _ci_load($_ci_data) + { + // Set the default data variables + foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) + { + $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val]; + } + + // Set the path to the requested file + if ($_ci_path == '') + { + $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); + $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view; + $_ci_path = $this->_ci_view_path.$_ci_file; + } + else + { + $_ci_x = explode('/', $_ci_path); + $_ci_file = end($_ci_x); + } + + if ( ! file_exists($_ci_path)) + { + show_error('Unable to load the requested file: '.$_ci_file); + } + + // This allows anything loaded using $this->load (views, files, etc.) + // to become accessible from within the Controller and Model functions. + // Only needed when running PHP 5 + + if ($this->_ci_is_instance()) + { + $_ci_CI =& get_instance(); + foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) + { + if ( ! isset($this->$_ci_key)) + { + $this->$_ci_key =& $_ci_CI->$_ci_key; + } + } + } + + /* + * Extract and cache variables + * + * You can either set variables using the dedicated $this->load_vars() + * function or via the second parameter of this function. We'll merge + * the two types and cache them so that views that are embedded within + * other views can have access to these variables. + */ + if (is_array($_ci_vars)) + { + $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); + } + extract($this->_ci_cached_vars); + + /* + * Buffer the output + * + * We buffer the output for two reasons: + * 1. Speed. You get a significant speed boost. + * 2. So that the final rendered template can be + * post-processed by the output class. Why do we + * need post processing? For one thing, in order to + * show the elapsed page load time. Unless we + * can intercept the content right before it's sent to + * the browser and then stop the timer it won't be accurate. + */ + ob_start(); + + // If the PHP installation does not support short tags we'll + // do a little string replacement, changing the short tags + // to standard PHP echo statements. + + if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE) + { + echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace(' $this->_ci_ob_level + 1) + { + ob_end_flush(); + } + else + { + // PHP 4 requires that we use a global + global $OUT; + $OUT->append_output(ob_get_contents()); + @ob_end_clean(); + } + } + + // -------------------------------------------------------------------- + + /** + * Load class + * + * This function loads the requested class. + * + * @access private + * @param string the item that is being loaded + * @param mixed any additional parameters + * @return void + */ + function _ci_load_class($class, $params = NULL) + { + // Get the class name + $class = str_replace(EXT, '', $class); + + // We'll test for both lowercase and capitalized versions of the file name + foreach (array(ucfirst($class), strtolower($class)) as $class) + { + $subclass = APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT; + + // Is this a class extension request? + if (file_exists($subclass)) + { + $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT; + + if ( ! file_exists($baseclass)) + { + log_message('error', "Unable to load the requested class: ".$class); + show_error("Unable to load the requested class: ".$class); + } + + // Safety: Was the class already loaded by a previous call? + if (in_array($subclass, $this->_ci_classes)) + { + $is_duplicate = TRUE; + log_message('debug', $class." class already loaded. Second attempt ignored."); + return; + } + + include($baseclass); + include($subclass); + $this->_ci_classes[] = $subclass; + + return $this->_ci_init_class($class, config_item('subclass_prefix'), $params); + } + + // Lets search for the requested library file and load it. + $is_duplicate = FALSE; + for ($i = 1; $i < 3; $i++) + { + $path = ($i % 2) ? APPPATH : BASEPATH; + $filepath = $path.'libraries/'.$class.EXT; + + // Does the file exist? No? Bummer... + if ( ! file_exists($filepath)) + { + continue; + } + + // Safety: Was the class already loaded by a previous call? + if (in_array($filepath, $this->_ci_classes)) + { + $is_duplicate = TRUE; + log_message('debug', $class." class already loaded. Second attempt ignored."); + return; + } + + include($filepath); + $this->_ci_classes[] = $filepath; + return $this->_ci_init_class($class, '', $params); + } + } // END FOREACH + + // If we got this far we were unable to find the requested class. + // We do not issue errors if the load call failed due to a duplicate request + if ($is_duplicate == FALSE) + { + log_message('error', "Unable to load the requested class: ".$class); + show_error("Unable to load the requested class: ".$class); + } + } + + // -------------------------------------------------------------------- + + /** + * Instantiates a class + * + * @access private + * @param string + * @param string + * @return null + */ + function _ci_init_class($class, $prefix = '', $config = FALSE) + { + $class = strtolower($class); + + // Is there an associated config file for this class? + if ($config === NULL) + { + if (file_exists(APPPATH.'config/'.$class.EXT)) + { + include(APPPATH.'config/'.$class.EXT); + } + } + + if ($prefix == '') + { + $name = (class_exists('CI_'.$class)) ? 'CI_'.$class : $class; + } + else + { + $name = $prefix.$class; + } + + // Set the variable name we will assign the class to + $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class]; + + // Instantiate the class + $CI =& get_instance(); + if ($config !== NULL) + { + $CI->$classvar = new $name($config); + } + else + { + $CI->$classvar = new $name; + } + } + + // -------------------------------------------------------------------- + + /** + * Autoloader + * + * The config/autoload.php file contains an array that permits sub-systems, + * libraries, plugins, and helpers to be loaded automatically. + * + * @access private + * @param array + * @return void + */ + function _ci_autoloader() + { + include(APPPATH.'config/autoload'.EXT); + + if ( ! isset($autoload)) + { + return FALSE; + } + + // Load any custom config file + if (count($autoload['config']) > 0) + { + $CI =& get_instance(); + foreach ($autoload['config'] as $key => $val) + { + $CI->config->load($val); + } + } + + // Autoload plugins, helpers, scripts and languages + foreach (array('helper', 'plugin', 'script', 'language') as $type) + { + if (isset($autoload[$type]) AND count($autoload[$type]) > 0) + { + $this->$type($autoload[$type]); + } + } + + + + // A little tweak to remain backward compatible + // The $autoload['core'] item was deprecated + if ( ! isset($autoload['libraries'])) + { + $autoload['libraries'] = $autoload['core']; + } + + // Load libraries + if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0) + { + // Load the database driver. + if (in_array('database', $autoload['libraries'])) + { + $this->database(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); + } + + // Load scaffolding + if (in_array('scaffolding', $autoload['libraries'])) + { + $this->scaffolding(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding')); + } + + // Load all other libraries + foreach ($autoload['libraries'] as $item) + { + $this->library($item); + } + } + + // Autoload models + if (isset($autoload['model'])) + { + $this->model($autoload['model']); + } + + } + + // -------------------------------------------------------------------- + + /** + * Assign to Models + * + * Makes sure that anything loaded by the loader class (libraries, plugins, etc.) + * will be available to models, if any exist. + * + * @access private + * @param object + * @return array + */ + function _ci_assign_to_models() + { + if (count($this->_ci_models) == 0) + { + return; + } + + if ($this->_ci_is_instance()) + { + $CI =& get_instance(); + foreach ($this->_ci_models as $model) + { + $CI->$model->_assign_libraries(); + } + } + else + { + foreach ($this->_ci_models as $model) + { + $this->$model->_assign_libraries(); + } + } + } + + // -------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @access private + * @param object + * @return array + */ + function _ci_object_to_array($object) + { + return (is_object($object)) ? get_object_vars($object) : $object; + } + + // -------------------------------------------------------------------- + + /** + * Determines whether we should use the CI instance or $this + * + * @access private + * @return bool + */ + function _ci_is_instance() + { + if ($this->_ci_is_php5 == TRUE) + { + return TRUE; + } + + global $CI; + return (is_object($CI)) ? TRUE : FALSE; + } + +} +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Log.php.svn-base b/system/libraries/.svn/text-base/Log.php.svn-base new file mode 100644 index 0000000..f9ca85a --- /dev/null +++ b/system/libraries/.svn/text-base/Log.php.svn-base @@ -0,0 +1,118 @@ + '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4'); + + /** + * Constructor + * + * @access public + * @param string the log file path + * @param string the error threshold + * @param string the date formatting codes + */ + function CI_Log() + { + $config =& get_config(); + + $this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/'; + + if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path)) + { + $this->_enabled = FALSE; + } + + if (is_numeric($config['log_threshold'])) + { + $this->_threshold = $config['log_threshold']; + } + + if ($config['log_date_format'] != '') + { + $this->_date_fmt = $config['log_date_format']; + } + } + + // -------------------------------------------------------------------- + + /** + * Write Log File + * + * Generally this function will be called using the global log_message() function + * + * @access public + * @param string the error level + * @param string the error message + * @param bool whether the error is a native PHP error + * @return bool + */ + function write_log($level = 'error', $msg, $php_error = FALSE) + { + if ($this->_enabled === FALSE) + { + return FALSE; + } + + $level = strtoupper($level); + + if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) + { + return FALSE; + } + + $filepath = $this->log_path.'log-'.date('Y-m-d').EXT; + $message = ''; + + if ( ! file_exists($filepath)) + { + $message .= "<"."?php if (!defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n"; + } + + if ( ! $fp = @fopen($filepath, "a")) + { + return FALSE; + } + + $message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n"; + + flock($fp, LOCK_EX); + fwrite($fp, $message); + flock($fp, LOCK_UN); + fclose($fp); + + @chmod($filepath, 0666); + return TRUE; + } + +} +// END Log Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Model.php.svn-base b/system/libraries/.svn/text-base/Model.php.svn-base new file mode 100644 index 0000000..8181ead --- /dev/null +++ b/system/libraries/.svn/text-base/Model.php.svn-base @@ -0,0 +1,82 @@ +_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE ); + + // We don't want to assign the model object to itself when using the + // assign_libraries function below so we'll grab the name of the model parent + $this->_parent_name = ucfirst(get_class($this)); + + log_message('debug', "Model Class Initialized"); + } + + /** + * Assign Libraries + * + * Creates local references to all currently instantiated objects + * so that any syntax that can be legally used in a controller + * can be used within models. + * + * @access private + */ + function _assign_libraries($use_reference = TRUE) + { + $CI =& get_instance(); + foreach (array_keys(get_object_vars($CI)) as $key) + { + if ( ! isset($this->$key) AND $key != $this->_parent_name) + { + // In some cases using references can cause + // problems so we'll conditionally use them + if ($use_reference == TRUE) + { + // Needed to prevent reference errors with some configurations + $this->$key = ''; + $this->$key =& $CI->$key; + } + else + { + $this->$key = $CI->$key; + } + } + } + } + +} +// END Model Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Output.php.svn-base b/system/libraries/.svn/text-base/Output.php.svn-base new file mode 100644 index 0000000..a4d8d34 --- /dev/null +++ b/system/libraries/.svn/text-base/Output.php.svn-base @@ -0,0 +1,386 @@ +final_output; + } + + // -------------------------------------------------------------------- + + /** + * Set Output + * + * Sets the output string + * + * @access public + * @param string + * @return void + */ + function set_output($output) + { + $this->final_output = $output; + } + + // -------------------------------------------------------------------- + + /** + * Append Output + * + * Appends data onto the output string + * + * @access public + * @param string + * @return void + */ + function append_output($output) + { + if ($this->final_output == '') + { + $this->final_output = $output; + } + else + { + $this->final_output .= $output; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Header + * + * Lets you set a server header which will be outputted with the final display. + * + * Note: If a file is cached, headers will not be sent. We need to figure out + * how to permit header data to be saved with the cache data... + * + * @access public + * @param string + * @return void + */ + function set_header($header) + { + $this->headers[] = $header; + } + + // -------------------------------------------------------------------- + + /** + * Enable/disable Profiler + * + * @access public + * @param bool + * @return void + */ + function enable_profiler($val = TRUE) + { + $this->enable_profiler = (is_bool($val)) ? $val : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Cache + * + * @access public + * @param integer + * @return void + */ + function cache($time) + { + $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time; + } + + // -------------------------------------------------------------------- + + /** + * Display Output + * + * All "view" data is automatically put into this variable by the controller class: + * + * $this->final_output + * + * This function sends the finalized output data to the browser along + * with any server headers and profile data. It also stops the + * benchmark timer so the page rendering speed and memory usage can be shown. + * + * @access public + * @return mixed + */ + function _display($output = '') + { + // Note: We use globals because we can't use $CI =& get_instance() + // since this function is sometimes called by the caching mechanism, + // which happens before the CI super object is available. + global $BM, $CFG; + + // -------------------------------------------------------------------- + + // Set the output data + if ($output == '') + { + $output =& $this->final_output; + } + + // -------------------------------------------------------------------- + + // Do we need to write a cache file? + if ($this->cache_expiration > 0) + { + $this->_write_cache($output); + } + + // -------------------------------------------------------------------- + + // Parse out the elapsed time and memory usage, + // then swap the pseudo-variables with the data + + $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end'); + $output = str_replace('{elapsed_time}', $elapsed, $output); + + $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB'; + $output = str_replace('{memory_usage}', $memory, $output); + + // -------------------------------------------------------------------- + + // Is compression requested? + if ($CFG->item('compress_output') === TRUE) + { + if (extension_loaded('zlib')) + { + if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) + { + ob_start('ob_gzhandler'); + } + } + } + + // -------------------------------------------------------------------- + + // Are there any server headers to send? + if (count($this->headers) > 0) + { + foreach ($this->headers as $header) + { + @header($header); + } + } + + // -------------------------------------------------------------------- + + // Does the get_instance() function exist? + // If not we know we are dealing with a cache file so we'll + // simply echo out the data and exit. + if ( ! function_exists('get_instance')) + { + echo $output; + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: ".$elapsed); + return TRUE; + } + + // -------------------------------------------------------------------- + + // Grab the super object. We'll need it in a moment... + $CI =& get_instance(); + + // Do we need to generate profile data? + // If so, load the Profile class and run it. + if ($this->enable_profiler == TRUE) + { + $CI->load->library('profiler'); + + // If the output data contains closing and tags + // we will remove them and add them back after we insert the profile data + if (preg_match("|.*?|is", $output)) + { + $output = preg_replace("|.*?|is", '', $output); + $output .= $CI->profiler->run(); + $output .= ''; + } + else + { + $output .= $CI->profiler->run(); + } + } + + // -------------------------------------------------------------------- + + // Does the controller contain a function named _output()? + // If so send the output there. Otherwise, echo it. + if (method_exists($CI, '_output')) + { + $CI->_output($output); + } + else + { + echo $output; // Send it to the browser! + } + + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: ".$elapsed); + } + + // -------------------------------------------------------------------- + + /** + * Write a Cache File + * + * @access public + * @return void + */ + function _write_cache($output) + { + $CI =& get_instance(); + $path = $CI->config->item('cache_path'); + + $cache_path = ($path == '') ? BASEPATH.'cache/' : $path; + + if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) + { + return; + } + + $uri = $CI->config->item('base_url'). + $CI->config->item('index_page'). + $CI->uri->uri_string(); + + $cache_path .= md5($uri); + + if ( ! $fp = @fopen($cache_path, 'wb')) + { + log_message('error', "Unable to write cache file: ".$cache_path); + return; + } + + $expire = time() + ($this->cache_expiration * 60); + + flock($fp, LOCK_EX); + fwrite($fp, $expire.'TS--->'.$output); + flock($fp, LOCK_UN); + fclose($fp); + @chmod($cache_path, 0777); + + log_message('debug', "Cache file written: ".$cache_path); + } + + // -------------------------------------------------------------------- + + /** + * Update/serve a cached file + * + * @access public + * @return void + */ + function _display_cache(&$CFG, &$RTR) + { + $URI =& load_class('URI'); + + $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path'); + + if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) + { + return FALSE; + } + + // Build the file path. The file name is an MD5 hash of the full URI + $uri = $CFG->item('base_url'). + $CFG->item('index_page'). + $URI->uri_string; + + $filepath = $cache_path.md5($uri); + + if ( ! @file_exists($filepath)) + { + return FALSE; + } + + if ( ! $fp = @fopen($filepath, 'rb')) + { + return FALSE; + } + + flock($fp, LOCK_SH); + + $cache = ''; + if (filesize($filepath) > 0) + { + $cache = fread($fp, filesize($filepath)); + } + + flock($fp, LOCK_UN); + fclose($fp); + + // Strip out the embedded timestamp + if ( ! preg_match("/(\d+TS--->)/", $cache, $match)) + { + return FALSE; + } + + // Has the file expired? If so we'll delete it. + if (time() >= trim(str_replace('TS--->', '', $match['1']))) + { + @unlink($filepath); + log_message('debug', "Cache file has expired. File deleted"); + return FALSE; + } + + // Display the cache + $this->_display(str_replace($match['0'], '', $cache)); + log_message('debug', "Cache file is current. Sending it to browser."); + return TRUE; + } + + +} +// END Output Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Pagination.php.svn-base b/system/libraries/.svn/text-base/Pagination.php.svn-base new file mode 100644 index 0000000..28b74f1 --- /dev/null +++ b/system/libraries/.svn/text-base/Pagination.php.svn-base @@ -0,0 +1,218 @@ +'; + var $cur_tag_close = ''; + var $next_tag_open = ' '; + var $next_tag_close = ' '; + var $prev_tag_open = ' '; + var $prev_tag_close = ''; + var $num_tag_open = ' '; + var $num_tag_close = ''; + + /** + * Constructor + * + * @access public + * @param array initialization parameters + */ + function CI_Pagination($params = array()) + { + if (count($params) > 0) + { + $this->initialize($params); + } + + log_message('debug', "Pagination Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Preferences + * + * @access public + * @param array initialization parameters + * @return void + */ + function initialize($params = array()) + { + if (count($params) > 0) + { + foreach ($params as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + } + + // -------------------------------------------------------------------- + + /** + * Generate the pagination links + * + * @access public + * @return string + */ + function create_links() + { + // If our item count or per-page total is zero there is no need to continue. + if ($this->total_rows == 0 OR $this->per_page == 0) + { + return ''; + } + + // Calculate the total number of pages + $num_pages = ceil($this->total_rows / $this->per_page); + + // Is there only one page? Hm... nothing more to do here then. + if ($num_pages == 1) + { + return ''; + } + + // Determine the current page number. + $CI =& get_instance(); + if ($CI->uri->segment($this->uri_segment) != 0) + { + $this->cur_page = $CI->uri->segment($this->uri_segment); + + // Prep the current page - no funny business! + $this->cur_page = (int) $this->cur_page; + } + + $this->num_links = (int)$this->num_links; + + if ($this->num_links < 1) + { + show_error('Your number of links must be a positive number.'); + } + + if ( ! is_numeric($this->cur_page)) + { + $this->cur_page = 0; + } + + // Is the page number beyond the result range? + // If so we show the last page + if ($this->cur_page > $this->total_rows) + { + $this->cur_page = ($num_pages - 1) * $this->per_page; + } + + $uri_page_number = $this->cur_page; + $this->cur_page = floor(($this->cur_page/$this->per_page) + 1); + + // Calculate the start and end numbers. These determine + // which number to start and end the digit links with + $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1; + $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages; + + // Add a trailing slash to the base URL if needed + $this->base_url = rtrim($this->base_url, '/') .'/'; + + // And here we go... + $output = ''; + + // Render the "First" link + if ($this->cur_page > $this->num_links) + { + $output .= $this->first_tag_open.''.$this->first_link.''.$this->first_tag_close; + } + + // Render the "previous" link + if ($this->cur_page != 1) + { + $i = $uri_page_number - $this->per_page; + if ($i == 0) $i = ''; + $output .= $this->prev_tag_open.''.$this->prev_link.''.$this->prev_tag_close; + } + + // Write the digit links + for ($loop = $start -1; $loop <= $end; $loop++) + { + $i = ($loop * $this->per_page) - $this->per_page; + + if ($i >= 0) + { + if ($this->cur_page == $loop) + { + $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page + } + else + { + $n = ($i == 0) ? '' : $i; + $output .= $this->num_tag_open.''.$loop.''.$this->num_tag_close; + } + } + } + + // Render the "next" link + if ($this->cur_page < $num_pages) + { + $output .= $this->next_tag_open.''.$this->next_link.''.$this->next_tag_close; + } + + // Render the "Last" link + if (($this->cur_page + $this->num_links) < $num_pages) + { + $i = (($num_pages * $this->per_page) - $this->per_page); + $output .= $this->last_tag_open.''.$this->last_link.''.$this->last_tag_close; + } + + // Kill double slashes. Note: Sometimes we can end up with a double slash + // in the penultimate link so we'll kill all double slashes. + $output = preg_replace("#([^:])//+#", "\\1/", $output); + + // Add the wrapper HTML if exists + $output = $this->full_tag_open.$output.$this->full_tag_close; + + return $output; + } +} +// END Pagination Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Parser.php.svn-base b/system/libraries/.svn/text-base/Parser.php.svn-base new file mode 100644 index 0000000..a0b310f --- /dev/null +++ b/system/libraries/.svn/text-base/Parser.php.svn-base @@ -0,0 +1,171 @@ +load->view($template, $data, TRUE); + + if ($template == '') + { + return FALSE; + } + + foreach ($data as $key => $val) + { + if (is_array($val)) + { + $template = $this->_parse_pair($key, $val, $template); + } + else + { + $template = $this->_parse_single($key, (string)$val, $template); + } + } + + if ($return == FALSE) + { + $CI->output->final_output = $template; + } + + return $template; + } + + // -------------------------------------------------------------------- + + /** + * Set the left/right variable delimiters + * + * @access public + * @param string + * @param string + * @return void + */ + function set_delimiters($l = '{', $r = '}') + { + $this->l_delim = $l; + $this->r_delim = $r; + } + + // -------------------------------------------------------------------- + + /** + * Parse a single key/value + * + * @access private + * @param string + * @param string + * @param string + * @return string + */ + function _parse_single($key, $val, $string) + { + return str_replace($this->l_delim.$key.$this->r_delim, $val, $string); + } + + // -------------------------------------------------------------------- + + /** + * Parse a tag pair + * + * Parses tag pairs: {some_tag} string... {/some_tag} + * + * @access private + * @param string + * @param array + * @param string + * @return string + */ + function _parse_pair($variable, $data, $string) + { + if (FALSE === ($match = $this->_match_pair($string, $variable))) + { + return $string; + } + + $str = ''; + foreach ($data as $row) + { + $temp = $match['1']; + foreach ($row as $key => $val) + { + if ( ! is_array($val)) + { + $temp = $this->_parse_single($key, $val, $temp); + } + else + { + $temp = $this->_parse_pair($key, $val, $temp); + } + } + + $str .= $temp; + } + + return str_replace($match['0'], $str, $string); + } + + // -------------------------------------------------------------------- + + /** + * Matches a variable pair + * + * @access private + * @param string + * @param string + * @return mixed + */ + function _match_pair($string, $variable) + { + if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match)) + { + return FALSE; + } + + return $match; + } + +} +// END Parser Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Profiler.php.svn-base b/system/libraries/.svn/text-base/Profiler.php.svn-base new file mode 100644 index 0000000..8a45933 --- /dev/null +++ b/system/libraries/.svn/text-base/Profiler.php.svn-base @@ -0,0 +1,343 @@ +CI =& get_instance(); + $this->CI->load->language('profiler'); + } + + // -------------------------------------------------------------------- + + /** + * Auto Profiler + * + * This function cycles through the entire array of mark points and + * matches any two points that are named identically (ending in "_start" + * and "_end" respectively). It then compiles the execution times for + * all points and returns it as an array + * + * @access private + * @return array + */ + function _compile_benchmarks() + { + $profile = array(); + foreach ($this->CI->benchmark->marker as $key => $val) + { + // We match the "end" marker so that the list ends + // up in the order that it was defined + if (preg_match("/(.+?)_end/i", $key, $match)) + { + if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start'])) + { + $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key); + } + } + } + + // Build a table containing the profile data. + // Note: At some point we should turn this into a template that can + // be modified. We also might want to make this data available to be logged + + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_benchmarks').'  '; + $output .= "\n"; + $output .= "\n\n\n"; + + foreach ($profile as $key => $val) + { + $key = ucwords(str_replace(array('_', '-'), ' ', $key)); + $output .= "\n"; + } + + $output .= "
    ".$key."  ".$val."
    \n"; + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile Queries + * + * @access private + * @return string + */ + function _compile_queries() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + + if ( ! class_exists('CI_DB_driver')) + { + $output .= '  '.$this->CI->lang->line('profiler_queries').'  '; + $output .= "\n"; + $output .= "\n\n\n"; + $output .="\n"; + } + else + { + $output .= '  '.$this->CI->lang->line('profiler_queries').' ('.count($this->CI->db->queries).')  '; + $output .= "\n"; + $output .= "\n\n
    ".$this->CI->lang->line('profiler_no_db')."
    \n"; + + if (count($this->CI->db->queries) == 0) + { + $output .= "\n"; + } + else + { + $highlight = array('SELECT', 'FROM', 'WHERE', 'AND', 'LEFT JOIN', 'ORDER BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR'); + + foreach ($this->CI->db->queries as $key => $val) + { + $val = htmlspecialchars($val, ENT_QUOTES); + $time = number_format($this->CI->db->query_times[$key], 4); + + foreach ($highlight as $bold) + { + $val = str_replace($bold, ''.$bold.'', $val); + } + + $output .= "\n"; + } + } + } + + $output .= "
    ".$this->CI->lang->line('profiler_no_queries')."
    ".$time."  ".$val."
    \n"; + $output .= "
    "; + + return $output; + } + + + // -------------------------------------------------------------------- + + /** + * Compile $_GET Data + * + * @access private + * @return string + */ + function _compile_get() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_get_data').'  '; + $output .= "\n"; + + if (count($_GET) == 0) + { + $output .= "
    ".$this->CI->lang->line('profiler_no_get')."
    "; + } + else + { + $output .= "\n\n\n"; + + foreach ($_GET as $key => $val) + { + if ( ! is_numeric($key)) + { + $key = "'".$key."'"; + } + + $output .= "\n"; + } + + $output .= "
    $_GET[".$key."]   "; + if (is_array($val)) + { + $output .= "
    " . htmlspecialchars(stripslashes(print_r($val, true))) . "
    "; + } + else + { + $output .= htmlspecialchars(stripslashes($val)); + } + $output .= "
    \n"; + } + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile $_POST Data + * + * @access private + * @return string + */ + function _compile_post() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_post_data').'  '; + $output .= "\n"; + + if (count($_POST) == 0) + { + $output .= "
    ".$this->CI->lang->line('profiler_no_post')."
    "; + } + else + { + $output .= "\n\n\n"; + + foreach ($_POST as $key => $val) + { + if ( ! is_numeric($key)) + { + $key = "'".$key."'"; + } + +// $output .= "\n"; + $output .= "\n"; + } + + $output .= "
    $_POST[".$key."]  ".htmlspecialchars(stripslashes($val))."
    $_POST[".$key."]   "; + if (is_array($val)) + { + $output .= "
    " . htmlspecialchars(stripslashes(print_r($val, true))) . "
    "; + } + else + { + $output .= htmlspecialchars(stripslashes($val)); + } + $output .= "
    \n"; + } + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Show query string + * + * @access private + * @return string + */ + function _compile_uri_string() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_uri_string').'  '; + $output .= "\n"; + + if ($this->CI->uri->uri_string == '') + { + $output .= "
    ".$this->CI->lang->line('profiler_no_uri')."
    "; + } + else + { + $output .= "
    ".$this->CI->uri->uri_string."
    "; + } + + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile memory usage + * + * Display total used memory + * + * @access public + * @return string + */ + function _compile_memory_usage() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_memory_usage').'  '; + $output .= "\n"; + + if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') + { + $output .= "
    ".number_format($usage).' bytes
    '; + } + else + { + $output .= "
    ".$this->CI->lang->line('profiler_no_memory_usage')."
    "; + } + + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Run the Profiler + * + * @access private + * @return string + */ + function run() + { + $output = '
    '; + $output .= "
    "; + + $output .= $this->_compile_memory_usage(); + $output .= $this->_compile_benchmarks(); + $output .= $this->_compile_uri_string(); + $output .= $this->_compile_get(); + $output .= $this->_compile_post(); + $output .= $this->_compile_queries(); + + $output .= '
    '; + + return $output; + } + +} + +// END CI_Profiler class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Router.php.svn-base b/system/libraries/.svn/text-base/Router.php.svn-base new file mode 100644 index 0000000..f6464a3 --- /dev/null +++ b/system/libraries/.svn/text-base/Router.php.svn-base @@ -0,0 +1,377 @@ +config =& load_class('Config'); + $this->uri =& load_class('URI'); + $this->_set_routing(); + log_message('debug', "Router Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Set the route mapping + * + * This function determines what should be served based on the URI request, + * as well as any "routes" that have been set in the routing config file. + * + * @access private + * @return void + */ + function _set_routing() + { + // Are query strings enabled in the config file? + // If so, we're done since segment based URIs are not used with query strings. + if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')])) + { + $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')]))); + + if (isset($_GET[$this->config->item('function_trigger')])) + { + $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')]))); + } + + return; + } + + // Load the routes.php file. + @include(APPPATH.'config/routes'.EXT); + $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route; + unset($route); + + // Set the default controller so we can display it in the event + // the URI doesn't correlated to a valid controller. + $this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']); + + // Fetch the complete URI string + $this->uri->_fetch_uri_string(); + + // Is there a URI string? If not, the default controller specified in the "routes" file will be shown. + if ($this->uri->uri_string == '') + { + if ($this->default_controller === FALSE) + { + show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); + } + + $this->set_class($this->default_controller); + $this->set_method('index'); + $this->_set_request(array($this->default_controller, 'index')); + + // re-index the routed segments array so it starts with 1 rather than 0 + $this->uri->_reindex_segments(); + + log_message('debug', "No URI present. Default controller set."); + return; + } + unset($this->routes['default_controller']); + + // Do we need to remove the URL suffix? + $this->uri->_remove_url_suffix(); + + // Compile the segments into an array + $this->uri->_explode_segments(); + + // Parse any custom routing that may exist + $this->_parse_routes(); + + // Re-index the segment array so that it starts with 1 rather than 0 + $this->uri->_reindex_segments(); + } + + // -------------------------------------------------------------------- + + /** + * Set the Route + * + * This function takes an array of URI segments as + * input, and sets the current class/method + * + * @access private + * @param array + * @param bool + * @return void + */ + function _set_request($segments = array()) + { + $segments = $this->_validate_request($segments); + + if (count($segments) == 0) + { + return; + } + + $this->set_class($segments[0]); + + if (isset($segments[1])) + { + // A scaffolding request. No funny business with the URL + if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding') + { + $this->scaffolding_request = TRUE; + unset($this->routes['scaffolding_trigger']); + } + else + { + // A standard method request + $this->set_method($segments[1]); + } + } + else + { + // This lets the "routed" segment array identify that the default + // index method is being used. + $segments[1] = 'index'; + } + + // Update our "routed" segment array to contain the segments. + // Note: If there is no custom routing, this array will be + // identical to $this->uri->segments + $this->uri->rsegments = $segments; + } + + // -------------------------------------------------------------------- + + /** + * Validates the supplied segments. Attempts to determine the path to + * the controller. + * + * @access private + * @param array + * @return array + */ + function _validate_request($segments) + { + // Does the requested controller exist in the root folder? + if (file_exists(APPPATH.'controllers/'.$segments[0].EXT)) + { + return $segments; + } + + // Is the controller in a sub-folder? + if (is_dir(APPPATH.'controllers/'.$segments[0])) + { + // Set the directory and remove it from the segment array + $this->set_directory($segments[0]); + $segments = array_slice($segments, 1); + + if (count($segments) > 0) + { + // Does the requested controller exist in the sub-folder? + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT)) + { + show_404(); + } + } + else + { + $this->set_class($this->default_controller); + $this->set_method('index'); + + // Does the default controller exist in the sub-folder? + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT)) + { + $this->directory = ''; + return array(); + } + + } + + return $segments; + } + + // Can't find the requested controller... + show_404(); + } + + // -------------------------------------------------------------------- + + /** + * Parse Routes + * + * This function matches any routes that may exist in + * the config/routes.php file against the URI to + * determine if the class/method need to be remapped. + * + * @access private + * @return void + */ + function _parse_routes() + { + // Do we even have any custom routing to deal with? + // There is a default scaffolding trigger, so we'll look just for 1 + if (count($this->routes) == 1) + { + $this->_set_request($this->uri->segments); + return; + } + + // Turn the segment array into a URI string + $uri = implode('/', $this->uri->segments); + $num = count($this->uri->segments); + + // Is there a literal match? If so we're done + if (isset($this->routes[$uri])) + { + $this->_set_request(explode('/', $this->routes[$uri])); + return; + } + + // Loop through the route array looking for wild-cards + foreach ($this->routes as $key => $val) + { + // Convert wild-cards to RegEx + $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); + + // Does the RegEx match? + if (preg_match('#^'.$key.'$#', $uri)) + { + // Do we have a back-reference? + if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) + { + $val = preg_replace('#^'.$key.'$#', $val, $uri); + } + + $this->_set_request(explode('/', $val)); + return; + } + } + + // If we got this far it means we didn't encounter a + // matching route so we'll set the site default route + $this->_set_request($this->uri->segments); + } + + // -------------------------------------------------------------------- + + /** + * Set the class name + * + * @access public + * @param string + * @return void + */ + function set_class($class) + { + $this->class = $class; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current class + * + * @access public + * @return string + */ + function fetch_class() + { + return $this->class; + } + + // -------------------------------------------------------------------- + + /** + * Set the method name + * + * @access public + * @param string + * @return void + */ + function set_method($method) + { + $this->method = $method; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current method + * + * @access public + * @return string + */ + function fetch_method() + { + if ($this->method == $this->fetch_class()) + { + return 'index'; + } + + return $this->method; + } + + // -------------------------------------------------------------------- + + /** + * Set the directory name + * + * @access public + * @param string + * @return void + */ + function set_directory($dir) + { + $this->directory = $dir.'/'; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the sub-directory (if any) that contains the requested controller class + * + * @access public + * @return string + */ + function fetch_directory() + { + return $this->directory; + } + +} +// END Router Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Session.php.svn-base b/system/libraries/.svn/text-base/Session.php.svn-base new file mode 100644 index 0000000..2cdd50c --- /dev/null +++ b/system/libraries/.svn/text-base/Session.php.svn-base @@ -0,0 +1,632 @@ +CI =& get_instance(); + + log_message('debug', "Session Class Initialized"); + $this->sess_run(); + } + + // -------------------------------------------------------------------- + + /** + * Run the session routines + * + * @access public + * @return void + */ + function sess_run() + { + /* + * Set the "now" time + * + * It can either set to GMT or time(). The pref + * is set in the config file. If the developer + * is doing any sort of time localization they + * might want to set the session time to GMT so + * they can offset the "last_activity" time + * based on each user's locale. + * + */ + + if (is_numeric($this->CI->config->item('sess_time_to_update'))) + { + $this->time_to_update = $this->CI->config->item('sess_time_to_update'); + } + + if (strtolower($this->CI->config->item('time_reference')) == 'gmt') + { + $now = time(); + $this->now = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)); + + if (strlen($this->now) < 10) + { + $this->now = time(); + log_message('error', 'The session class could not set a proper GMT timestamp so the local time() value was used.'); + } + } + else + { + $this->now = time(); + } + + /* + * Set the session length + * + * If the session expiration is set to zero in + * the config file we'll set the expiration + * two years from now. + * + */ + $expiration = $this->CI->config->item('sess_expiration'); + + if (is_numeric($expiration)) + { + if ($expiration > 0) + { + $this->sess_length = $this->CI->config->item('sess_expiration'); + } + else + { + $this->sess_length = (60*60*24*365*2); + } + } + + // Do we need encryption? + $this->encryption = $this->CI->config->item('sess_encrypt_cookie'); + + if ($this->encryption == TRUE) + { + $this->CI->load->library('encrypt'); + } + + // Are we using a database? + if ($this->CI->config->item('sess_use_database') === TRUE AND $this->CI->config->item('sess_table_name') != '') + { + $this->use_database = TRUE; + $this->session_table = $this->CI->config->item('sess_table_name'); + $this->CI->load->database(); + } + + // Set the cookie name + if ($this->CI->config->item('sess_cookie_name') != FALSE) + { + $this->sess_cookie = $this->CI->config->item('cookie_prefix').$this->CI->config->item('sess_cookie_name'); + } + + /* + * Fetch the current session + * + * If a session doesn't exist we'll create + * a new one. If it does, we'll update it. + * + */ + if ( ! $this->sess_read()) + { + $this->sess_create(); + } + else + { + // We only update the session every five minutes + if (($this->userdata['last_activity'] + $this->time_to_update) < $this->now) + { + $this->sess_update(); + } + } + + // Delete expired sessions if necessary + if ($this->use_database === TRUE) + { + $this->sess_gc(); + } + + // Delete 'old' flashdata (from last request) + $this->_flashdata_sweep(); + + // Mark all new flashdata as old (data will be deleted before next request) + $this->_flashdata_mark(); + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current session data if it exists + * + * @access public + * @return void + */ + function sess_read() + { + // Fetch the cookie + $session = $this->CI->input->cookie($this->sess_cookie); + + if ($session === FALSE) + { + log_message('debug', 'A session cookie was not found.'); + return FALSE; + } + + // Decrypt and unserialize the data + if ($this->encryption == TRUE) + { + $session = $this->CI->encrypt->decode($session); + } + + $session = @unserialize($this->strip_slashes($session)); + + if ( ! is_array($session) OR ! isset($session['last_activity'])) + { + log_message('error', 'The session cookie data did not contain a valid array. This could be a possible hacking attempt.'); + return FALSE; + } + + // Is the session current? + if (($session['last_activity'] + $this->sess_length) < $this->now) + { + $this->sess_destroy(); + return FALSE; + } + + // Does the IP Match? + if ($this->CI->config->item('sess_match_ip') == TRUE AND $session['ip_address'] != $this->CI->input->ip_address()) + { + $this->sess_destroy(); + return FALSE; + } + + // Does the User Agent Match? + if ($this->CI->config->item('sess_match_useragent') == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))) + { + $this->sess_destroy(); + return FALSE; + } + + // Is there a corresponding session in the DB? + if ($this->use_database === TRUE) + { + $this->CI->db->where('session_id', $session['session_id']); + + if ($this->CI->config->item('sess_match_ip') == TRUE) + { + $this->CI->db->where('ip_address', $session['ip_address']); + } + + if ($this->CI->config->item('sess_match_useragent') == TRUE) + { + $this->CI->db->where('user_agent', $session['user_agent']); + } + + $query = $this->CI->db->get($this->session_table); + + if ($query->num_rows() == 0) + { + $this->sess_destroy(); + return FALSE; + } + else + { + $row = $query->row(); + if (($row->last_activity + $this->sess_length) < $this->now) + { + $this->CI->db->where('session_id', $session['session_id']); + $this->CI->db->delete($this->session_table); + $this->sess_destroy(); + return FALSE; + } + } + } + + // Session is valid! + $this->userdata = $session; + unset($session); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Write the session cookie + * + * @access public + * @return void + */ + function sess_write() + { + $cookie_data = serialize($this->userdata); + + if ($this->encryption == TRUE) + { + $cookie_data = $this->CI->encrypt->encode($cookie_data); + } + + setcookie( + $this->sess_cookie, + $cookie_data, + $this->sess_length + time(), + $this->CI->config->item('cookie_path'), + $this->CI->config->item('cookie_domain'), + 0 + ); + } + + // -------------------------------------------------------------------- + + /** + * Create a new session + * + * @access public + * @return void + */ + function sess_create() + { + $sessid = ''; + while (strlen($sessid) < 32) + { + $sessid .= mt_rand(0, mt_getrandmax()); + } + + $this->userdata = array( + 'session_id' => md5(uniqid($sessid, TRUE)), + 'ip_address' => $this->CI->input->ip_address(), + 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), + 'last_activity' => $this->now + ); + + + // Save the session in the DB if needed + if ($this->use_database === TRUE) + { + $this->CI->db->query($this->CI->db->insert_string($this->session_table, $this->userdata)); + } + + // Write the cookie + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Update an existing session + * + * @access public + * @return void + */ + function sess_update() + { + // Save the old session id so we know which record to + // update in the database if we need it + $old_sessid = $this->userdata['session_id']; + $new_sessid = ''; + while (strlen($new_sessid) < 32) + { + $new_sessid .= mt_rand(0, mt_getrandmax()); + } + $new_sessid = md5(uniqid($new_sessid, TRUE)); + + // Update the session data in the session data array + $this->userdata['session_id'] = $new_sessid; + $this->userdata['last_activity'] = $this->now; + + // Update the session in the DB if needed + if ($this->use_database === TRUE) + { + $this->CI->db->query($this->CI->db->update_string($this->session_table, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid))); + } + + // Write the cookie + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Destroy the current session + * + * @access public + * @return void + */ + function sess_destroy() + { + setcookie( + $this->sess_cookie, + addslashes(serialize(array())), + ($this->now - 31500000), + $this->CI->config->item('cookie_path'), + $this->CI->config->item('cookie_domain'), + 0 + ); + } + + // -------------------------------------------------------------------- + + /** + * Garbage collection + * + * This deletes expired session rows from database + * if the probability percentage is met + * + * @access public + * @return void + */ + function sess_gc() + { + srand(time()); + if ((rand() % 100) < $this->gc_probability) + { + $expire = $this->now - $this->sess_length; + + $this->CI->db->where("last_activity < {$expire}"); + $this->CI->db->delete($this->session_table); + + log_message('debug', 'Session garbage collection performed.'); + } + } + + // -------------------------------------------------------------------- + + /** + * Fetch a specific item from the session array + * + * @access public + * @param string + * @return string + */ + function userdata($item) + { + return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch all session data + * + * @access public + * @return mixed + */ + function all_userdata() + { + return ( ! isset($this->userdata)) ? FALSE : $this->userdata; + } + + // -------------------------------------------------------------------- + + /** + * Add or change data in the "userdata" array + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_userdata($newdata = array(), $newval = '') + { + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $this->userdata[$key] = $val; + } + } + + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Delete a session variable from the "userdata" array + * + * @access array + * @return void + */ + function unset_userdata($newdata = array()) + { + if (is_string($newdata)) + { + $newdata = array($newdata => ''); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + unset($this->userdata[$key]); + } + } + + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Strip slashes + * + * @access public + * @param mixed + * @return mixed + */ + function strip_slashes($vals) + { + if (is_array($vals)) + { + foreach ($vals as $key=>$val) + { + $vals[$key] = $this->strip_slashes($val); + } + } + else + { + $vals = stripslashes($vals); + } + + return $vals; + } + + + // ------------------------------------------------------------------------ + + /** + * Add or change flashdata, only available + * until the next request + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_flashdata($newdata = array(), $newval = '') + { + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $flashdata_key = $this->flashdata_key.':new:'.$key; + $this->set_userdata($flashdata_key, $val); + } + } + } + + // ------------------------------------------------------------------------ + + /** + * Keeps existing flashdata available to next request. + * + * @access public + * @param string + * @return void + */ + function keep_flashdata($key) + { + // 'old' flashdata gets removed. Here we mark all + // flashdata as 'new' to preserve it from _flashdata_sweep() + // Note the function will return FALSE if the $key + // provided cannot be found + $old_flashdata_key = $this->flashdata_key.':old:'.$key; + $value = $this->userdata($old_flashdata_key); + + $new_flashdata_key = $this->flashdata_key.':new:'.$key; + $this->set_userdata($new_flashdata_key, $value); + } + + // ------------------------------------------------------------------------ + + /** + * Fetch a specific flashdata item from the session array + * + * @access public + * @param string + * @return string + */ + function flashdata($key) + { + $flashdata_key = $this->flashdata_key.':old:'.$key; + return $this->userdata($flashdata_key); + } + + // ------------------------------------------------------------------------ + + /** + * Identifies flashdata as 'old' for removal + * when _flashdata_sweep() runs. + * + * @access private + * @return void + */ + function _flashdata_mark() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $name => $value) + { + $parts = explode(':new:', $name); + if (is_array($parts) && count($parts) === 2) + { + $new_name = $this->flashdata_key.':old:'.$parts[1]; + $this->set_userdata($new_name, $value); + $this->unset_userdata($name); + } + } + } + + // ------------------------------------------------------------------------ + + /** + * Removes all flashdata marked as 'old' + * + * @access private + * @return void + */ + + function _flashdata_sweep() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $key => $value) + { + if (strpos($key, ':old:')) + { + $this->unset_userdata($key); + } + } + + } + +} +// END Session Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Sha1.php.svn-base b/system/libraries/.svn/text-base/Sha1.php.svn-base new file mode 100644 index 0000000..6bb8911 --- /dev/null +++ b/system/libraries/.svn/text-base/Sha1.php.svn-base @@ -0,0 +1,249 @@ +> 6) + 1; + + for ($i = 0; $i < $n * 16; $i++) + { + $x[$i] = 0; + } + + for ($i = 0; $i < strlen($str); $i++) + { + $x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8); + } + + $x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8); + + $x[$n * 16 - 1] = strlen($str) * 8; + + $a = 1732584193; + $b = -271733879; + $c = -1732584194; + $d = 271733878; + $e = -1009589776; + + for ($i = 0; $i < sizeof($x); $i += 16) + { + $olda = $a; + $oldb = $b; + $oldc = $c; + $oldd = $d; + $olde = $e; + + for($j = 0; $j < 80; $j++) + { + if ($j < 16) + { + $w[$j] = $x[$i + $j]; + } + else + { + $w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1); + } + + $t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j))); + + $e = $d; + $d = $c; + $c = $this->_rol($b, 30); + $b = $a; + $a = $t; + } + + $a = $this->_safe_add($a, $olda); + $b = $this->_safe_add($b, $oldb); + $c = $this->_safe_add($c, $oldc); + $d = $this->_safe_add($d, $oldd); + $e = $this->_safe_add($e, $olde); + } + + return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e); + } + + // -------------------------------------------------------------------- + + /** + * Convert a decimal to hex + * + * @access private + * @param string + * @return string + */ + function _hex($str) + { + $str = dechex($str); + + if (strlen($str) == 7) + { + $str = '0'.$str; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Return result based on iteration + * + * @access private + * @return string + */ + function _ft($t, $b, $c, $d) + { + if ($t < 20) + return ($b & $c) | ((~$b) & $d); + if ($t < 40) + return $b ^ $c ^ $d; + if ($t < 60) + return ($b & $c) | ($b & $d) | ($c & $d); + + return $b ^ $c ^ $d; + } + + // -------------------------------------------------------------------- + + /** + * Determine the additive constant + * + * @access private + * @return string + */ + function _kt($t) + { + if ($t < 20) + { + return 1518500249; + } + else if ($t < 40) + { + return 1859775393; + } + else if ($t < 60) + { + return -1894007588; + } + else + { + return -899497514; + } + } + + // -------------------------------------------------------------------- + + /** + * Add integers, wrapping at 2^32 + * + * @access private + * @return string + */ + function _safe_add($x, $y) + { + $lsw = ($x & 0xFFFF) + ($y & 0xFFFF); + $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16); + + return ($msw << 16) | ($lsw & 0xFFFF); + } + + // -------------------------------------------------------------------- + + /** + * Bitwise rotate a 32-bit number + * + * @access private + * @return integer + */ + function _rol($num, $cnt) + { + return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt); + } + + // -------------------------------------------------------------------- + + /** + * Pad string with zero + * + * @access private + * @return string + */ + function _zero_fill($a, $b) + { + $bin = decbin($a); + + if (strlen($bin) < $b) + { + $bin = 0; + } + else + { + $bin = substr($bin, 0, strlen($bin) - $b); + } + + for ($i=0; $i < $b; $i++) + { + $bin = "0".$bin; + } + + return bindec($bin); + } +} +// END CI_SHA +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Table.php.svn-base b/system/libraries/.svn/text-base/Table.php.svn-base new file mode 100644 index 0000000..d1c5254 --- /dev/null +++ b/system/libraries/.svn/text-base/Table.php.svn-base @@ -0,0 +1,439 @@ +template = $template; + } + + // -------------------------------------------------------------------- + + /** + * Set the table heading + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function set_heading() + { + $args = func_get_args(); + $this->heading = (is_array($args[0])) ? $args[0] : $args; + } + + // -------------------------------------------------------------------- + + /** + * Set columns. Takes a one-dimensional array as input and creates + * a multi-dimensional array with a depth equal to the number of + * columns. This allows a single array with many elements to be + * displayed in a table that has a fixed column count. + * + * @access public + * @param array + * @param int + * @return void + */ + function make_columns($array = array(), $col_limit = 0) + { + if ( ! is_array($array) OR count($array) == 0) + { + return FALSE; + } + + // Turn off the auto-heading feature since it's doubtful we + // will want headings from a one-dimensional array + $this->auto_heading = FALSE; + + if ($col_limit == 0) + { + return $array; + } + + $new = array(); + while(count($array) > 0) + { + $temp = array_slice($array, 0, $col_limit); + $array = array_diff($array, $temp); + + if (count($temp) < $col_limit) + { + for ($i = count($temp); $i < $col_limit; $i++) + { + $temp[] = ' '; + } + } + + $new[] = $temp; + } + + return $new; + } + + // -------------------------------------------------------------------- + + /** + * Set "empty" cells + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function set_empty($value) + { + $this->empty_cells = $value; + } + + // -------------------------------------------------------------------- + + /** + * Add a table row + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function add_row() + { + $args = func_get_args(); + $this->rows[] = (is_array($args[0])) ? $args[0] : $args; + } + + // -------------------------------------------------------------------- + + /** + * Add a table caption + * + * @access public + * @param string + * @return void + */ + function set_caption($caption) + { + $this->caption = $caption; + } + + // -------------------------------------------------------------------- + + /** + * Generate the table + * + * @access public + * @param mixed + * @return string + */ + function generate($table_data = NULL) + { + // The table data can optionally be passed to this function + // either as a database result object or an array + if ( ! is_null($table_data)) + { + if (is_object($table_data)) + { + $this->_set_from_object($table_data); + } + elseif (is_array($table_data)) + { + $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE; + $this->_set_from_array($table_data, $set_heading); + } + } + + // Is there anything to display? No? Smite them! + if (count($this->heading) == 0 AND count($this->rows) == 0) + { + return 'Undefined table data'; + } + + // Compile and validate the template date + $this->_compile_template(); + + + // Build the table! + + $out = $this->template['table_open']; + $out .= $this->newline; + + // Add any caption here + if ($this->caption) + { + $out .= $this->newline; + $out .= '' . $this->caption . ''; + $out .= $this->newline; + } + + // Is there a table heading to display? + if (count($this->heading) > 0) + { + $out .= $this->template['heading_row_start']; + $out .= $this->newline; + + foreach($this->heading as $heading) + { + $out .= $this->template['heading_cell_start']; + $out .= $heading; + $out .= $this->template['heading_cell_end']; + } + + $out .= $this->template['heading_row_end']; + $out .= $this->newline; + } + + // Build the table rows + if (count($this->rows) > 0) + { + $i = 1; + foreach($this->rows as $row) + { + if ( ! is_array($row)) + { + break; + } + + // We use modulus to alternate the row colors + $name = (fmod($i++, 2)) ? '' : 'alt_'; + + $out .= $this->template['row_'.$name.'start']; + $out .= $this->newline; + + foreach($row as $cell) + { + $out .= $this->template['cell_'.$name.'start']; + + if ($cell == "") + { + $out .= $this->empty_cells; + } + else + { + $out .= $cell; + } + + $out .= $this->template['cell_'.$name.'end']; + } + + $out .= $this->template['row_'.$name.'end']; + $out .= $this->newline; + } + } + + $out .= $this->template['table_close']; + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Clears the table arrays. Useful if multiple tables are being generated + * + * @access public + * @return void + */ + function clear() + { + $this->rows = array(); + $this->heading = array(); + $this->auto_heading = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set table data from a database result object + * + * @access public + * @param object + * @return void + */ + function _set_from_object($query) + { + if ( ! is_object($query)) + { + return FALSE; + } + + // First generate the headings from the table column names + if (count($this->heading) == 0) + { + if ( ! method_exists($query, 'list_fields')) + { + return FALSE; + } + + $this->heading = $query->list_fields(); + } + + // Next blast through the result array and build out the rows + + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $this->rows[] = $row; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set table data from an array + * + * @access public + * @param array + * @return void + */ + function _set_from_array($data, $set_heading = TRUE) + { + if ( ! is_array($data) OR count($data) == 0) + { + return FALSE; + } + + $i = 0; + foreach ($data as $row) + { + if ( ! is_array($row)) + { + $this->rows[] = $data; + break; + } + + // If a heading hasn't already been set we'll use the first row of the array as the heading + if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE) + { + $this->heading = $row; + } + else + { + $this->rows[] = $row; + } + + $i++; + } + } + + // -------------------------------------------------------------------- + + /** + * Compile Template + * + * @access private + * @return void + */ + function _compile_template() + { + if ($this->template == NULL) + { + $this->template = $this->_default_template(); + return; + } + + $this->temp = $this->_default_template(); + foreach (array('table_open','heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val) + { + if ( ! isset($this->template[$val])) + { + $this->template[$val] = $this->temp[$val]; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Default Template + * + * @access private + * @return void + */ + function _default_template() + { + return array ( + 'table_open' => '', + + 'heading_row_start' => '', + 'heading_row_end' => '', + 'heading_cell_start' => '', + + 'row_start' => '', + 'row_end' => '', + 'cell_start' => '', + + 'row_alt_start' => '', + 'row_alt_end' => '', + 'cell_alt_start' => '', + + 'table_close' => '
    ', + 'heading_cell_end' => '
    ', + 'cell_end' => '
    ', + 'cell_alt_end' => '
    ' + ); + } + + +} + +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Trackback.php.svn-base b/system/libraries/.svn/text-base/Trackback.php.svn-base new file mode 100644 index 0000000..5371e90 --- /dev/null +++ b/system/libraries/.svn/text-base/Trackback.php.svn-base @@ -0,0 +1,548 @@ + '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => ''); + var $convert_ascii = TRUE; + var $response = ''; + var $error_msg = array(); + + /** + * Constructor + * + * @access public + */ + function CI_Trackback() + { + log_message('debug', "Trackback Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback + * + * @access public + * @param array + * @return bool + */ + function send($tb_data) + { + if ( ! is_array($tb_data)) + { + $this->set_error('The send() method must be passed an array'); + return FALSE; + } + + // Pre-process the Trackback Data + foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item) + { + if ( ! isset($tb_data[$item])) + { + $this->set_error('Required item missing: '.$item); + return FALSE; + } + + switch ($item) + { + case 'ping_url' : $$item = $this->extract_urls($tb_data[$item]); + break; + case 'excerpt' : $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); + break; + case 'url' : $$item = str_replace('-', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); + break; + default : $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))); + break; + } + + // Convert High ASCII Characters + if ($this->convert_ascii == TRUE) + { + if ($item == 'excerpt') + { + $$item = $this->convert_ascii($$item); + } + elseif ($item == 'title') + { + $$item = $this->convert_ascii($$item); + } + elseif($item == 'blog_name') + { + $$item = $this->convert_ascii($$item); + } + } + } + + // Build the Trackback data string + $charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset']; + + $data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset); + + // Send Trackback(s) + $return = TRUE; + if (count($ping_url) > 0) + { + foreach ($ping_url as $url) + { + if ($this->process($url, $data) == FALSE) + { + $return = FALSE; + } + } + } + + return $return; + } + + // -------------------------------------------------------------------- + + /** + * Receive Trackback Data + * + * This function simply validates the incoming TB data. + * It returns false on failure and true on success. + * If the data is valid it is set to the $this->data array + * so that it can be inserted into a database. + * + * @access public + * @return bool + */ + function receive() + { + foreach (array('url', 'title', 'blog_name', 'excerpt') as $val) + { + if ( ! isset($_POST[$val]) OR $_POST[$val] == '') + { + $this->set_error('The following required POST variable is missing: '.$val); + return FALSE; + } + + $this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset'])); + + if ($val != 'url' && function_exists('mb_convert_encoding')) + { + $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']); + } + + $_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]); + + if ($val == 'excerpt') + { + $_POST['excerpt'] = $this->limit_characters($_POST['excerpt']); + } + + $this->data[$val] = $_POST[$val]; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback Error Message + * + * Allows custom errors to be set. By default it + * sends the "incomplete information" error, as that's + * the most common one. + * + * @access public + * @param string + * @return void + */ + function send_error($message = 'Incomplete Information') + { + echo "\n\n1\n".$message."\n"; + exit; + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback Success Message + * + * This should be called when a trackback has been + * successfully received and inserted. + * + * @access public + * @return void + */ + function send_success() + { + echo "\n\n0\n"; + exit; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a particular item + * + * @access public + * @param string + * @return string + */ + function data($item) + { + return ( ! isset($this->data[$item])) ? '' : $this->data[$item]; + } + + // -------------------------------------------------------------------- + + /** + * Process Trackback + * + * Opens a socket connection and passes the data to + * the server. Returns true on success, false on failure + * + * @access public + * @param string + * @param string + * @return bool + */ + function process($url, $data) + { + $target = parse_url($url); + + // Open the socket + if ( ! $fp = @fsockopen($target['host'], 80)) + { + $this->set_error('Invalid Connection: '.$url); + return FALSE; + } + + // Build the path + $ppath = ( ! isset($target['path'])) ? $url : $target['path']; + + $path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath; + + // Add the Trackback ID to the data string + if ($id = $this->get_id($url)) + { + $data = "tb_id=".$id."&".$data; + } + + // Transfer the data + fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" ); + fputs ($fp, "Host: " . $target['host'] . "\r\n" ); + fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" ); + fputs ($fp, "Content-length: " . strlen($data) . "\r\n" ); + fputs ($fp, "Connection: close\r\n\r\n" ); + fputs ($fp, $data); + + // Was it successful? + $this->response = ""; + + while(!feof($fp)) + { + $this->response .= fgets($fp, 128); + } + @fclose($fp); + + if ( ! eregi("0", $this->response)) + { + $message = 'An unknown error was encountered'; + + if (preg_match("/(.*?)<\/message>/is", $this->response, $match)) + { + $message = trim($match['1']); + } + + $this->set_error($message); + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Extract Trackback URLs + * + * This function lets multiple trackbacks be sent. + * It takes a string of URLs (separated by comma or + * space) and puts each URL into an array + * + * @access public + * @param string + * @return string + */ + function extract_urls($urls) + { + // Remove the pesky white space and replace with a comma. + $urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls); + + // If they use commas get rid of the doubles. + $urls = str_replace(",,", ",", $urls); + + // Remove any comma that might be at the end + if (substr($urls, -1) == ",") + { + $urls = substr($urls, 0, -1); + } + + // Break into an array via commas + $urls = preg_split('/[,]/', $urls); + + // Removes duplicates + $urls = array_unique($urls); + + array_walk($urls, array($this, 'validate_url')); + + return $urls; + } + + // -------------------------------------------------------------------- + + /** + * Validate URL + * + * Simply adds "http://" if missing + * + * @access public + * @param string + * @return string + */ + function validate_url($url) + { + $url = trim($url); + + if (substr($url, 0, 4) != "http") + { + $url = "http://".$url; + } + } + + // -------------------------------------------------------------------- + + /** + * Find the Trackback URL's ID + * + * @access public + * @param string + * @return string + */ + function get_id($url) + { + $tb_id = ""; + + if (strstr($url, '?')) + { + $tb_array = explode('/', $url); + $tb_end = $tb_array[count($tb_array)-1]; + + if ( ! is_numeric($tb_end)) + { + $tb_end = $tb_array[count($tb_array)-2]; + } + + $tb_array = explode('=', $tb_end); + $tb_id = $tb_array[count($tb_array)-1]; + } + else + { + if (ereg("/$", $url)) + { + $url = substr($url, 0, -1); + } + + $tb_array = explode('/', $url); + $tb_id = $tb_array[count($tb_array)-1]; + + if ( ! is_numeric($tb_id)) + { + $tb_id = $tb_array[count($tb_array)-2]; + } + } + + if ( ! preg_match ("/^([0-9]+)$/", $tb_id)) + { + return false; + } + else + { + return $tb_id; + } + } + + // -------------------------------------------------------------------- + + /** + * Convert Reserved XML characters to Entities + * + * @access public + * @param string + * @return string + */ + function convert_xml($str) + { + $temp = '__TEMP_AMPERSANDS__'; + + $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); + $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); + + $str = str_replace(array("&","<",">","\"", "'", "-"), + array("&", "<", ">", """, "'", "-"), + $str); + + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;", $str); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Character limiter + * + * Limits the string based on the character count. Will preserve complete words. + * + * @access public + * @param string + * @param integer + * @param string + * @return string + */ + function limit_characters($str, $n = 500, $end_char = '…') + { + if (strlen($str) < $n) + { + return $str; + } + + $str = preg_replace("/\s+/", ' ', preg_replace("/(\r\n|\r|\n)/", " ", $str)); + + if (strlen($str) <= $n) + { + return $str; + } + + $out = ""; + foreach (explode(' ', trim($str)) as $val) + { + $out .= $val.' '; + if (strlen($out) >= $n) + { + return trim($out).$end_char; + } + } + } + + // -------------------------------------------------------------------- + + /** + * High ASCII to Entities + * + * Converts Hight ascii text and MS Word special chars + * to character entities + * + * @access public + * @param string + * @return string + */ + function convert_ascii($str) + { + $count = 1; + $out = ''; + $temp = array(); + + for ($i = 0, $s = strlen($str); $i < $s; $i++) + { + $ordinal = ord($str[$i]); + + if ($ordinal < 128) + { + $out .= $str[$i]; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + + $out .= '&#'.$number.';'; + $count = 1; + $temp = array(); + } + } + } + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Set error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + log_message('error', $msg); + $this->error_msg[] = $msg; + } + + // -------------------------------------------------------------------- + + /** + * Show error messages + * + * @access public + * @param string + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + +} +// END Trackback Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/URI.php.svn-base b/system/libraries/.svn/text-base/URI.php.svn-base new file mode 100644 index 0000000..aecf051 --- /dev/null +++ b/system/libraries/.svn/text-base/URI.php.svn-base @@ -0,0 +1,588 @@ +config =& load_class('Config'); + log_message('debug', "URI Class Initialized"); + } + + + // -------------------------------------------------------------------- + + /** + * Get the URI String + * + * @access private + * @return string + */ + function _fetch_uri_string() + { + if (strtoupper($this->config->item('uri_protocol')) == 'AUTO') + { + // If the URL has a question mark then it's simplest to just + // build the URI string from the zero index of the $_GET array. + // This avoids having to deal with $_SERVER variables, which + // can be unreliable in some environments + if (is_array($_GET) AND count($_GET) == 1) + { + $this->uri_string = key($_GET); + return; + } + + // Is there a PATH_INFO variable? + // Note: some servers seem to have trouble with getenv() so we'll test it two ways + $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); + if ($path != '' AND $path != '/' AND $path != "/".SELF) + { + $this->uri_string = $path; + return; + } + + // No PATH_INFO?... What about QUERY_STRING? + $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + if ($path != '' AND $path != '/') + { + $this->uri_string = $path; + return; + } + + // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists? + $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'); + if ($path != '' AND $path != '/' AND $path != "/".SELF) + { + $this->uri_string = $path; + return; + } + + // We've exhausted all our options... + $this->uri_string = ''; + } + else + { + $uri = strtoupper($this->config->item('uri_protocol')); + + if ($uri == 'REQUEST_URI') + { + $this->uri_string = $this->_parse_request_uri(); + return; + } + + $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); + } + + // If the URI contains only a slash we'll kill it + if ($this->uri_string == '/') + { + $this->uri_string = ''; + } + } + + // -------------------------------------------------------------------- + + /** + * Parse the REQUEST_URI + * + * Due to the way REQUEST_URI works it usually contains path info + * that makes it unusable as URI data. We'll trim off the unnecessary + * data, hopefully arriving at a valid URI that we can use. + * + * @access private + * @return string + */ + function _parse_request_uri() + { + if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '') + { + return ''; + } + + $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI'])); + + if ($request_uri == '' OR $request_uri == SELF) + { + return ''; + } + + $fc_path = FCPATH; + if (strpos($request_uri, '?') !== FALSE) + { + $fc_path .= '?'; + } + + $parsed_uri = explode("/", $request_uri); + + $i = 0; + foreach(explode("/", $fc_path) as $segment) + { + if (isset($parsed_uri[$i]) AND $segment == $parsed_uri[$i]) + { + $i++; + } + } + + $parsed_uri = implode("/", array_slice($parsed_uri, $i)); + + if ($parsed_uri != '') + { + $parsed_uri = '/'.$parsed_uri; + } + + return $parsed_uri; + } + + // -------------------------------------------------------------------- + + /** + * Filter segments for malicious characters + * + * @access private + * @param string + * @return string + */ + function _filter_uri($str) + { + if ($str != '' AND $this->config->item('permitted_uri_chars') != '') + { + if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str)) + { + exit('The URI you submitted has disallowed characters.'); + } + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Remove the suffix from the URL if needed + * + * @access private + * @return void + */ + function _remove_url_suffix() + { + if ($this->config->item('url_suffix') != "") + { + $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string); + } + } + + // -------------------------------------------------------------------- + + /** + * Explode the URI Segments. The individual segments will + * be stored in the $this->segments array. + * + * @access private + * @return void + */ + function _explode_segments() + { + foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) + { + // Filter segments for security + $val = trim($this->_filter_uri($val)); + + if ($val != '') + $this->segments[] = $val; + } + } + + // -------------------------------------------------------------------- + /** + * Re-index Segments + * + * This function re-indexes the $this->segment array so that it + * starts at 1 rather then 0. Doing so makes it simpler to + * use functions like $this->uri->segment(n) since there is + * a 1:1 relationship between the segment array and the actual segments. + * + * @access private + * @return void + */ + function _reindex_segments() + { + $i = 1; + + foreach ($this->segments as $val) + { + $this->segments[$i++] = $val; + } + + unset($this->segments[0]); + + $i = 1; + + foreach ($this->rsegments as $val) + { + $this->rsegments[$i++] = $val; + } + + unset($this->rsegments[0]); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment + * + * This function returns the URI segment based on the number provided. + * + * @access public + * @param integer + * @param bool + * @return string + */ + function segment($n, $no_result = FALSE) + { + return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI "routed" Segment + * + * This function returns the re-routed URI segment (assuming routing rules are used) + * based on the number provided. If there is no routing this function returns the + * same result as $this->segment() + * + * @access public + * @param integer + * @param bool + * @return string + */ + function rsegment($n, $no_result = FALSE) + { + return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n]; + } + + // -------------------------------------------------------------------- + + /** + * Generate a key value pair from the URI string + * + * This function generates and associative array of URI data starting + * at the supplied segment. For example, if this is your URI: + * + * www.your-site.com/user/search/name/joe/location/UK/gender/male + * + * You can use this function to generate an array with this prototype: + * + * array ( + * name => joe + * location => UK + * gender => male + * ) + * + * @access public + * @param integer the starting segment number + * @param array an array of default values + * @return array + */ + function uri_to_assoc($n = 3, $default = array()) + { + return $this->_uri_to_assoc($n, $default, 'segment'); + } + /** + * Identical to above only it uses the re-routed segment array + * + */ + function ruri_to_assoc($n = 3, $default = array()) + { + return $this->_uri_to_assoc($n, $default, 'rsegment'); + } + + // -------------------------------------------------------------------- + + /** + * Generate a key value pair from the URI string or Re-routed URI string + * + * @access private + * @param integer the starting segment number + * @param array an array of default values + * @param string which array we should use + * @return array + */ + function _uri_to_assoc($n = 3, $default = array(), $which = 'segment') + { + if ($which == 'segment') + { + $total_segments = 'total_segments'; + $segment_array = 'segment_array'; + } + else + { + $total_segments = 'total_rsegments'; + $segment_array = 'rsegment_array'; + } + + if ( ! is_numeric($n)) + { + return $default; + } + + if (isset($this->keyval[$n])) + { + return $this->keyval[$n]; + } + + if ($this->$total_segments() < $n) + { + if (count($default) == 0) + { + return array(); + } + + $retval = array(); + foreach ($default as $val) + { + $retval[$val] = FALSE; + } + return $retval; + } + + $segments = array_slice($this->$segment_array(), ($n - 1)); + + $i = 0; + $lastval = ''; + $retval = array(); + foreach ($segments as $seg) + { + if ($i % 2) + { + $retval[$lastval] = $seg; + } + else + { + $retval[$seg] = FALSE; + $lastval = $seg; + } + + $i++; + } + + if (count($default) > 0) + { + foreach ($default as $val) + { + if ( ! array_key_exists($val, $retval)) + { + $retval[$val] = FALSE; + } + } + } + + // Cache the array for reuse + $this->keyval[$n] = $retval; + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Generate a URI string from an associative array + * + * + * @access public + * @param array an associative array of key/values + * @return array + */ + function assoc_to_uri($array) + { + $temp = array(); + foreach ((array)$array as $key => $val) + { + $temp[] = $key; + $temp[] = $val; + } + + return implode('/', $temp); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash + * + * @access public + * @param integer + * @param string + * @return string + */ + function slash_segment($n, $where = 'trailing') + { + return $this->_slash_segment($n, $where, 'segment'); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash + * + * @access public + * @param integer + * @param string + * @return string + */ + function slash_rsegment($n, $where = 'trailing') + { + return $this->_slash_segment($n, $where, 'rsegment'); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash - helper function + * + * @access private + * @param integer + * @param string + * @param string + * @return string + */ + function _slash_segment($n, $where = 'trailing', $which = 'segment') + { + if ($where == 'trailing') + { + $trailing = '/'; + $leading = ''; + } + elseif ($where == 'leading') + { + $leading = '/'; + $trailing = ''; + } + else + { + $leading = '/'; + $trailing = '/'; + } + return $leading.$this->$which($n).$trailing; + } + + // -------------------------------------------------------------------- + + /** + * Segment Array + * + * @access public + * @return array + */ + function segment_array() + { + return $this->segments; + } + + // -------------------------------------------------------------------- + + /** + * Routed Segment Array + * + * @access public + * @return array + */ + function rsegment_array() + { + return $this->rsegments; + } + + // -------------------------------------------------------------------- + + /** + * Total number of segments + * + * @access public + * @return integer + */ + function total_segments() + { + return count($this->segments); + } + + // -------------------------------------------------------------------- + + /** + * Total number of routed segments + * + * @access public + * @return integer + */ + function total_rsegments() + { + return count($this->rsegments); + } + + // -------------------------------------------------------------------- + + /** + * Fetch the entire URI string + * + * @access public + * @return string + */ + function uri_string() + { + return $this->uri_string; + } + + + // -------------------------------------------------------------------- + + /** + * Fetch the entire Re-routed URI string + * + * @access public + * @return string + */ + function ruri_string() + { + return '/'.implode('/', $this->rsegment_array()).'/'; + } + +} +// END URI Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Unit_test.php.svn-base b/system/libraries/.svn/text-base/Unit_test.php.svn-base new file mode 100644 index 0000000..33a8f31 --- /dev/null +++ b/system/libraries/.svn/text-base/Unit_test.php.svn-base @@ -0,0 +1,331 @@ +active == FALSE) + return FALSE; + + if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE)) + { + $expected = str_replace('is_float', 'is_double', $expected); + $result = ($expected($test)) ? TRUE : FALSE; + $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected)); + } + else + { + if ($this->strict == TRUE) + $result = ($test === $expected) ? TRUE : FALSE; + else + $result = ($test == $expected) ? TRUE : FALSE; + + $extype = gettype($expected); + } + + $back = $this->_backtrace(); + + $report[] = array ( + 'test_name' => $test_name, + 'test_datatype' => gettype($test), + 'res_datatype' => $extype, + 'result' => ($result === TRUE) ? 'passed' : 'failed', + 'file' => $back['file'], + 'line' => $back['line'] + ); + + $this->results[] = $report; + + return($this->report($this->result($report))); + } + + // -------------------------------------------------------------------- + + /** + * Generate a report + * + * Displays a table with the test data + * + * @access public + * @return string + */ + function report($result = array()) + { + if (count($result) == 0) + { + $result = $this->result(); + } + + $this->_parse_template(); + + $r = ''; + foreach ($result as $res) + { + $table = ''; + + foreach ($res as $key => $val) + { + $temp = $this->_template_rows; + $temp = str_replace('{item}', $key, $temp); + $temp = str_replace('{result}', $val, $temp); + $table .= $temp; + } + + $r .= str_replace('{rows}', $table, $this->_template); + } + + return $r; + } + + // -------------------------------------------------------------------- + + /** + * Use strict comparison + * + * Causes the evaluation to use === rather then == + * + * @access public + * @param bool + * @return null + */ + function use_strict($state = TRUE) + { + $this->strict = ($state == FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Make Unit testing active + * + * Enables/disables unit testing + * + * @access public + * @param bool + * @return null + */ + function active($state = TRUE) + { + $this->active = ($state == FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Result Array + * + * Returns the raw result data + * + * @access public + * @return array + */ + function result($results = array()) + { + $CI =& get_instance(); + $CI->load->language('unit_test'); + + if (count($results) == 0) + { + $results = $this->results; + } + + $retval = array(); + foreach ($results as $result) + { + $temp = array(); + foreach ($result as $key => $val) + { + if (is_array($val)) + { + foreach ($val as $k => $v) + { + if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v)))) + { + $v = $line; + } + $temp[$CI->lang->line('ut_'.$k)] = $v; + } + } + else + { + if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val)))) + { + $val = $line; + } + $temp[$CI->lang->line('ut_'.$key)] = $val; + } + } + + $retval[] = $temp; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Set the template + * + * This lets us set the template to be used to display results + * + * @access public + * @param string + * @return void + */ + function set_template($template) + { + $this->_template = $template; + } + + // -------------------------------------------------------------------- + + /** + * Generate a backtrace + * + * This lets us show file names and line numbers + * + * @access private + * @return array + */ + function _backtrace() + { + if (function_exists('debug_backtrace')) + { + $back = debug_backtrace(); + + $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file']; + $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line']; + + return array('file' => $file, 'line' => $line); + } + return array('file' => 'Unknown', 'line' => 'Unknown'); + } + + // -------------------------------------------------------------------- + + /** + * Get Default Template + * + * @access private + * @return string + */ + function _default_template() + { + $this->_template = ' +
    + + {rows} +
    '; + + $this->_template_rows = ' + + {item} + {result} + + '; + } + + // -------------------------------------------------------------------- + + /** + * Parse Template + * + * Harvests the data within the template {pseudo-variables} + * + * @access private + * @return void + */ + function _parse_template() + { + if ( ! is_null($this->_template_rows)) + { + return; + } + + if (is_null($this->_template)) + { + $this->_default_template(); + return; + } + + if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match)) + { + $this->_default_template(); + return; + } + + $this->_template_rows = $match['1']; + $this->_template = str_replace($match['0'], '{rows}', $this->_template); + } + +} +// END Unit_test Class + +/** + * Helper functions to test boolean true/false + * + * + * @access private + * @return bool + */ +function is_true($test) +{ + return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE; +} +function is_false($test) +{ + return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE; +} + +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Upload.php.svn-base b/system/libraries/.svn/text-base/Upload.php.svn-base new file mode 100644 index 0000000..2a3f53d --- /dev/null +++ b/system/libraries/.svn/text-base/Upload.php.svn-base @@ -0,0 +1,838 @@ + 0) + { + $this->initialize($props); + } + + log_message('debug', "Upload Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + $defaults = array( + 'max_size' => 0, + 'max_width' => 0, + 'max_height' => 0, + 'allowed_types' => "", + 'file_temp' => "", + 'file_name' => "", + 'orig_name' => "", + 'file_type' => "", + 'file_size' => "", + 'file_ext' => "", + 'upload_path' => "", + 'overwrite' => FALSE, + 'encrypt_name' => FALSE, + 'is_image' => FALSE, + 'image_width' => '', + 'image_height' => '', + 'image_type' => '', + 'image_size_str' => '', + 'error_msg' => array(), + 'mimes' => array(), + 'remove_spaces' => TRUE, + 'xss_clean' => FALSE, + 'temp_prefix' => "temp_file_" + ); + + + foreach ($defaults as $key => $val) + { + if (isset($config[$key])) + { + $method = 'set_'.$key; + if (method_exists($this, $method)) + { + $this->$method($config[$key]); + } + else + { + $this->$key = $config[$key]; + } + } + else + { + $this->$key = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Perform the file upload + * + * @access public + * @return bool + */ + function do_upload($field = 'userfile') + { + // Is $_FILES[$field] set? If not, no reason to continue. + if ( ! isset($_FILES[$field])) + { + $this->set_error('upload_no_file_selected'); + return FALSE; + } + + // Is the upload path valid? + if ( ! $this->validate_upload_path()) + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + // Was the file able to be uploaded? If not, determine the reason why. + if ( ! is_uploaded_file($_FILES[$field]['tmp_name'])) + { + $error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error']; + + switch($error) + { + case 1: // UPLOAD_ERR_INI_SIZE + $this->set_error('upload_file_exceeds_limit'); + break; + case 2: // UPLOAD_ERR_FORM_SIZE + $this->set_error('upload_file_exceeds_form_limit'); + break; + case 3: // UPLOAD_ERR_PARTIAL + $this->set_error('upload_file_partial'); + break; + case 4: // UPLOAD_ERR_NO_FILE + $this->set_error('upload_no_file_selected'); + break; + case 6: // UPLOAD_ERR_NO_TMP_DIR + $this->set_error('upload_no_temp_directory'); + break; + case 7: // UPLOAD_ERR_CANT_WRITE + $this->set_error('upload_unable_to_write_file'); + break; + case 8: // UPLOAD_ERR_EXTENSION + $this->set_error('upload_stopped_by_extension'); + break; + default : $this->set_error('upload_no_file_selected'); + break; + } + + return FALSE; + } + + // Set the uploaded data as class variables + $this->file_temp = $_FILES[$field]['tmp_name']; + $this->file_name = $_FILES[$field]['name']; + $this->file_size = $_FILES[$field]['size']; + $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); + $this->file_type = strtolower($this->file_type); + $this->file_ext = $this->get_extension($_FILES[$field]['name']); + + // Convert the file size to kilobytes + if ($this->file_size > 0) + { + $this->file_size = round($this->file_size/1024, 2); + } + + // Is the file type allowed to be uploaded? + if ( ! $this->is_allowed_filetype()) + { + $this->set_error('upload_invalid_filetype'); + return FALSE; + } + + // Is the file size within the allowed maximum? + if ( ! $this->is_allowed_filesize()) + { + $this->set_error('upload_invalid_filesize'); + return FALSE; + } + + // Are the image dimensions within the allowed size? + // Note: This can fail if the server has an open_basdir restriction. + if ( ! $this->is_allowed_dimensions()) + { + $this->set_error('upload_invalid_dimensions'); + return FALSE; + } + + // Sanitize the file name for security + $this->file_name = $this->clean_file_name($this->file_name); + + // Remove white spaces in the name + if ($this->remove_spaces == TRUE) + { + $this->file_name = preg_replace("/\s+/", "_", $this->file_name); + } + + /* + * Validate the file name + * This function appends an number onto the end of + * the file if one with the same name already exists. + * If it returns false there was a problem. + */ + $this->orig_name = $this->file_name; + + if ($this->overwrite == FALSE) + { + $this->file_name = $this->set_filename($this->upload_path, $this->file_name); + + if ($this->file_name === FALSE) + { + return FALSE; + } + } + + /* + * Move the file to the final destination + * To deal with different server configurations + * we'll attempt to use copy() first. If that fails + * we'll use move_uploaded_file(). One of the two should + * reliably work in most environments + */ + if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name)) + { + if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) + { + $this->set_error('upload_destination_error'); + return FALSE; + } + } + + /* + * Run the file through the XSS hacking filter + * This helps prevent malicious code from being + * embedded within a file. Scripts can easily + * be disguised as images or other file types. + */ + if ($this->xss_clean == TRUE) + { + $this->do_xss_clean(); + } + + /* + * Set the finalized image dimensions + * This sets the image width/height (assuming the + * file was an image). We use this information + * in the "data" function. + */ + $this->set_image_properties($this->upload_path.$this->file_name); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Finalized Data Array + * + * Returns an associative array containing all of the information + * related to the upload, allowing the developer easy access in one array. + * + * @access public + * @return array + */ + function data() + { + return array ( + 'file_name' => $this->file_name, + 'file_type' => $this->file_type, + 'file_path' => $this->upload_path, + 'full_path' => $this->upload_path.$this->file_name, + 'raw_name' => str_replace($this->file_ext, '', $this->file_name), + 'orig_name' => $this->orig_name, + 'file_ext' => $this->file_ext, + 'file_size' => $this->file_size, + 'is_image' => $this->is_image(), + 'image_width' => $this->image_width, + 'image_height' => $this->image_height, + 'image_type' => $this->image_type, + 'image_size_str' => $this->image_size_str, + ); + } + + // -------------------------------------------------------------------- + + /** + * Set Upload Path + * + * @access public + * @param string + * @return void + */ + function set_upload_path($path) + { + $this->upload_path = $path; + } + + // -------------------------------------------------------------------- + + /** + * Set the file name + * + * This function takes a filename/path as input and looks for the + * existence of a file with the same name. If found, it will append a + * number to the end of the filename to avoid overwriting a pre-existing file. + * + * @access public + * @param string + * @param string + * @return string + */ + function set_filename($path, $filename) + { + if ($this->encrypt_name == TRUE) + { + mt_srand(); + $filename = md5(uniqid(mt_rand())).$this->file_ext; + } + + if ( ! file_exists($path.$filename)) + { + return $filename; + } + + $filename = str_replace($this->file_ext, '', $filename); + + $new_filename = ''; + for ($i = 1; $i < 100; $i++) + { + if ( ! file_exists($path.$filename.$i.$this->file_ext)) + { + $new_filename = $filename.$i.$this->file_ext; + break; + } + } + + if ($new_filename == '') + { + $this->set_error('upload_bad_filename'); + return FALSE; + } + else + { + return $new_filename; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum File Size + * + * @access public + * @param integer + * @return void + */ + function set_max_filesize($n) + { + $this->max_size = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum Image Width + * + * @access public + * @param integer + * @return void + */ + function set_max_width($n) + { + $this->max_width = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum Image Height + * + * @access public + * @param integer + * @return void + */ + function set_max_height($n) + { + $this->max_height = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Allowed File Types + * + * @access public + * @param string + * @return void + */ + function set_allowed_types($types) + { + $this->allowed_types = explode('|', $types); + } + + // -------------------------------------------------------------------- + + /** + * Set Image Properties + * + * Uses GD to determine the width/height/type of image + * + * @access public + * @param string + * @return void + */ + function set_image_properties($path = '') + { + if ( ! $this->is_image()) + { + return; + } + + if (function_exists('getimagesize')) + { + if (FALSE !== ($D = @getimagesize($path))) + { + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); + + $this->image_width = $D['0']; + $this->image_height = $D['1']; + $this->image_type = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']]; + $this->image_size_str = $D['3']; // string containing height and width + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set XSS Clean + * + * Enables the XSS flag so that the file that was uploaded + * will be run through the XSS filter. + * + * @access public + * @param bool + * @return void + */ + function set_xss_clean($flag = FALSE) + { + $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Validate the image + * + * @access public + * @return bool + */ + function is_image() + { + // IE will sometimes return odd mime-types during upload, so here we just standardize all + // jpegs or pngs to the same file type. + + $png_mimes = array('image/x-png'); + $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg'); + + if (in_array($this->file_type, $png_mimes)) + { + $this->file_type = 'image/png'; + } + + if (in_array($this->file_type, $jpeg_mimes)) + { + $this->file_type = 'image/jpeg'; + } + + $img_mimes = array( + 'image/gif', + 'image/jpeg', + 'image/png', + ); + + return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Verify that the filetype is allowed + * + * @access public + * @return bool + */ + function is_allowed_filetype() + { + if (count($this->allowed_types) == 0 || ! is_array($this->allowed_types)) + { + $this->set_error('upload_no_file_types'); + return FALSE; + } + + foreach ($this->allowed_types as $val) + { + $mime = $this->mimes_types(strtolower($val)); + + if (is_array($mime)) + { + if (in_array($this->file_type, $mime, TRUE)) + { + return TRUE; + } + } + else + { + if ($mime == $this->file_type) + { + return TRUE; + } + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Verify that the file is within the allowed size + * + * @access public + * @return bool + */ + function is_allowed_filesize() + { + if ($this->max_size != 0 AND $this->file_size > $this->max_size) + { + return FALSE; + } + else + { + return TRUE; + } + } + + // -------------------------------------------------------------------- + + /** + * Verify that the image is within the allowed width/height + * + * @access public + * @return bool + */ + function is_allowed_dimensions() + { + if ( ! $this->is_image()) + { + return TRUE; + } + + if (function_exists('getimagesize')) + { + $D = @getimagesize($this->file_temp); + + if ($this->max_width > 0 AND $D['0'] > $this->max_width) + { + return FALSE; + } + + if ($this->max_height > 0 AND $D['1'] > $this->max_height) + { + return FALSE; + } + + return TRUE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Validate Upload Path + * + * Verifies that it is a valid upload path with proper permissions. + * + * + * @access public + * @return bool + */ + function validate_upload_path() + { + if ($this->upload_path == '') + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE) + { + $this->upload_path = str_replace("\\", "/", realpath($this->upload_path)); + } + + if ( ! @is_dir($this->upload_path)) + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + if ( ! is_really_writable($this->upload_path)) + { + $this->set_error('upload_not_writable'); + return FALSE; + } + + $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Extract the file extension + * + * @access public + * @param string + * @return string + */ + function get_extension($filename) + { + $x = explode('.', $filename); + return '.'.end($x); + } + + // -------------------------------------------------------------------- + + /** + * Clean the file name for security + * + * @access public + * @param string + * @return string + */ + function clean_file_name($filename) + { + $bad = array( + "", + "'", + "<", + ">", + '"', + '&', + '$', + '=', + ';', + '?', + '/', + "%20", + "%22", + "%3c", // < + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; + "%3d" // = + ); + + foreach ($bad as $val) + { + $filename = str_replace($val, '', $filename); + } + + return stripslashes($filename); + } + + // -------------------------------------------------------------------- + + /** + * Runs the file through the XSS clean function + * + * This prevents people from embedding malicious code in their files. + * I'm not sure that it won't negatively affect certain files in unexpected ways, + * but so far I haven't found that it causes trouble. + * + * @access public + * @return void + */ + function do_xss_clean() + { + $file = $this->upload_path.$this->file_name; + + if (filesize($file) == 0) + { + return FALSE; + } + + if (($data = @file_get_contents($file)) === FALSE) + { + return FALSE; + } + + if ( ! $fp = @fopen($file, 'r+b')) + { + return FALSE; + } + + $CI =& get_instance(); + $data = $CI->input->xss_clean($data); + + flock($fp, LOCK_EX); + fwrite($fp, $data); + flock($fp, LOCK_UN); + fclose($fp); + } + + // -------------------------------------------------------------------- + + /** + * Set an error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + $CI =& get_instance(); + $CI->lang->load('upload'); + + if (is_array($msg)) + { + foreach ($msg as $val) + { + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + else + { + $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + + // -------------------------------------------------------------------- + + /** + * Display the error message + * + * @access public + * @param string + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * List of Mime Types + * + * This is a list of mime types. We use it to validate + * the "allowed types" set by the developer + * + * @access public + * @param string + * @return string + */ + function mimes_types($mime) + { + if (count($this->mimes) == 0) + { + if (@include(APPPATH.'config/mimes'.EXT)) + { + $this->mimes = $mimes; + unset($mimes); + } + } + + return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime]; + } + +} +// END Upload Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/User_agent.php.svn-base b/system/libraries/.svn/text-base/User_agent.php.svn-base new file mode 100644 index 0000000..ff6d4a9 --- /dev/null +++ b/system/libraries/.svn/text-base/User_agent.php.svn-base @@ -0,0 +1,500 @@ +agent = trim($_SERVER['HTTP_USER_AGENT']); + } + + if ( ! is_null($this->agent)) + { + if ($this->_load_agent_file()) + { + $this->_compile_data(); + } + } + + log_message('debug', "User Agent Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Compile the User Agent Data + * + * @access private + * @return bool + */ + function _load_agent_file() + { + if ( ! @include(APPPATH.'config/user_agents'.EXT)) + { + return FALSE; + } + + $return = FALSE; + + if (isset($platforms)) + { + $this->platforms = $platforms; + unset($platforms); + $return = TRUE; + } + + if (isset($browsers)) + { + $this->browsers = $browsers; + unset($browsers); + $return = TRUE; + } + + if (isset($mobiles)) + { + $this->mobiles = $mobiles; + unset($mobiles); + $return = TRUE; + } + + if (isset($robots)) + { + $this->robots = $robots; + unset($robots); + $return = TRUE; + } + + return $return; + } + + // -------------------------------------------------------------------- + + /** + * Compile the User Agent Data + * + * @access private + * @return bool + */ + function _compile_data() + { + $this->_set_platform(); + + foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function) + { + if ($this->$function() === TRUE) + { + break; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set the Platform + * + * @access private + * @return mixed + */ + function _set_platform() + { + if (is_array($this->platforms) AND count($this->platforms) > 0) + { + foreach ($this->platforms as $key => $val) + { + if (preg_match("|".preg_quote($key)."|i", $this->agent)) + { + $this->platform = $val; + return TRUE; + } + } + } + $this->platform = 'Unknown Platform'; + } + + // -------------------------------------------------------------------- + + /** + * Set the Browser + * + * @access private + * @return bool + */ + function _set_browser() + { + if (is_array($this->browsers) AND count($this->browsers) > 0) + { + foreach ($this->browsers as $key => $val) + { + if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match)) + { + $this->is_browser = TRUE; + $this->version = $match[1]; + $this->browser = $val; + $this->_set_mobile(); + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the Robot + * + * @access private + * @return bool + */ + function _set_robot() + { + if (is_array($this->robots) AND count($this->robots) > 0) + { + foreach ($this->robots as $key => $val) + { + if (preg_match("|".preg_quote($key)."|i", $this->agent)) + { + $this->is_robot = TRUE; + $this->robot = $val; + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the Mobile Device + * + * @access private + * @return bool + */ + function _set_mobile() + { + if (is_array($this->mobiles) AND count($this->mobiles) > 0) + { + foreach ($this->mobiles as $key => $val) + { + if (FALSE !== (strpos(strtolower($this->agent), $key))) + { + $this->is_mobile = TRUE; + $this->mobile = $val; + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the accepted languages + * + * @access private + * @return void + */ + function _set_languages() + { + if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '') + { + $languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))); + + $this->languages = explode(',', $languages); + } + + if (count($this->languages) == 0) + { + $this->languages = array('Undefined'); + } + } + + // -------------------------------------------------------------------- + + /** + * Set the accepted character sets + * + * @access private + * @return void + */ + function _set_charsets() + { + if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '') + { + $charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))); + + $this->charsets = explode(',', $charsets); + } + + if (count($this->charsets) == 0) + { + $this->charsets = array('Undefined'); + } + } + + // -------------------------------------------------------------------- + + /** + * Is Browser + * + * @access public + * @return bool + */ + function is_browser() + { + return $this->is_browser; + } + + // -------------------------------------------------------------------- + + /** + * Is Robot + * + * @access public + * @return bool + */ + function is_robot() + { + return $this->is_robot; + } + + // -------------------------------------------------------------------- + + /** + * Is Mobile + * + * @access public + * @return bool + */ + function is_mobile() + { + return $this->is_mobile; + } + + // -------------------------------------------------------------------- + + /** + * Is this a referral from another site? + * + * @access public + * @return bool + */ + function is_referral() + { + return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Agent String + * + * @access public + * @return string + */ + function agent_string() + { + return $this->agent; + } + + // -------------------------------------------------------------------- + + /** + * Get Platform + * + * @access public + * @return string + */ + function platform() + { + return $this->platform; + } + + // -------------------------------------------------------------------- + + /** + * Get Browser Name + * + * @access public + * @return string + */ + function browser() + { + return $this->browser; + } + + // -------------------------------------------------------------------- + + /** + * Get the Browser Version + * + * @access public + * @return string + */ + function version() + { + return $this->version; + } + + // -------------------------------------------------------------------- + + /** + * Get The Robot Name + * + * @access public + * @return string + */ + function robot() + { + return $this->robot; + } + // -------------------------------------------------------------------- + + /** + * Get the Mobile Device + * + * @access public + * @return string + */ + function mobile() + { + return $this->mobile; + } + + // -------------------------------------------------------------------- + + /** + * Get the referrer + * + * @access public + * @return bool + */ + function referrer() + { + return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']); + } + + // -------------------------------------------------------------------- + + /** + * Get the accepted languages + * + * @access public + * @return array + */ + function languages() + { + if (count($this->languages) == 0) + { + $this->_set_languages(); + } + + return $this->languages; + } + + // -------------------------------------------------------------------- + + /** + * Get the accepted Character Sets + * + * @access public + * @return array + */ + function charsets() + { + if (count($this->charsets) == 0) + { + $this->_set_charsets(); + } + + return $this->charsets; + } + + // -------------------------------------------------------------------- + + /** + * Test for a particular language + * + * @access public + * @return bool + */ + function accept_lang($lang = 'en') + { + return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Test for a particular character set + * + * @access public + * @return bool + */ + function accept_charset($charset = 'utf-8') + { + return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE; + } + + +} + +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Validation.php.svn-base b/system/libraries/.svn/text-base/Validation.php.svn-base new file mode 100644 index 0000000..d0714d0 --- /dev/null +++ b/system/libraries/.svn/text-base/Validation.php.svn-base @@ -0,0 +1,781 @@ +'; + var $_error_suffix = '

    '; + + + + /** + * Constructor + * + */ + function CI_Validation() + { + $this->CI =& get_instance(); + log_message('debug', "Validation Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Set Fields + * + * This function takes an array of field names as input + * and generates class variables with the same name, which will + * either be blank or contain the $_POST value corresponding to it + * + * @access public + * @param string + * @param string + * @return void + */ + function set_fields($data = '', $field = '') + { + if ($data == '') + { + if (count($this->_fields) == 0) + { + return FALSE; + } + } + else + { + if ( ! is_array($data)) + { + $data = array($data => $field); + } + + if (count($data) > 0) + { + $this->_fields = $data; + } + } + + foreach($this->_fields as $key => $val) + { + $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]); + + $error = $key.'_error'; + if ( ! isset($this->$error)) + { + $this->$error = ''; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set Rules + * + * This function takes an array of field names and validation + * rules as input ad simply stores is for use later. + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_rules($data, $rules = '') + { + if ( ! is_array($data)) + { + if ($rules == '') + return; + + $data[$data] = $rules; + } + + foreach ($data as $key => $val) + { + $this->_rules[$key] = $val; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Error Message + * + * Lets users set their own error messages on the fly. Note: The key + * name has to match the function name that it corresponds to. + * + * @access public + * @param string + * @param string + * @return string + */ + function set_message($lang, $val = '') + { + if ( ! is_array($lang)) + { + $lang = array($lang => $val); + } + + $this->_error_messages = array_merge($this->_error_messages, $lang); + } + + // -------------------------------------------------------------------- + + /** + * Set The Error Delimiter + * + * Permits a prefix/suffix to be added to each error message + * + * @access public + * @param string + * @param string + * @return void + */ + function set_error_delimiters($prefix = '

    ', $suffix = '

    ') + { + $this->_error_prefix = $prefix; + $this->_error_suffix = $suffix; + } + + // -------------------------------------------------------------------- + + /** + * Run the Validator + * + * This function does all the work. + * + * @access public + * @return bool + */ + function run() + { + // Do we even have any data to process? Mm? + if (count($_POST) == 0 OR count($this->_rules) == 0) + { + return FALSE; + } + + // Load the language file containing error messages + $this->CI->lang->load('validation'); + + // Cycle through the rules and test for errors + foreach ($this->_rules as $field => $rules) + { + //Explode out the rules! + $ex = explode('|', $rules); + + // Is the field required? If not, if the field is blank we'll move on to the next test + if ( ! in_array('required', $ex, TRUE)) + { + if ( ! isset($_POST[$field]) OR $_POST[$field] == '') + { + continue; + } + } + + /* + * Are we dealing with an "isset" rule? + * + * Before going further, we'll see if one of the rules + * is to check whether the item is set (typically this + * applies only to checkboxes). If so, we'll + * test for it here since there's not reason to go + * further + */ + if ( ! isset($_POST[$field])) + { + if (in_array('isset', $ex, TRUE) OR in_array('required', $ex)) + { + if ( ! isset($this->_error_messages['isset'])) + { + if (FALSE === ($line = $this->CI->lang->line('isset'))) + { + $line = 'The field was not set'; + } + } + else + { + $line = $this->_error_messages['isset']; + } + + // Build the error message + $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; + $message = sprintf($line, $mfield); + + // Set the error variable. Example: $this->username_error + $error = $field.'_error'; + $this->$error = $this->_error_prefix.$message.$this->_error_suffix; + $this->_error_array[] = $message; + } + + continue; + } + + /* + * Set the current field + * + * The various prepping functions need to know the + * current field name so they can do this: + * + * $_POST[$this->_current_field] == 'bla bla'; + */ + $this->_current_field = $field; + + // Cycle through the rules! + foreach ($ex As $rule) + { + // Is the rule a callback? + $callback = FALSE; + if (substr($rule, 0, 9) == 'callback_') + { + $rule = substr($rule, 9); + $callback = TRUE; + } + + // Strip the parameter (if exists) from the rule + // Rules can contain a parameter: max_length[5] + $param = FALSE; + if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) + { + $rule = $match[1]; + $param = $match[2]; + } + + // Call the function that corresponds to the rule + if ($callback === TRUE) + { + if ( ! method_exists($this->CI, $rule)) + { + continue; + } + + $result = $this->CI->$rule($_POST[$field], $param); + + // If the field isn't required and we just processed a callback we'll move on... + if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE) + { + continue 2; + } + + } + else + { + if ( ! method_exists($this, $rule)) + { + /* + * Run the native PHP function if called for + * + * If our own wrapper function doesn't exist we see + * if a native PHP function does. Users can use + * any native PHP function call that has one param. + */ + if (function_exists($rule)) + { + $_POST[$field] = $rule($_POST[$field]); + $this->$field = $_POST[$field]; + } + + continue; + } + + $result = $this->$rule($_POST[$field], $param); + } + + // Did the rule test negatively? If so, grab the error. + if ($result === FALSE) + { + if ( ! isset($this->_error_messages[$rule])) + { + if (FALSE === ($line = $this->CI->lang->line($rule))) + { + $line = 'Unable to access an error message corresponding to your field name.'; + } + } + else + { + $line = $this->_error_messages[$rule]; + } + + // Build the error message + $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; + $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param]; + $message = sprintf($line, $mfield, $mparam); + + // Set the error variable. Example: $this->username_error + $error = $field.'_error'; + $this->$error = $this->_error_prefix.$message.$this->_error_suffix; + + // Add the error to the error array + $this->_error_array[] = $message; + continue 2; + } + } + + } + + $total_errors = count($this->_error_array); + + /* + * Recompile the class variables + * + * If any prepping functions were called the $_POST data + * might now be different then the corresponding class + * variables so we'll set them anew. + */ + if ($total_errors > 0) + { + $this->_safe_form_data = TRUE; + } + + $this->set_fields(); + + // Did we end up with any errors? + if ($total_errors == 0) + { + return TRUE; + } + + // Generate the error string + foreach ($this->_error_array as $val) + { + $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n"; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Required + * + * @access public + * @param string + * @return bool + */ + function required($str) + { + if ( ! is_array($str)) + { + return (trim($str) == '') ? FALSE : TRUE; + } + else + { + return ( ! empty($str)); + } + } + + // -------------------------------------------------------------------- + + /** + * Match one field to another + * + * @access public + * @param string + * @return bool + */ + function matches($str, $field) + { + if ( ! isset($_POST[$field])) + { + return FALSE; + } + + return ($str !== $_POST[$field]) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Minimum Length + * + * @access public + * @param string + * @return bool + */ + function min_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) < $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Max Length + * + * @access public + * @param string + * @return bool + */ + function max_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) > $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Exact Length + * + * @access public + * @param string + * @return bool + */ + function exact_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) != $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Valid Email + * + * @access public + * @param string + * @return bool + */ + function valid_email($str) + { + return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Validate IP Address + * + * @access public + * @param string + * @return string + */ + function valid_ip($ip) + { + return $this->CI->input->valid_ip($ip); + } + + // -------------------------------------------------------------------- + + /** + * Alpha + * + * @access public + * @param string + * @return bool + */ + function alpha($str) + { + return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Alpha-numeric + * + * @access public + * @param string + * @return bool + */ + function alpha_numeric($str) + { + return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Alpha-numeric with underscores and dashes + * + * @access public + * @param string + * @return bool + */ + function alpha_dash($str) + { + return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Numeric + * + * @access public + * @param string + * @return bool + */ + function numeric($str) + { + return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str); + + } + + // -------------------------------------------------------------------- + + /** + * Is Numeric + * + * @access public + * @param string + * @return bool + */ + function is_numeric($str) + { + return ( ! is_numeric($str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Integer + * + * @access public + * @param string + * @return bool + */ + function integer($str) + { + return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str); + } + + // -------------------------------------------------------------------- + + /** + * Valid Base64 + * + * Tests a string for characters outside of the Base64 alphabet + * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045 + * + * @access public + * @param string + * @return bool + */ + function valid_base64($str) + { + return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str); + } + + // -------------------------------------------------------------------- + + /** + * Set Select + * + * Enables pull-down lists to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_select($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' selected="selected"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Radio + * + * Enables radio buttons to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_radio($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' checked="checked"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Checkbox + * + * Enables checkboxes to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_checkbox($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' checked="checked"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Prep data for form + * + * This function allows HTML to be safely shown in a form. + * Special characters are converted. + * + * @access public + * @param string + * @return string + */ + function prep_for_form($data = '') + { + if (is_array($data)) + { + foreach ($data as $key => $val) + { + $data[$key] = $this->prep_for_form($val); + } + } + + if ($this->_safe_form_data == FALSE OR $data == '') + { + return $data; + } + + return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data)); + } + + // -------------------------------------------------------------------- + + /** + * Prep URL + * + * @access public + * @param string + * @return string + */ + function prep_url($str = '') + { + if ($str == 'http://' OR $str == '') + { + $_POST[$this->_current_field] = ''; + return; + } + + if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') + { + $str = 'http://'.$str; + } + + $_POST[$this->_current_field] = $str; + } + + // -------------------------------------------------------------------- + + /** + * Strip Image Tags + * + * @access public + * @param string + * @return string + */ + function strip_image_tags($str) + { + $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str); + } + + // -------------------------------------------------------------------- + + /** + * XSS Clean + * + * @access public + * @param string + * @return string + */ + function xss_clean($str) + { + $_POST[$this->_current_field] = $this->CI->input->xss_clean($str); + } + + // -------------------------------------------------------------------- + + /** + * Convert PHP tags to entities + * + * @access public + * @param string + * @return string + */ + function encode_php_tags($str) + { + $_POST[$this->_current_field] = str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str); + } + +} +// END Validation Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Xmlrpc.php.svn-base b/system/libraries/.svn/text-base/Xmlrpc.php.svn-base new file mode 100644 index 0000000..f90ee56 --- /dev/null +++ b/system/libraries/.svn/text-base/Xmlrpc.php.svn-base @@ -0,0 +1,1419 @@ +xmlrpcName = $this->xmlrpcName; + $this->xmlrpc_backslash = chr(92).chr(92); + + // Types for info sent back and forth + $this->xmlrpcTypes = array( + $this->xmlrpcI4 => '1', + $this->xmlrpcInt => '1', + $this->xmlrpcBoolean => '1', + $this->xmlrpcString => '1', + $this->xmlrpcDouble => '1', + $this->xmlrpcDateTime => '1', + $this->xmlrpcBase64 => '1', + $this->xmlrpcArray => '2', + $this->xmlrpcStruct => '3' + ); + + // Array of Valid Parents for Various XML-RPC elements + $this->valid_parents = array('BOOLEAN' => array('VALUE'), + 'I4' => array('VALUE'), + 'INT' => array('VALUE'), + 'STRING' => array('VALUE'), + 'DOUBLE' => array('VALUE'), + 'DATETIME.ISO8601' => array('VALUE'), + 'BASE64' => array('VALUE'), + 'ARRAY' => array('VALUE'), + 'STRUCT' => array('VALUE'), + 'PARAM' => array('PARAMS'), + 'METHODNAME' => array('METHODCALL'), + 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'), + 'MEMBER' => array('STRUCT'), + 'NAME' => array('MEMBER'), + 'DATA' => array('ARRAY'), + 'FAULT' => array('METHODRESPONSE'), + 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT') + ); + + + // XML-RPC Responses + $this->xmlrpcerr['unknown_method'] = '1'; + $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server'; + $this->xmlrpcerr['invalid_return'] = '2'; + $this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.'; + $this->xmlrpcerr['incorrect_params'] = '3'; + $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method'; + $this->xmlrpcerr['introspect_unknown'] = '4'; + $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown"; + $this->xmlrpcerr['http_error'] = '5'; + $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server."; + $this->xmlrpcerr['no_data'] = '6'; + $this->xmlrpcstr['no_data'] ='No data received from server.'; + + $this->initialize($config); + + log_message('debug', "XML-RPC Class Initialized"); + } + + + //------------------------------------- + // Initialize Prefs + //------------------------------------- + + function initialize($config = array()) + { + if (sizeof($config) > 0) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + } + // END + + //------------------------------------- + // Take URL and parse it + //------------------------------------- + + function server($url, $port=80) + { + if (substr($url, 0, 4) != "http") + { + $url = "http://".$url; + } + + $parts = parse_url($url); + + $path = (!isset($parts['path'])) ? '/' : $parts['path']; + + if (isset($parts['query']) && $parts['query'] != '') + { + $path .= '?'.$parts['query']; + } + + $this->client = new XML_RPC_Client($path, $parts['host'], $port); + } + // END + + //------------------------------------- + // Set Timeout + //------------------------------------- + + function timeout($seconds=5) + { + if ( ! is_null($this->client) && is_int($seconds)) + { + $this->client->timeout = $seconds; + } + } + // END + + //------------------------------------- + // Set Methods + //------------------------------------- + + function method($function) + { + $this->method = $function; + } + // END + + //------------------------------------- + // Take Array of Data and Create Objects + //------------------------------------- + + function request($incoming) + { + if ( ! is_array($incoming)) + { + // Send Error + } + + $this->data = array(); + + foreach($incoming as $key => $value) + { + $this->data[$key] = $this->values_parsing($value); + } + } + // END + + + //------------------------------------- + // Set Debug + //------------------------------------- + + function set_debug($flag = TRUE) + { + $this->debug = ($flag == TRUE) ? TRUE : FALSE; + } + + //------------------------------------- + // Values Parsing + //------------------------------------- + + function values_parsing($value, $return = FALSE) + { + if (is_array($value) && isset($value['0'])) + { + if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])])) + { + if (is_array($value[0])) + { + $temp = new XML_RPC_Values($value['0'], 'array'); + } + else + { + $temp = new XML_RPC_Values($value['0'], 'string'); + } + } + elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array')) + { + while (list($k) = each($value['0'])) + { + $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE); + } + + $temp = new XML_RPC_Values($value['0'], $value['1']); + } + else + { + $temp = new XML_RPC_Values($value['0'], $value['1']); + } + } + else + { + $temp = new XML_RPC_Values($value, 'string'); + } + + return $temp; + } + // END + + + //------------------------------------- + // Sends XML-RPC Request + //------------------------------------- + + function send_request() + { + $this->message = new XML_RPC_Message($this->method,$this->data); + $this->message->debug = $this->debug; + + if ( ! $this->result = $this->client->send($this->message)) + { + $this->error = $this->result->errstr; + return FALSE; + } + elseif( ! is_object($this->result->val)) + { + $this->error = $this->result->errstr; + return FALSE; + } + + $this->response = $this->result->decode(); + + return TRUE; + } + // END + + //------------------------------------- + // Returns Error + //------------------------------------- + + function display_error() + { + return $this->error; + } + // END + + //------------------------------------- + // Returns Remote Server Response + //------------------------------------- + + function display_response() + { + return $this->response; + } + // END + + //------------------------------------- + // Sends an Error Message for Server Request + //------------------------------------- + + function send_error_message($number, $message) + { + return new XML_RPC_Response('0',$number, $message); + } + // END + + + //------------------------------------- + // Send Response for Server Request + //------------------------------------- + + function send_response($response) + { + // $response should be array of values, which will be parsed + // based on their data and type into a valid group of XML-RPC values + + $response = $this->values_parsing($response); + + return new XML_RPC_Response($response); + } + // END + +} // END XML_RPC Class + + + +/** + * XML-RPC Client class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Client extends CI_Xmlrpc +{ + var $path = ''; + var $server = ''; + var $port = 80; + var $errno = ''; + var $errstring = ''; + var $timeout = 5; + var $no_multicall = false; + + function XML_RPC_Client($path, $server, $port=80) + { + parent::CI_Xmlrpc(); + + $this->port = $port; + $this->server = $server; + $this->path = $path; + } + + function send($msg) + { + if (is_array($msg)) + { + // Multi-call disabled + $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']); + return $r; + } + + return $this->sendPayload($msg); + } + + function sendPayload($msg) + { + $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout); + + if (! is_resource($fp)) + { + error_log($this->xmlrpcstr['http_error']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']); + return $r; + } + + if(empty($msg->payload)) + { + // $msg = XML_RPC_Messages + $msg->createPayload(); + } + + $r = "\r\n"; + $op = "POST {$this->path} HTTP/1.0$r"; + $op .= "Host: {$this->server}$r"; + $op .= "Content-Type: text/xml$r"; + $op .= "User-Agent: {$this->xmlrpcName}$r"; + $op .= "Content-Length: ".strlen($msg->payload). "$r$r"; + $op .= $msg->payload; + + + if (!fputs($fp, $op, strlen($op))) + { + error_log($this->xmlrpcstr['http_error']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']); + return $r; + } + $resp = $msg->parseResponse($fp); + fclose($fp); + return $resp; + } + +} // end class XML_RPC_Client + + +/** + * XML-RPC Response class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Response +{ + var $val = 0; + var $errno = 0; + var $errstr = ''; + var $headers = array(); + + function XML_RPC_Response($val, $code = 0, $fstr = '') + { + if ($code != 0) + { + // error + $this->errno = $code; + $this->errstr = htmlentities($fstr); + } + else if (!is_object($val)) + { + // programmer error, not an object + error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response. Defaulting to empty value."); + $this->val = new XML_RPC_Values(); + } + else + { + $this->val = $val; + } + } + + function faultCode() + { + return $this->errno; + } + + function faultString() + { + return $this->errstr; + } + + function value() + { + return $this->val; + } + + function prepare_response() + { + $result = "\n"; + if ($this->errno) + { + $result .= ' + + + + faultCode + ' . $this->errno . ' + + + faultString + ' . $this->errstr . ' + + + +'; + } + else + { + $result .= "\n\n" . + $this->val->serialize_class() . + "\n"; + } + $result .= "\n"; + return $result; + } + + function decode($array=FALSE) + { + $CI =& get_instance(); + + if ($array !== FALSE && is_array($array)) + { + while (list($key) = each($array)) + { + if (is_array($array[$key])) + { + $array[$key] = $this->decode($array[$key]); + } + else + { + $array[$key] = $CI->input->xss_clean($array[$key]); + } + } + + $result = $array; + } + else + { + $result = $this->xmlrpc_decoder($this->val); + + if (is_array($result)) + { + $result = $this->decode($result); + } + else + { + $result = $CI->input->xss_clean($result); + } + } + + return $result; + } + + + + //------------------------------------- + // XML-RPC Object to PHP Types + //------------------------------------- + + function xmlrpc_decoder($xmlrpc_val) + { + $kind = $xmlrpc_val->kindOf(); + + if($kind == 'scalar') + { + return $xmlrpc_val->scalarval(); + } + elseif($kind == 'array') + { + reset($xmlrpc_val->me); + list($a,$b) = each($xmlrpc_val->me); + $size = sizeof($b); + + $arr = array(); + + for($i = 0; $i < $size; $i++) + { + $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]); + } + return $arr; + } + elseif($kind == 'struct') + { + reset($xmlrpc_val->me['struct']); + $arr = array(); + + while(list($key,$value) = each($xmlrpc_val->me['struct'])) + { + $arr[$key] = $this->xmlrpc_decoder($value); + } + return $arr; + } + } + + + //------------------------------------- + // ISO-8601 time to server or UTC time + //------------------------------------- + + function iso8601_decode($time, $utc=0) + { + // return a timet in the localtime, or UTC + $t = 0; + if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs)) + { + if ($utc == 1) + $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + else + $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } + return $t; + } + +} // End Response Class + + + +/** + * XML-RPC Message class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Message extends CI_Xmlrpc +{ + var $payload; + var $method_name; + var $params = array(); + var $xh = array(); + + function XML_RPC_Message($method, $pars=0) + { + parent::CI_Xmlrpc(); + + $this->method_name = $method; + if (is_array($pars) && sizeof($pars) > 0) + { + for($i=0; $iparams[] = $pars[$i]; + } + } + } + + //------------------------------------- + // Create Payload to Send + //------------------------------------- + + function createPayload() + { + $this->payload = "\r\n\r\n"; + $this->payload .= '' . $this->method_name . "\r\n"; + $this->payload .= "\r\n"; + + for($i=0; $iparams); $i++) + { + // $p = XML_RPC_Values + $p = $this->params[$i]; + $this->payload .= "\r\n".$p->serialize_class()."\r\n"; + } + + $this->payload .= "\r\n\r\n"; + } + + //------------------------------------- + // Parse External XML-RPC Server's Response + //------------------------------------- + + function parseResponse($fp) + { + $data = ''; + + while($datum = fread($fp, 4096)) + { + $data .= $datum; + } + + //------------------------------------- + // DISPLAY HTTP CONTENT for DEBUGGING + //------------------------------------- + + if ($this->debug === TRUE) + { + echo "
    ";
    +			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
    +			echo "
    "; + } + + //------------------------------------- + // Check for data + //------------------------------------- + + if($data == "") + { + error_log($this->xmlrpcstr['no_data']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']); + return $r; + } + + + //------------------------------------- + // Check for HTTP 200 Response + //------------------------------------- + + if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data)) + { + $errstr= substr($data, 0, strpos($data, "\n")-1); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')'); + return $r; + } + + //------------------------------------- + // Create and Set Up XML Parser + //------------------------------------- + + $parser = xml_parser_create($this->xmlrpc_defencoding); + + $this->xh[$parser] = array(); + $this->xh[$parser]['isf'] = 0; + $this->xh[$parser]['ac'] = ''; + $this->xh[$parser]['headers'] = array(); + $this->xh[$parser]['stack'] = array(); + $this->xh[$parser]['valuestack'] = array(); + $this->xh[$parser]['isf_reason'] = 0; + + xml_set_object($parser, $this); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'open_tag', 'closing_tag'); + xml_set_character_data_handler($parser, 'character_data'); + //xml_set_default_handler($parser, 'default_handler'); + + + //------------------------------------- + // GET HEADERS + //------------------------------------- + + $lines = explode("\r\n", $data); + while (($line = array_shift($lines))) + { + if (strlen($line) < 1) + { + break; + } + $this->xh[$parser]['headers'][] = $line; + } + $data = implode("\r\n", $lines); + + + //------------------------------------- + // PARSE XML DATA + //------------------------------------- + + if (!xml_parse($parser, $data, sizeof($data))) + { + $errstr = sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser)); + //error_log($errstr); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']); + xml_parser_free($parser); + return $r; + } + xml_parser_free($parser); + + // --------------------------------------- + // Got Ourselves Some Badness, It Seems + // --------------------------------------- + + if ($this->xh[$parser]['isf'] > 1) + { + if ($this->debug === TRUE) + { + echo "---Invalid Return---\n"; + echo $this->xh[$parser]['isf_reason']; + echo "---Invalid Return---\n\n"; + } + + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return $r; + } + elseif ( ! is_object($this->xh[$parser]['value'])) + { + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return $r; + } + + //------------------------------------- + // DISPLAY XML CONTENT for DEBUGGING + //------------------------------------- + + if ($this->debug === TRUE) + { + echo "
    ";
    +			
    +			if (count($this->xh[$parser]['headers'] > 0))
    +			{
    +				echo "---HEADERS---\n";
    +				foreach ($this->xh[$parser]['headers'] as $header)
    +				{
    +					echo "$header\n";
    +				}
    +				echo "---END HEADERS---\n\n";
    +			}
    +			
    +			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
    +			
    +			echo "---PARSED---\n" ;
    +			var_dump($this->xh[$parser]['value']);
    +			echo "\n---END PARSED---
    "; + } + + //------------------------------------- + // SEND RESPONSE + //------------------------------------- + + $v = $this->xh[$parser]['value']; + + if ($this->xh[$parser]['isf']) + { + $errno_v = $v->me['struct']['faultCode']; + $errstr_v = $v->me['struct']['faultString']; + $errno = $errno_v->scalarval(); + + if ($errno == 0) + { + // FAULT returned, errno needs to reflect that + $errno = -1; + } + + $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval()); + } + else + { + $r = new XML_RPC_Response($v); + } + + $r->headers = $this->xh[$parser]['headers']; + return $r; + } + + // ------------------------------------ + // Begin Return Message Parsing section + // ------------------------------------ + + // quick explanation of components: + // ac - used to accumulate values + // isf - used to indicate a fault + // lv - used to indicate "looking for a value": implements + // the logic to allow values with no types to be strings + // params - used to store parameters in method calls + // method - used to store method name + // stack - array with parent tree of the xml element, + // used to validate the nesting of elements + + //------------------------------------- + // Start Element Handler + //------------------------------------- + + function open_tag($the_parser, $name, $attrs) + { + // If invalid nesting, then return + if ($this->xh[$the_parser]['isf'] > 1) return; + + // Evaluate and check for correct nesting of XML elements + + if (count($this->xh[$the_parser]['stack']) == 0) + { + if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') + { + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing'; + return; + } + } + else + { + // not top level element: see if parent is OK + if (!in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE)) + { + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0]; + return; + } + } + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + // Creates array for child elements + + $cur_val = array('value' => array(), + 'type' => $name); + + array_unshift($this->xh[$the_parser]['valuestack'], $cur_val); + break; + case 'METHODNAME': + case 'NAME': + $this->xh[$the_parser]['ac'] = ''; + break; + case 'FAULT': + $this->xh[$the_parser]['isf'] = 1; + break; + case 'PARAM': + $this->xh[$the_parser]['value'] = null; + break; + case 'VALUE': + $this->xh[$the_parser]['vt'] = 'value'; + $this->xh[$the_parser]['ac'] = ''; + $this->xh[$the_parser]['lv'] = 1; + break; + case 'I4': + case 'INT': + case 'STRING': + case 'BOOLEAN': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + if ($this->xh[$the_parser]['vt'] != 'value') + { + //two data elements inside a value: an error occurred! + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value"; + return; + } + + $this->xh[$the_parser]['ac'] = ''; + break; + case 'MEMBER': + // Set name of to nothing to prevent errors later if no is found + $this->xh[$the_parser]['valuestack'][0]['name'] = ''; + + // Set NULL value to check to see if value passed for this param/member + $this->xh[$the_parser]['value'] = null; + break; + case 'DATA': + case 'METHODCALL': + case 'METHODRESPONSE': + case 'PARAMS': + // valid elements that add little to processing + break; + default: + /// An Invalid Element is Found, so we have trouble + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name"; + break; + } + + // Add current element name to stack, to allow validation of nesting + array_unshift($this->xh[$the_parser]['stack'], $name); + + if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0; + } + // END + + + //------------------------------------- + // End Element Handler + //------------------------------------- + + function closing_tag($the_parser, $name) + { + if ($this->xh[$the_parser]['isf'] > 1) return; + + // Remove current element from stack and set variable + // NOTE: If the XML validates, then we do not have to worry about + // the opening and closing of elements. Nesting is checked on the opening + // tag so we be safe there as well. + + $curr_elem = array_shift($this->xh[$the_parser]['stack']); + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + $cur_val = array_shift($this->xh[$the_parser]['valuestack']); + $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values']; + $this->xh[$the_parser]['vt'] = strtolower($name); + break; + case 'NAME': + $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac']; + break; + case 'BOOLEAN': + case 'I4': + case 'INT': + case 'STRING': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + $this->xh[$the_parser]['vt'] = strtolower($name); + + if ($name == 'STRING') + { + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + } + elseif ($name=='DATETIME.ISO8601') + { + $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime; + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + } + elseif ($name=='BASE64') + { + $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']); + } + elseif ($name=='BOOLEAN') + { + // Translated BOOLEAN values to TRUE AND FALSE + if ($this->xh[$the_parser]['ac'] == '1') + { + $this->xh[$the_parser]['value'] = TRUE; + } + else + { + $this->xh[$the_parser]['value'] = FALSE; + } + } + elseif ($name=='DOUBLE') + { + // we have a DOUBLE + // we must check that only 0123456789-. are characters here + if (! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND'; + } + else + { + $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac']; + } + } + else + { + // we have an I4/INT + // we must check that only 0123456789- are characters here + if (! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND'; + } + else + { + $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac']; + } + } + $this->xh[$the_parser]['ac'] = ''; + $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value + break; + case 'VALUE': + // This if() detects if no scalar was inside + if ($this->xh[$the_parser]['vt']=='value') + { + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + $this->xh[$the_parser]['vt'] = $this->xmlrpcString; + } + + // build the XML-RPC value out of the data received, and substitute it + $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']); + + if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY') + { + // Array + $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp; + } + else + { + // Struct + $this->xh[$the_parser]['value'] = $temp; + } + break; + case 'MEMBER': + $this->xh[$the_parser]['ac']=''; + + // If value add to array in the stack for the last element built + if ($this->xh[$the_parser]['value']) + { + $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value']; + } + break; + case 'DATA': + $this->xh[$the_parser]['ac']=''; + break; + case 'PARAM': + if ($this->xh[$the_parser]['value']) + { + $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value']; + } + break; + case 'METHODNAME': + $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']); + break; + case 'PARAMS': + case 'FAULT': + case 'METHODCALL': + case 'METHORESPONSE': + // We're all good kids with nuthin' to do + break; + default: + // End of an Invalid Element. Taken care of during the opening tag though + break; + } + } + + //------------------------------------- + // Parses Character Data + //------------------------------------- + + function character_data($the_parser, $data) + { + if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already + + // If a value has not been found + if ($this->xh[$the_parser]['lv'] != 3) + { + if ($this->xh[$the_parser]['lv'] == 1) + { + $this->xh[$the_parser]['lv'] = 2; // Found a value + } + + if( ! @isset($this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['ac'] = ''; + } + + $this->xh[$the_parser]['ac'] .= $data; + } + } + + + function addParam($par) { $this->params[]=$par; } + + function output_parameters($array=FALSE) + { + $CI =& get_instance(); + + if ($array !== FALSE && is_array($array)) + { + while (list($key) = each($array)) + { + if (is_array($array[$key])) + { + $array[$key] = $this->output_parameters($array[$key]); + } + else + { + $array[$key] = $CI->input->xss_clean($array[$key]); + } + } + + $parameters = $array; + } + else + { + $parameters = array(); + + for ($i = 0; $i < sizeof($this->params); $i++) + { + $a_param = $this->decode_message($this->params[$i]); + + if (is_array($a_param)) + { + $parameters[] = $this->output_parameters($a_param); + } + else + { + $parameters[] = $CI->input->xss_clean($a_param); + } + } + } + + return $parameters; + } + + + function decode_message($param) + { + $kind = $param->kindOf(); + + if($kind == 'scalar') + { + return $param->scalarval(); + } + elseif($kind == 'array') + { + reset($param->me); + list($a,$b) = each($param->me); + + $arr = array(); + + for($i = 0; $i < sizeof($b); $i++) + { + $arr[] = $this->decode_message($param->me['array'][$i]); + } + + return $arr; + } + elseif($kind == 'struct') + { + reset($param->me['struct']); + + $arr = array(); + + while(list($key,$value) = each($param->me['struct'])) + { + $arr[$key] = $this->decode_message($value); + } + + return $arr; + } + } + +} // End XML_RPC_Messages class + + + +/** + * XML-RPC Values class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Values extends CI_Xmlrpc +{ + var $me = array(); + var $mytype = 0; + + function XML_RPC_Values($val=-1, $type='') + { + parent::CI_Xmlrpc(); + + if ($val != -1 || $type != '') + { + $type = $type == '' ? 'string' : $type; + + if ($this->xmlrpcTypes[$type] == 1) + { + $this->addScalar($val,$type); + } + elseif ($this->xmlrpcTypes[$type] == 2) + { + $this->addArray($val); + } + elseif ($this->xmlrpcTypes[$type] == 3) + { + $this->addStruct($val); + } + } + } + + function addScalar($val, $type='string') + { + $typeof = $this->xmlrpcTypes[$type]; + + if ($this->mytype==1) + { + echo 'XML_RPC_Values: scalar can have only one value
    '; + return 0; + } + + if ($typeof != 1) + { + echo 'XML_RPC_Values: not a scalar type (${typeof})
    '; + return 0; + } + + if ($type == $this->xmlrpcBoolean) + { + if (strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false'))) + { + $val = 1; + } + else + { + $val=0; + } + } + + if ($this->mytype == 2) + { + // adding to an array here + $ar = $this->me['array']; + $ar[] = new XML_RPC_Values($val, $type); + $this->me['array'] = $ar; + } + else + { + // a scalar, so set the value and remember we're scalar + $this->me[$type] = $val; + $this->mytype = $typeof; + } + return 1; + } + + function addArray($vals) + { + if ($this->mytype != 0) + { + echo 'XML_RPC_Values: already initialized as a [' . $this->kindOf() . ']
    '; + return 0; + } + + $this->mytype = $this->xmlrpcTypes['array']; + $this->me['array'] = $vals; + return 1; + } + + function addStruct($vals) + { + if ($this->mytype != 0) + { + echo 'XML_RPC_Values: already initialized as a [' . $this->kindOf() . ']
    '; + return 0; + } + $this->mytype = $this->xmlrpcTypes['struct']; + $this->me['struct'] = $vals; + return 1; + } + + function kindOf() + { + switch($this->mytype) + { + case 3: + return 'struct'; + break; + case 2: + return 'array'; + break; + case 1: + return 'scalar'; + break; + default: + return 'undef'; + } + } + + function serializedata($typ, $val) + { + $rs = ''; + + switch($this->xmlrpcTypes[$typ]) + { + case 3: + // struct + $rs .= "\n"; + reset($val); + while(list($key2, $val2) = each($val)) + { + $rs .= "\n{$key2}\n"; + $rs .= $this->serializeval($val2); + $rs .= "\n"; + } + $rs .= ''; + break; + case 2: + // array + $rs .= "\n\n"; + for($i=0; $i < sizeof($val); $i++) + { + $rs .= $this->serializeval($val[$i]); + } + $rs.="\n\n"; + break; + case 1: + // others + switch ($typ) + { + case $this->xmlrpcBase64: + $rs .= "<{$typ}>" . base64_encode($val) . "\n"; + break; + case $this->xmlrpcBoolean: + $rs .= "<{$typ}>" . ($val ? '1' : '0') . "\n"; + break; + case $this->xmlrpcString: + $rs .= "<{$typ}>" . htmlspecialchars($val). "\n"; + break; + default: + $rs .= "<{$typ}>{$val}\n"; + break; + } + default: + break; + } + return $rs; + } + + function serialize_class() + { + return $this->serializeval($this); + } + + function serializeval($o) + { + $ar = $o->me; + reset($ar); + + list($typ, $val) = each($ar); + $rs = "\n".$this->serializedata($typ, $val)."\n"; + return $rs; + } + + function scalarval() + { + reset($this->me); + list($a,$b) = each($this->me); + return $b; + } + + + //------------------------------------- + // Encode time in ISO-8601 form. + //------------------------------------- + + // Useful for sending time in XML-RPC + + function iso8601_encode($time, $utc=0) + { + if ($utc == 1) + { + $t = strftime("%Y%m%dT%H:%M:%S", $time); + } + else + { + if (function_exists('gmstrftime')) + $t = gmstrftime("%Y%m%dT%H:%M:%S", $time); + else + $t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z')); + } + return $t; + } + +} +// END XML_RPC_Values Class +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Xmlrpcs.php.svn-base b/system/libraries/.svn/text-base/Xmlrpcs.php.svn-base new file mode 100644 index 0000000..ac644d8 --- /dev/null +++ b/system/libraries/.svn/text-base/Xmlrpcs.php.svn-base @@ -0,0 +1,522 @@ +set_system_methods(); + + if (isset($config['functions']) && is_array($config['functions'])) + { + $this->methods = array_merge($this->methods, $config['functions']); + } + + log_message('debug', "XML-RPC Server Class Initialized"); + } + + //------------------------------------- + // Initialize Prefs and Serve + //------------------------------------- + + function initialize($config=array()) + { + if (isset($config['functions']) && is_array($config['functions'])) + { + $this->methods = array_merge($this->methods, $config['functions']); + } + + if (isset($config['debug'])) + { + $this->debug = $config['debug']; + } + } + + //------------------------------------- + // Setting of System Methods + //------------------------------------- + + function set_system_methods () + { + $this->methods = array( + 'system.listMethods' => array( + 'function' => 'this.listMethods', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)), + 'docstring' => 'Returns an array of available methods on this server'), + 'system.methodHelp' => array( + 'function' => 'this.methodHelp', + 'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)), + 'docstring' => 'Returns a documentation string for the specified method'), + 'system.methodSignature' => array( + 'function' => 'this.methodSignature', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)), + 'docstring' => 'Returns an array describing the return type and required parameters of a method'), + 'system.multicall' => array( + 'function' => 'this.multicall', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)), + 'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details') + ); + } + + + //------------------------------------- + // Main Server Function + //------------------------------------- + + function serve() + { + $r = $this->parseRequest(); + $payload = 'xmlrpc_defencoding.'"?'.'>'."\n"; + $payload .= $this->debug_msg; + $payload .= $r->prepare_response(); + + header("Content-Type: text/xml"); + header("Content-Length: ".strlen($payload)); + echo $payload; + } + + //------------------------------------- + // Add Method to Class + //------------------------------------- + + function add_to_map($methodname,$function,$sig,$doc) + { + $this->methods[$methodname] = array( + 'function' => $function, + 'signature' => $sig, + 'docstring' => $doc + ); + } + + + //------------------------------------- + // Parse Server Request + //------------------------------------- + + function parseRequest($data='') + { + global $HTTP_RAW_POST_DATA; + + //------------------------------------- + // Get Data + //------------------------------------- + + if ($data == '') + { + $data = $HTTP_RAW_POST_DATA; + } + + //------------------------------------- + // Set up XML Parser + //------------------------------------- + + $parser = xml_parser_create($this->xmlrpc_defencoding); + $parser_object = new XML_RPC_Message("filler"); + + $parser_object->xh[$parser] = array(); + $parser_object->xh[$parser]['isf'] = 0; + $parser_object->xh[$parser]['isf_reason'] = ''; + $parser_object->xh[$parser]['params'] = array(); + $parser_object->xh[$parser]['stack'] = array(); + $parser_object->xh[$parser]['valuestack'] = array(); + $parser_object->xh[$parser]['method'] = ''; + + xml_set_object($parser, $parser_object); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'open_tag', 'closing_tag'); + xml_set_character_data_handler($parser, 'character_data'); + //xml_set_default_handler($parser, 'default_handler'); + + + //------------------------------------- + // PARSE + PROCESS XML DATA + //------------------------------------- + + if ( ! xml_parse($parser, $data, 1)) + { + // return XML error as a faultCode + $r = new XML_RPC_Response(0, + $this->xmlrpcerrxml + xml_get_error_code($parser), + sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + xml_parser_free($parser); + } + elseif($parser_object->xh[$parser]['isf']) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']); + } + else + { + xml_parser_free($parser); + + $m = new XML_RPC_Message($parser_object->xh[$parser]['method']); + $plist=''; + + for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++) + { + if ($this->debug === TRUE) + { + $plist .= "$i - " . print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n"; + } + + $m->addParam($parser_object->xh[$parser]['params'][$i]); + } + + if ($this->debug === TRUE) + { + echo "
    ";
    +				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
    +				echo "
    "; + } + + $r = $this->_execute($m); + } + + //------------------------------------- + // SET DEBUGGING MESSAGE + //------------------------------------- + + if ($this->debug === TRUE) + { + $this->debug_msg = "\n"; + } + + return $r; + } + + //------------------------------------- + // Executes the Method + //------------------------------------- + + function _execute($m) + { + $methName = $m->method_name; + + // Check to see if it is a system call + $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE; + + //------------------------------------- + // Valid Method + //------------------------------------- + + if ( ! isset($this->methods[$methName]['function'])) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + + //------------------------------------- + // Check for Method (and Object) + //------------------------------------- + + $method_parts = explode(".", $this->methods[$methName]['function']); + $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE; + + if ($system_call === TRUE) + { + if (! is_callable(array($this,$method_parts['1']))) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + } + else + { + if ($objectCall && !is_callable(array($method_parts['0'],$method_parts['1']))) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + elseif (!$objectCall && !is_callable($this->methods[$methName]['function'])) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + } + + //------------------------------------- + // Checking Methods Signature + //------------------------------------- + + if (isset($this->methods[$methName]['signature'])) + { + $sig = $this->methods[$methName]['signature']; + for($i=0; $iparams)+1) + { + for($n=0; $n < sizeof($m->params); $n++) + { + $p = $m->params[$n]; + $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf(); + + if ($pt != $current_sig[$n+1]) + { + $pno = $n+1; + $wanted = $current_sig[$n+1]; + + return new XML_RPC_Response(0, + $this->xmlrpcerr['incorrect_params'], + $this->xmlrpcstr['incorrect_params'] . + ": Wanted {$wanted}, got {$pt} at param {$pno})"); + } + } + } + } + } + + //------------------------------------- + // Calls the Function + //------------------------------------- + + if ($objectCall === TRUE) + { + if ($method_parts[0] == "this" && $system_call == TRUE) + { + return call_user_func(array($this, $method_parts[1]), $m); + } + else + { + $CI =& get_instance(); + return $CI->$method_parts['1']($m); + //$class = new $method_parts['0']; + //return $class->$method_parts['1']($m); + //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m); + } + } + else + { + return call_user_func($this->methods[$methName]['function'], $m); + } + } + + + //------------------------------------- + // Server Function: List Methods + //------------------------------------- + + function listMethods($m) + { + $v = new XML_RPC_Values(); + $output = array(); + + foreach($this->methods as $key => $value) + { + $output[] = new XML_RPC_Values($key, 'string'); + } + + foreach($this->system_methods as $key => $value) + { + $output[]= new XML_RPC_Values($key, 'string'); + } + + $v->addArray($output); + return new XML_RPC_Response($v); + } + + //------------------------------------- + // Server Function: Return Signature for Method + //------------------------------------- + + function methodSignature($m) + { + $parameters = $m->output_parameters(); + $method_name = $parameters[0]; + + if (isset($this->methods[$method_name])) + { + if ($this->methods[$method_name]['signature']) + { + $sigs = array(); + $signature = $this->methods[$method_name]['signature']; + + for($i=0; $i < sizeof($signature); $i++) + { + $cursig = array(); + $inSig = $signature[$i]; + for($j=0; $jxmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); + } + return $r; + } + + //------------------------------------- + // Server Function: Doc String for Method + //------------------------------------- + + function methodHelp($m) + { + $parameters = $m->output_parameters(); + $method_name = $parameters[0]; + + if (isset($this->methods[$method_name])) + { + $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : ''; + + return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string')); + } + else + { + return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); + } + } + + //------------------------------------- + // Server Function: Multi-call + //------------------------------------- + + function multicall($m) + { + // Disabled + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + + $parameters = $m->output_parameters(); + $calls = $parameters[0]; + + $result = array(); + + foreach ($calls as $value) + { + //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1])); + + $m = new XML_RPC_Message($value[0]); + $plist=''; + + for($i=0; $i < sizeof($value[1]); $i++) + { + $m->addParam(new XML_RPC_Values($value[1][$i], 'string')); + } + + $attempt = $this->_execute($m); + + if ($attempt->faultCode() != 0) + { + return $attempt; + } + + $result[] = new XML_RPC_Values(array($attempt->value()), 'array'); + } + + return new XML_RPC_Response(new XML_RPC_Values($result, 'array')); + } + + + //------------------------------------- + // Multi-call Function: Error Handling + //------------------------------------- + + function multicall_error($err) + { + $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString(); + $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode(); + + $struct['faultCode'] = new XML_RPC_Values($code, 'int'); + $struct['faultString'] = new XML_RPC_Values($str, 'string'); + + return new XML_RPC_Values($struct, 'struct'); + } + + + //------------------------------------- + // Multi-call Function: Processes method + //------------------------------------- + + function do_multicall($call) + { + if ($call->kindOf() != 'struct') + return $this->multicall_error('notstruct'); + elseif (!$methName = $call->me['struct']['methodName']) + return $this->multicall_error('nomethod'); + + list($scalar_type,$scalar_value)=each($methName->me); + $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type; + + if ($methName->kindOf() != 'scalar' || $scalar_type != 'string') + return $this->multicall_error('notstring'); + elseif ($scalar_value == 'system.multicall') + return $this->multicall_error('recursion'); + elseif (!$params = $call->me['struct']['params']) + return $this->multicall_error('noparams'); + elseif ($params->kindOf() != 'array') + return $this->multicall_error('notarray'); + + list($a,$b)=each($params->me); + $numParams = sizeof($b); + + $msg = new XML_RPC_Message($scalar_value); + for ($i = 0; $i < $numParams; $i++) + { + $msg->params[] = $params->me['array'][$i]; + } + + $result = $this->_execute($msg); + + if ($result->faultCode() != 0) + { + return $this->multicall_error($result); + } + + return new XML_RPC_Values(array($result->value()), 'array'); + } + +} +// END XML_RPC_Server class + +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/Zip.php.svn-base b/system/libraries/.svn/text-base/Zip.php.svn-base new file mode 100644 index 0000000..a3d42f3 --- /dev/null +++ b/system/libraries/.svn/text-base/Zip.php.svn-base @@ -0,0 +1,377 @@ +_add_dir($dir); + } + } + + // -------------------------------------------------------------------- + + /** + * Add Directory + * + * @access private + * @param string the directory name + * @return void + */ + function _add_dir($dir) + { + $dir = str_replace("\\", "/", $dir); + + $this->zipdata[] = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + .pack('V', 0) + .pack('V', 0) + .pack('V', 0) + .pack('v', strlen($dir)) + .pack('v', 0) + .$dir + .pack('V', 0) + .pack('V', 0) + .pack('V', 0); + + $newoffset = strlen(implode('', $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + .pack('V',0) + .pack('V',0) + .pack('V',0) + .pack('v', strlen($dir)) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('V', 16) + .pack('V', $this->offset) + .$dir; + + $this->offset = $newoffset; + $this->directory[] = $record; + } + + // -------------------------------------------------------------------- + + /** + * Add Data to Zip + * + * Lets you add files to the archive. If the path is included + * in the filename it will be placed within a directory. Make + * sure you use add_dir() first to create the folder. + * + * @access public + * @param mixed + * @param string + * @return void + */ + function add_data($filepath, $data = NULL) + { + if (is_array($filepath)) + { + foreach ($filepath as $path => $data) + { + $this->_add_data($path, $data); + } + } + else + { + $this->_add_data($filepath, $data); + } + } + + // -------------------------------------------------------------------- + + /** + * Add Data to Zip + * + * @access private + * @param string the file name/path + * @param string the data to be encoded + * @return void + */ + function _add_data($filepath, $data) + { + $filepath = str_replace("\\", "/", $filepath); + + $oldlen = strlen($data); + $crc32 = crc32($data); + + $gzdata = gzcompress($data); + $gzdata = substr($gzdata, 2, -4); + $newlen = strlen($gzdata); + + $this->zipdata[] = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + .pack('V', $crc32) + .pack('V', $newlen) + .pack('V', $oldlen) + .pack('v', strlen($filepath)) + .pack('v', 0) + .$filepath + .$gzdata; + + $newoffset = strlen(implode("", $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + .pack('V', $crc32) + .pack('V', $newlen) + .pack('V', $oldlen) + .pack('v', strlen($filepath)) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('V', 32) + .pack('V', $this->offset); + + $this->offset = $newoffset; + $this->directory[] = $record.$filepath; + } + + // -------------------------------------------------------------------- + + /** + * Read the contents of a file and add it to the zip + * + * @access public + * @return bool + */ + function read_file($path, $preserve_filepath = FALSE) + { + if ( ! file_exists($path)) + { + return FALSE; + } + + if (FALSE !== ($data = file_get_contents($path))) + { + $name = str_replace("\\", "/", $path); + + if ($preserve_filepath === FALSE) + { + $name = preg_replace("|.*/(.+)|", "\\1", $name); + } + + $this->add_data($name, $data); + return TRUE; + } + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Read a directory and add it to the zip. + * + * This function recursively reads a folder and everything it contains (including + * sub-folders) and creates a zip based on it. Whatever directory structure + * is in the original file path will be recreated in the zip file. + * + * @access public + * @param string path to source + * @return bool + */ + function read_dir($path) + { + if ($fp = @opendir($path)) + { + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($path.$file) && substr($file, 0, 1) != '.') + { + $this->read_dir($path.$file."/"); + } + elseif (substr($file, 0, 1) != ".") + { + if (FALSE !== ($data = file_get_contents($path.$file))) + { + $this->add_data(str_replace("\\", "/", $path).$file, $data); + } + } + } + return TRUE; + } + } + + // -------------------------------------------------------------------- + + /** + * Get the Zip file + * + * @access public + * @return binary string + */ + function get_zip() + { + // We cache the zip data so multiple calls + // do not require recompiling + if ($this->zipfile != '') + { + return $this->zipfile; + } + + // Is there any data to return? + if (count($this->zipdata) == 0) + { + return FALSE; + } + + $data = implode('', $this->zipdata); + $dir = implode('', $this->directory); + + $this->zipfile = $data.$dir."\x50\x4b\x05\x06\x00\x00\x00\x00" + .pack('v', sizeof($this->directory)) + .pack('v', sizeof($this->directory)) + .pack('V', strlen($dir)) + .pack('V', strlen($data)) + ."\x00\x00"; + + return $this->zipfile; + } + + // -------------------------------------------------------------------- + + /** + * Write File to the specified directory + * + * Lets you write a file + * + * @access public + * @param string the file name + * @param string the data to be encoded + * @return bool + */ + function archive($filepath) + { + if ( ! ($fp = @fopen($filepath, "wb"))) + { + return FALSE; + } + + flock($fp, LOCK_EX); + fwrite($fp, $this->get_zip()); + flock($fp, LOCK_UN); + fclose($fp); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Download + * + * @access public + * @param string the file name + * @param string the data to be encoded + * @return bool + */ + function download($filename = 'backup.zip') + { + if ( ! preg_match("|.+?\.zip$|", $filename)) + { + $filename .= '.zip'; + } + + if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: inline; filename="'.$filename.'"'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header("Content-Transfer-Encoding: binary"); + header('Pragma: public'); + header("Content-Length: ".strlen($this->get_zip())); + } + else + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: attachment; filename="'.$filename.'"'); + header("Content-Transfer-Encoding: binary"); + header('Expires: 0'); + header('Pragma: no-cache'); + header("Content-Length: ".strlen($this->get_zip())); + } + + echo $this->get_zip(); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Data + * + * Lets you clear current zip data. Useful if you need to create + * multiple zips with different data. + * + * @access public + * @return void + */ + function clear_data() + { + $this->zipfile = ''; + $this->zipdata = array(); + $this->directory = array(); + $this->offset = array(); + } + +} +?> \ No newline at end of file diff --git a/system/libraries/.svn/text-base/index.html.svn-base b/system/libraries/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/libraries/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/libraries/Benchmark.php b/system/libraries/Benchmark.php new file mode 100755 index 0000000..bca3782 --- /dev/null +++ b/system/libraries/Benchmark.php @@ -0,0 +1,111 @@ +marker[$name] = microtime(); + } + + // -------------------------------------------------------------------- + + /** + * Calculates the time difference between two marked points. + * + * If the first parameter is empty this function instead returns the + * {elapsed_time} pseudo-variable. This permits the full system + * execution time to be shown in a template. The output class will + * swap the real value for this variable. + * + * @access public + * @param string a particular marked point + * @param string a particular marked point + * @param integer the number of decimal places + * @return mixed + */ + function elapsed_time($point1 = '', $point2 = '', $decimals = 4) + { + if ($point1 == '') + { + return '{elapsed_time}'; + } + + if ( ! isset($this->marker[$point1])) + { + return ''; + } + + if ( ! isset($this->marker[$point2])) + { + $this->marker[$point2] = microtime(); + } + + list($sm, $ss) = explode(' ', $this->marker[$point1]); + list($em, $es) = explode(' ', $this->marker[$point2]); + + return number_format(($em + $es) - ($sm + $ss), $decimals); + } + + // -------------------------------------------------------------------- + + /** + * Memory Usage + * + * This function returns the {memory_usage} pseudo-variable. + * This permits it to be put it anywhere in a template + * without the memory being calculated until the end. + * The output class will swap the real value for this variable. + * + * @access public + * @return string + */ + function memory_usage() + { + return '{memory_usage}'; + } + +} + +// END CI_Benchmark class +?> \ No newline at end of file diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php new file mode 100755 index 0000000..a85c183 --- /dev/null +++ b/system/libraries/Calendar.php @@ -0,0 +1,475 @@ +CI =& get_instance(); + + if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE)) + { + $this->CI->lang->load('calendar'); + } + + $this->local_time = time(); + + if (count($config) > 0) + { + $this->initialize($config); + } + + log_message('debug', "Calendar Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the user preferences + * + * Accepts an associative array as input, containing display preferences + * + * @access public + * @param array config preferences + * @return void + */ + function initialize($config = array()) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Generate the calendar + * + * @access public + * @param integer the year + * @param integer the month + * @param array the data to be shown in the calendar cells + * @return string + */ + function generate($year = '', $month = '', $data = array()) + { + // Set and validate the supplied month/year + if ($year == '') + $year = date("Y", $this->local_time); + + if ($month == '') + $month = date("m", $this->local_time); + + if (strlen($year) == 1) + $year = '200'.$year; + + if (strlen($year) == 2) + $year = '20'.$year; + + if (strlen($month) == 1) + $month = '0'.$month; + + $adjusted_date = $this->adjust_date($month, $year); + + $month = $adjusted_date['month']; + $year = $adjusted_date['year']; + + // Determine the total days in the month + $total_days = $this->get_total_days($month, $year); + + // Set the starting day of the week + $start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6); + $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day]; + + // Set the starting day number + $local_date = mktime(12, 0, 0, $month, 1, $year); + $date = getdate($local_date); + $day = $start_day + 1 - $date["wday"]; + + while ($day > 1) + { + $day -= 7; + } + + // Set the current month/year/day + // We use this to determine the "today" date + $cur_year = date("Y", $this->local_time); + $cur_month = date("m", $this->local_time); + $cur_day = date("j", $this->local_time); + + $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE; + + // Generate the template data array + $this->parse_template(); + + // Begin building the calendar output + $out = $this->temp['table_open']; + $out .= "\n"; + + $out .= "\n"; + $out .= $this->temp['heading_row_start']; + $out .= "\n"; + + // "previous" month link + if ($this->show_next_prev == TRUE) + { + // Add a trailing slash to the URL if needed + $this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url); + + $adjusted_date = $this->adjust_date($month - 1, $year); + $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']); + $out .= "\n"; + } + + // Heading containing the month/year + $colspan = ($this->show_next_prev == TRUE) ? 5 : 7; + + $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']); + $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)." ".$year, $this->temp['heading_title_cell']); + + $out .= $this->temp['heading_title_cell']; + $out .= "\n"; + + // "next" month link + if ($this->show_next_prev == TRUE) + { + $adjusted_date = $this->adjust_date($month + 1, $year); + $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']); + } + + $out .= "\n"; + $out .= $this->temp['heading_row_end']; + $out .= "\n"; + + // Write the cells containing the days of the week + $out .= "\n"; + $out .= $this->temp['week_row_start']; + $out .= "\n"; + + $day_names = $this->get_day_names(); + + for ($i = 0; $i < 7; $i ++) + { + $out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']); + } + + $out .= "\n"; + $out .= $this->temp['week_row_end']; + $out .= "\n"; + + // Build the main body of the calendar + while ($day <= $total_days) + { + $out .= "\n"; + $out .= $this->temp['cal_row_start']; + $out .= "\n"; + + for ($i = 0; $i < 7; $i++) + { + $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start']; + + if ($day > 0 AND $day <= $total_days) + { + if (isset($data[$day])) + { + // Cells with content + $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content']; + $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp)); + } + else + { + // Cells with no content + $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content']; + $out .= str_replace('{day}', $day, $temp); + } + } + else + { + // Blank cells + $out .= $this->temp['cal_cell_blank']; + } + + $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; + $day++; + } + + $out .= "\n"; + $out .= $this->temp['cal_row_end']; + $out .= "\n"; + } + + $out .= "\n"; + $out .= $this->temp['table_close']; + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Get Month Name + * + * Generates a textual month name based on the numeric + * month provided. + * + * @access public + * @param integer the month + * @return string + */ + function get_month_name($month) + { + if ($this->month_type == 'short') + { + $month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec'); + } + else + { + $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_may', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december'); + } + + $month = $month_names[$month]; + + if ($this->CI->lang->line($month) === FALSE) + { + return ucfirst(str_replace('cal_', '', $month)); + } + + return $this->CI->lang->line($month); + } + + // -------------------------------------------------------------------- + + /** + * Get Day Names + * + * Returns an array of day names (Sunday, Monday, etc.) based + * on the type. Options: long, short, abrev + * + * @access public + * @param string + * @return array + */ + function get_day_names($day_type = '') + { + if ($day_type != '') + $this->day_type = $day_type; + + if ($this->day_type == 'long') + { + $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); + } + elseif ($this->day_type == 'short') + { + $day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'); + } + else + { + $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'); + } + + $days = array(); + foreach ($day_names as $val) + { + $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val); + } + + return $days; + } + + // -------------------------------------------------------------------- + + /** + * Adjust Date + * + * This function makes sure that we have a valid month/year. + * For example, if you submit 13 as the month, the year will + * increment and the month will become January. + * + * @access public + * @param integer the month + * @param integer the year + * @return array + */ + function adjust_date($month, $year) + { + $date = array(); + + $date['month'] = $month; + $date['year'] = $year; + + while ($date['month'] > 12) + { + $date['month'] -= 12; + $date['year']++; + } + + while ($date['month'] <= 0) + { + $date['month'] += 12; + $date['year']--; + } + + if (strlen($date['month']) == 1) + { + $date['month'] = '0'.$date['month']; + } + + return $date; + } + + // -------------------------------------------------------------------- + + /** + * Total days in a given month + * + * @access public + * @param integer the month + * @param integer the year + * @return integer + */ + function get_total_days($month, $year) + { + $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + + if ($month < 1 OR $month > 12) + { + return 0; + } + + // Is the year a leap year? + if ($month == 2) + { + if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0)) + { + return 29; + } + } + + return $days_in_month[$month - 1]; + } + + // -------------------------------------------------------------------- + + /** + * Set Default Template Data + * + * This is used in the event that the user has not created their own template + * + * @access public + * @return array + */ + function default_template() + { + return array ( + 'table_open' => '', + 'heading_row_start' => '', + 'heading_previous_cell' => '', + 'heading_title_cell' => '', + 'heading_next_cell' => '', + 'heading_row_end' => '', + 'week_row_start' => '', + 'week_day_cell' => '', + 'week_row_end' => '', + 'cal_row_start' => '', + 'cal_cell_start' => '', + 'cal_cell_end_today' => '', + 'cal_row_end' => '', + 'table_close' => '
    <<{heading}>>
    {week_day}
    ', + 'cal_cell_start_today' => '', + 'cal_cell_content' => '{day}', + 'cal_cell_content_today' => '{day}', + 'cal_cell_no_content' => '{day}', + 'cal_cell_no_content_today' => '{day}', + 'cal_cell_blank' => ' ', + 'cal_cell_end' => '
    ' + ); + } + + // -------------------------------------------------------------------- + + /** + * Parse Template + * + * Harvests the data within the template {pseudo-variables} + * used to display the calendar + * + * @access public + * @return void + */ + function parse_template() + { + $this->temp = $this->default_template(); + + if ($this->template == '') + { + return; + } + + $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today'); + + foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val) + { + if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match)) + { + $this->temp[$val] = $match['1']; + } + else + { + if (in_array($val, $today, TRUE)) + { + $this->temp[$val] = $this->temp[str_replace('_today', '', $val)]; + } + } + } + } + +} + +// END CI_Calendar class +?> \ No newline at end of file diff --git a/system/libraries/Config.php b/system/libraries/Config.php new file mode 100755 index 0000000..9b8b07c --- /dev/null +++ b/system/libraries/Config.php @@ -0,0 +1,245 @@ +config =& get_config(); + log_message('debug', "Config Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Load Config File + * + * @access public + * @param string the config file name + * @return boolean if the file was loaded correctly + */ + function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + { + $file = ($file == '') ? 'config' : str_replace(EXT, '', $file); + + if (in_array($file, $this->is_loaded, TRUE)) + { + return TRUE; + } + + if ( ! file_exists(APPPATH.'config/'.$file.EXT)) + { + if ($fail_gracefully === TRUE) + { + return FALSE; + } + show_error('The configuration file '.$file.EXT.' does not exist.'); + } + + include(APPPATH.'config/'.$file.EXT); + + if ( ! isset($config) OR ! is_array($config)) + { + if ($fail_gracefully === TRUE) + { + return FALSE; + } + show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.'); + } + + if ($use_sections === TRUE) + { + if (isset($this->config[$file])) + { + $this->config[$file] = array_merge($this->config[$file], $config); + } + else + { + $this->config[$file] = $config; + } + } + else + { + $this->config = array_merge($this->config, $config); + } + + $this->is_loaded[] = $file; + unset($config); + + log_message('debug', 'Config file loaded: config/'.$file.EXT); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a config file item + * + * + * @access public + * @param string the config item name + * @param string the index name + * @param bool + * @return string + */ + function item($item, $index = '') + { + if ($index == '') + { + if ( ! isset($this->config[$item])) + { + return FALSE; + } + + $pref = $this->config[$item]; + } + else + { + if ( ! isset($this->config[$index])) + { + return FALSE; + } + + if ( ! isset($this->config[$index][$item])) + { + return FALSE; + } + + $pref = $this->config[$index][$item]; + } + + return $pref; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a config file item - adds slash after item + * + * The second parameter allows a slash to be added to the end of + * the item, in the case of a path. + * + * @access public + * @param string the config item name + * @param bool + * @return string + */ + function slash_item($item) + { + if ( ! isset($this->config[$item])) + { + return FALSE; + } + + $pref = $this->config[$item]; + + if ($pref != '') + { + if (ereg("/$", $pref) === FALSE) + { + $pref .= '/'; + } + } + + return $pref; + } + + // -------------------------------------------------------------------- + + /** + * Site URL + * + * @access public + * @param string the URI string + * @return string + */ + function site_url($uri = '') + { + if (is_array($uri)) + { + $uri = implode('/', $uri); + } + + if ($uri == '') + { + return $this->slash_item('base_url').$this->item('index_page'); + } + else + { + $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); + return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix; + } + } + + // -------------------------------------------------------------------- + + /** + * System URL + * + * @access public + * @return string + */ + function system_url() + { + $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH)); + return $this->slash_item('base_url').end($x).'/'; + } + + // -------------------------------------------------------------------- + + /** + * Set a config file item + * + * @access public + * @param string the config item key + * @param string the config item value + * @return void + */ + function set_item($item, $value) + { + $this->config[$item] = $value; + } + +} + +// END CI_Config class +?> \ No newline at end of file diff --git a/system/libraries/Controller.php b/system/libraries/Controller.php new file mode 100755 index 0000000..ad9c668 --- /dev/null +++ b/system/libraries/Controller.php @@ -0,0 +1,124 @@ +_ci_initialize(); + log_message('debug', "Controller Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize + * + * Assigns all the bases classes loaded by the front controller to + * variables in this class. Also calls the autoload routine. + * + * @access private + * @return void + */ + function _ci_initialize() + { + // Assign all the class objects that were instantiated by the + // front controller to local class variables so that CI can be + // run as one big super object. + $classes = array( + 'config' => 'Config', + 'input' => 'Input', + 'benchmark' => 'Benchmark', + 'uri' => 'URI', + 'output' => 'Output', + 'lang' => 'Language' + ); + + foreach ($classes as $var => $class) + { + $this->$var =& load_class($class); + } + + // In PHP 5 the Loader class is run as a discreet + // class. In PHP 4 it extends the Controller + if (floor(phpversion()) >= 5) + { + $this->load =& load_class('Loader'); + $this->load->_ci_autoloader(); + } + else + { + $this->_ci_autoloader(); + + // sync up the objects since PHP4 was working from a copy + foreach (array_keys(get_object_vars($this)) as $attribute) + { + if (is_object($this->$attribute)) + { + $this->load->$attribute =& $this->$attribute; + } + } + } + } + + // -------------------------------------------------------------------- + + /** + * Run Scaffolding + * + * @access private + * @return void + */ + function _ci_scaffolding() + { + if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE) + { + show_404('Scaffolding unavailable'); + } + + $method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3); + + require_once(BASEPATH.'scaffolding/Scaffolding'.EXT); + $scaff = new Scaffolding($this->_ci_scaff_table); + $scaff->$method(); + } + + +} +// END _Controller class +?> \ No newline at end of file diff --git a/system/libraries/Email.php b/system/libraries/Email.php new file mode 100755 index 0000000..25e5963 --- /dev/null +++ b/system/libraries/Email.php @@ -0,0 +1,1828 @@ + 0) + { + $this->initialize($config); + } + + log_message('debug', "Email Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + $this->clear(); + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $method = 'set_'.$key; + + if (method_exists($this, $method)) + { + $this->$method($val); + } + else + { + $this->$key = $val; + } + } + } + $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; + $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Email Data + * + * @access public + * @return void + */ + function clear($clear_attachments = FALSE) + { + $this->_subject = ""; + $this->_body = ""; + $this->_finalbody = ""; + $this->_header_str = ""; + $this->_replyto_flag = FALSE; + $this->_recipients = array(); + $this->_headers = array(); + $this->_debug_msg = array(); + + $this->_set_header('User-Agent', $this->useragent); + $this->_set_header('Date', $this->_set_date()); + + if ($clear_attachments !== FALSE) + { + $this->_attach_name = array(); + $this->_attach_type = array(); + $this->_attach_disp = array(); + } + } + + // -------------------------------------------------------------------- + + /** + * Set FROM + * + * @access public + * @param string + * @param string + * @return void + */ + function from($from, $name = '') + { + if (preg_match( '/\<(.*)\>/', $from, $match)) + $from = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($from)); + + if ($name != '' && substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('From', $name.' <'.$from.'>'); + $this->_set_header('Return-Path', '<'.$from.'>'); + } + + // -------------------------------------------------------------------- + + /** + * Set Reply-to + * + * @access public + * @param string + * @param string + * @return void + */ + function reply_to($replyto, $name = '') + { + if (preg_match( '/\<(.*)\>/', $replyto, $match)) + $replyto = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($replyto)); + + if ($name == '') + { + $name = $replyto; + } + + if (substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('Reply-To', $name.' <'.$replyto.'>'); + $this->_replyto_flag = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Recipients + * + * @access public + * @param string + * @return void + */ + function to($to) + { + $to = $this->_str_to_array($to); + $to = $this->clean_email($to); + + if ($this->validate) + $this->validate_email($to); + + if ($this->_get_protocol() != 'mail') + $this->_set_header('To', implode(", ", $to)); + + switch ($this->_get_protocol()) + { + case 'smtp' : $this->_recipients = $to; + break; + case 'sendmail' : $this->_recipients = implode(", ", $to); + break; + case 'mail' : $this->_recipients = implode(", ", $to); + break; + } + } + + // -------------------------------------------------------------------- + + /** + * Set CC + * + * @access public + * @param string + * @return void + */ + function cc($cc) + { + $cc = $this->_str_to_array($cc); + $cc = $this->clean_email($cc); + + if ($this->validate) + $this->validate_email($cc); + + $this->_set_header('Cc', implode(", ", $cc)); + + if ($this->_get_protocol() == "smtp") + $this->_cc_array = $cc; + } + + // -------------------------------------------------------------------- + + /** + * Set BCC + * + * @access public + * @param string + * @param string + * @return void + */ + function bcc($bcc, $limit = '') + { + if ($limit != '' && is_numeric($limit)) + { + $this->bcc_batch_mode = TRUE; + $this->bcc_batch_size = $limit; + } + + $bcc = $this->_str_to_array($bcc); + $bcc = $this->clean_email($bcc); + + if ($this->validate) + $this->validate_email($bcc); + + if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size)) + $this->_bcc_array = $bcc; + else + $this->_set_header('Bcc', implode(", ", $bcc)); + } + + // -------------------------------------------------------------------- + + /** + * Set Email Subject + * + * @access public + * @param string + * @return void + */ + function subject($subject) + { + $subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject); + $subject = preg_replace("/(\t)/", " ", $subject); + + $this->_set_header('Subject', trim($subject)); + } + + // -------------------------------------------------------------------- + + /** + * Set Body + * + * @access public + * @param string + * @return void + */ + function message($body) + { + $this->_body = stripslashes(rtrim(str_replace("\r", "", $body))); + } + + // -------------------------------------------------------------------- + + /** + * Assign file attachments + * + * @access public + * @param string + * @return string + */ + function attach($filename, $disposition = 'attachment') + { + $this->_attach_name[] = $filename; + $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); + $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters + } + + // -------------------------------------------------------------------- + + /** + * Add a Header Item + * + * @access public + * @param string + * @param string + * @return void + */ + function _set_header($header, $value) + { + $this->_headers[$header] = $value; + } + + // -------------------------------------------------------------------- + + /** + * Convert a String to an Array + * + * @access public + * @param string + * @return array + */ + function _str_to_array($email) + { + if ( ! is_array($email)) + { + if (ereg(',$', $email)) + $email = substr($email, 0, -1); + + if (ereg('^,', $email)) + $email = substr($email, 1); + + if (ereg(',', $email)) + { + $x = explode(',', $email); + $email = array(); + + for ($i = 0; $i < count($x); $i ++) + $email[] = trim($x[$i]); + } + else + { + $email = trim($email); + settype($email, "array"); + } + } + return $email; + } + + // -------------------------------------------------------------------- + + /** + * Set Multipart Value + * + * @access public + * @param string + * @return void + */ + function set_alt_message($str = '') + { + $this->alt_message = ($str == '') ? '' : $str; + } + + // -------------------------------------------------------------------- + + /** + * Set Mailtype + * + * @access public + * @param string + * @return void + */ + function set_mailtype($type = 'text') + { + $this->mailtype = ($type == 'html') ? 'html' : 'text'; + } + + // -------------------------------------------------------------------- + + /** + * Set Wordwrap + * + * @access public + * @param string + * @return void + */ + function set_wordwrap($wordwrap = TRUE) + { + $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Protocol + * + * @access public + * @param string + * @return void + */ + function set_protocol($protocol = 'mail') + { + $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol); + } + + // -------------------------------------------------------------------- + + /** + * Set Priority + * + * @access public + * @param integer + * @return void + */ + function set_priority($n = 3) + { + if ( ! is_numeric($n)) + { + $this->priority = 3; + return; + } + + if ($n < 1 OR $n > 5) + { + $this->priority = 3; + return; + } + + $this->priority = $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Newline Character + * + * @access public + * @param string + * @return void + */ + function set_newline($newline = "\n") + { + if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r") + { + $this->newline = "\n"; + return; + } + + $this->newline = $newline; + } + + // -------------------------------------------------------------------- + + /** + * Set Message Boundary + * + * @access private + * @return void + */ + function _set_boundaries() + { + $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative + $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary + } + + // -------------------------------------------------------------------- + + /** + * Get the Message ID + * + * @access private + * @return string + */ + function _get_message_id() + { + $from = $this->_headers['Return-Path']; + $from = str_replace(">", "", $from); + $from = str_replace("<", "", $from); + + return "<".uniqid('').strstr($from, '@').">"; + } + + // -------------------------------------------------------------------- + + /** + * Get Mail Protocol + * + * @access private + * @param bool + * @return string + */ + function _get_protocol($return = TRUE) + { + $this->protocol = strtolower($this->protocol); + $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol; + + if ($return == TRUE) + return $this->protocol; + } + + // -------------------------------------------------------------------- + + /** + * Get Mail Encoding + * + * @access private + * @param bool + * @return string + */ + function _get_encoding($return = TRUE) + { + $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding; + + foreach ($this->_base_charsets as $charset) + { + if (strncmp($charset, $this->charset, strlen($charset)) == 0) + { + $this->_encoding = '7bit'; + } + } + + if ($return == TRUE) + { + return $this->_encoding; + } + } + + // -------------------------------------------------------------------- + + /** + * Get content type (text/html/attachment) + * + * @access private + * @return string + */ + function _get_content_type() + { + if ($this->mailtype == 'html' && count($this->_attach_name) == 0) + return 'html'; + + elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0) + return 'html-attach'; + + elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0) + return 'plain-attach'; + + else return 'plain'; + } + + // -------------------------------------------------------------------- + + /** + * Set RFC 822 Date + * + * @access public + * @return string + */ + function _set_date() + { + $timezone = date("Z"); + $operator = (substr($timezone, 0, 1) == '-') ? '-' : '+'; + $timezone = abs($timezone); + $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60; + + return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone); + } + + // -------------------------------------------------------------------- + + /** + * Mime message + * + * @access private + * @return string + */ + function _get_mime_message() + { + return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format."; + } + + // -------------------------------------------------------------------- + + /** + * Validate Email Address + * + * @access public + * @param string + * @return bool + */ + function validate_email($email) + { + if ( ! is_array($email)) + { + $this->_set_error_message('email_must_be_array'); + return FALSE; + } + + foreach ($email as $val) + { + if ( ! $this->valid_email($val)) + { + $this->_set_error_message('email_invalid_address', $val); + return FALSE; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Email Validation + * + * @access public + * @param string + * @return bool + */ + function valid_email($address) + { + if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) + return FALSE; + else + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Clean Extended Email Address: Joe Smith + * + * @access public + * @param string + * @return string + */ + function clean_email($email) + { + if ( ! is_array($email)) + { + if (preg_match('/\<(.*)\>/', $email, $match)) + return $match['1']; + else + return $email; + } + + $clean_email = array(); + + foreach ($email as $addy) + { + if (preg_match( '/\<(.*)\>/', $addy, $match)) + { + $clean_email[] = $match['1']; + } + else + { + $clean_email[] = $addy; + } + } + + return $clean_email; + } + + // -------------------------------------------------------------------- + + /** + * Build alternative plain text message + * + * This function provides the raw message for use + * in plain-text headers of HTML-formatted emails. + * If the user hasn't specified his own alternative message + * it creates one by stripping the HTML + * + * @access private + * @return string + */ + function _get_alt_message() + { + if ($this->alt_message != "") + { + return $this->word_wrap($this->alt_message, '76'); + } + + if (eregi( '\', $this->_body, $match)) + { + $body = $match['1']; + $body = substr($body, strpos($body, ">") + 1); + } + else + { + $body = $this->_body; + } + + $body = trim(strip_tags($body)); + $body = preg_replace( '# '.$message. ' '.$filepath.' '.$line, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * 404 Page Not Found Handler + * + * @access private + * @param string + * @return string + */ + function show_404($page = '') + { + $heading = "404 Page Not Found"; + $message = "The page you requested was not found."; + + log_message('error', '404 Page Not Found --> '.$page); + echo $this->show_error($heading, $message, 'error_404'); + exit; + } + + // -------------------------------------------------------------------- + + /** + * General Error Page + * + * This function takes an error message as input + * (either as a string or an array) and displays + * it using the specified template. + * + * @access private + * @param string the heading + * @param string the message + * @param string the template name + * @return string + */ + function show_error($heading, $message, $template = 'error_general') + { + $message = '

    '.implode('

    ', ( ! is_array($message)) ? array($message) : $message).'

    '; + + if (ob_get_level() > $this->ob_level + 1) + { + ob_end_flush(); + } + ob_start(); + include(APPPATH.'errors/'.$template.EXT); + $buffer = ob_get_contents(); + ob_end_clean(); + return $buffer; + } + + // -------------------------------------------------------------------- + + /** + * Native PHP error handler + * + * @access private + * @param string the error severity + * @param string the error string + * @param string the error filepath + * @param string the error line number + * @return string + */ + function show_php_error($severity, $message, $filepath, $line) + { + $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity]; + + $filepath = str_replace("\\", "/", $filepath); + + // For safety reasons we do not show the full file path + if (FALSE !== strpos($filepath, '/')) + { + $x = explode('/', $filepath); + $filepath = $x[count($x)-2].'/'.end($x); + } + + if (ob_get_level() > $this->ob_level + 1) + { + ob_end_flush(); + } + ob_start(); + include(APPPATH.'errors/error_php'.EXT); + $buffer = ob_get_contents(); + ob_end_clean(); + echo $buffer; + } + + +} +// END Exceptions Class +?> \ No newline at end of file diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php new file mode 100755 index 0000000..ed934b5 --- /dev/null +++ b/system/libraries/Ftp.php @@ -0,0 +1,616 @@ + 0) + { + $this->initialize($config); + } + + log_message('debug', "FTP Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + + // Prep the hostname + $this->hostname = preg_replace('|.+?://|', '', $this->hostname); + } + + // -------------------------------------------------------------------- + + /** + * FTP Connect + * + * @access public + * @param array the connection values + * @return bool + */ + function connect($config = array()) + { + if (count($config) > 0) + { + $this->initialize($config); + } + + if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port))) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_connect'); + } + return FALSE; + } + + if ( ! $this->_login()) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_login'); + } + return FALSE; + } + + // Set passive mode if needed + if ($this->passive == TRUE) + { + ftp_pasv($this->conn_id, TRUE); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * FTP Login + * + * @access private + * @return bool + */ + function _login() + { + return @ftp_login($this->conn_id, $this->username, $this->password); + } + + // -------------------------------------------------------------------- + + /** + * Validates the connection ID + * + * @access private + * @return bool + */ + function _is_conn() + { + if ( ! is_resource($this->conn_id)) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_no_connection'); + } + return FALSE; + } + return TRUE; + } + + // -------------------------------------------------------------------- + + + /** + * Change direcotry + * + * The second parameter lets us momentarily turn off debugging so that + * this function can be used to test for the existance of a folder + * without throwing an error. There's no FTP equivalent to is_dir() + * so we do it by trying to change to a particular directory. + * Internally, this paramter is only used by the "mirror" function below. + * + * @access public + * @param string + * @param bool + * @return bool + */ + function changedir($path = '', $supress_debug = FALSE) + { + if ($path == '' OR ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_chdir($this->conn_id, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE AND $supress_debug == FALSE) + { + $this->_error('ftp_unable_to_changedir'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Create a directory + * + * @access public + * @param string + * @return bool + */ + function mkdir($path = '', $permissions = NULL) + { + if ($path == '' OR ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_mkdir($this->conn_id, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_makdir'); + } + return FALSE; + } + + // Set file permissions if needed + if ( ! is_null($permissions)) + { + $this->chmod($path, (int)$permissions); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Upload a file to the server + * + * @access public + * @param string + * @param string + * @param string + * @return bool + */ + function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + if ( ! file_exists($locpath)) + { + $this->_error('ftp_no_source_file'); + return FALSE; + } + + // Set the mode if not specified + if ($mode == 'auto') + { + // Get the file extension so we can set the upload type + $ext = $this->_getext($locpath); + $mode = $this->_settype($ext); + } + + $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; + + $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_upload'); + } + return FALSE; + } + + // Set file permissions if needed + if ( ! is_null($permissions)) + { + $this->chmod($rempath, (int)$permissions); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Rename (or move) a file + * + * @access public + * @param string + * @param string + * @param bool + * @return bool + */ + function rename($old_file, $new_file, $move = FALSE) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_rename($this->conn_id, $old_file, $new_file); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move'; + + $this->_error($msg); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Move a file + * + * @access public + * @param string + * @param string + * @return bool + */ + function move($old_file, $new_file) + { + return $this->rename($old_file, $new_file, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Rename (or move) a file + * + * @access public + * @param string + * @return bool + */ + function delete_file($filepath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + $result = @ftp_delete($this->conn_id, $filepath); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_delete'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Delete a folder and recursively delete everything (including sub-folders) + * containted within it. + * + * @access public + * @param string + * @return bool + */ + function delete_dir($filepath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Add a trailing slash to the file path if needed + $filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath); + + $list = $this->list_files($filepath); + + if ($list !== FALSE AND count($list) > 0) + { + foreach ($list as $item) + { + // If we can't delete the item it's probaly a folder so + // we'll recursively call delete_dir() + if ( ! @ftp_delete($this->conn_id, $filepath.$item)) + { + $this->delete_dir($filepath.$item); + } + } + } + + $result = @ftp_rmdir($this->conn_id, $filepath); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_delete'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set file permissions + * + * @access public + * @param string the file path + * @param string the permissions + * @return bool + */ + function chmod($path, $perm) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Permissions can only be set when running PHP 5 + if ( ! function_exists('ftp_chmod')) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_chmod'); + } + return FALSE; + } + + $result = @ftp_chmod($this->conn_id, $perm, $path); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_chmod'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * FTP List files in the specified directory + * + * @access public + * @return array + */ + function list_files($path = '.') + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + return ftp_nlist($this->conn_id, $path); + } + + // ------------------------------------------------------------------------ + + /** + * Read a directory and recreate it remotely + * + * This function recursively reads a folder and everything it contains (including + * sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure + * of the original file path will be recreated on the server. + * + * @access public + * @param string path to source with trailing slash + * @param string path to destination - include the base folder with trailing slash + * @return bool + */ + function mirror($locpath, $rempath) + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Open the local file path + if ($fp = @opendir($locpath)) + { + // Attempt to open the remote file path. + if ( ! $this->changedir($rempath, TRUE)) + { + // If it doesn't exist we'll attempt to create the direcotory + if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath)) + { + return FALSE; + } + } + + // Recursively read the local directory + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.') + { + $this->mirror($locpath.$file."/", $rempath.$file."/"); + } + elseif (substr($file, 0, 1) != ".") + { + // Get the file extension so we can se the upload type + $ext = $this->_getext($file); + $mode = $this->_settype($ext); + + $this->upload($locpath.$file, $rempath.$file, $mode); + } + } + return TRUE; + } + + return FALSE; + } + + + // -------------------------------------------------------------------- + + /** + * Extract the file extension + * + * @access private + * @param string + * @return string + */ + function _getext($filename) + { + if (FALSE === strpos($filename, '.')) + { + return 'txt'; + } + + $x = explode('.', $filename); + return end($x); + } + + + // -------------------------------------------------------------------- + + /** + * Set the upload type + * + * @access private + * @param string + * @return string + */ + function _settype($ext) + { + $text_types = array( + 'txt', + 'text', + 'php', + 'phps', + 'php4', + 'js', + 'css', + 'htm', + 'html', + 'phtml', + 'shtml', + 'log', + 'xml' + ); + + + return (in_array($ext, $text_types)) ? 'ascii' : 'binary'; + } + + // ------------------------------------------------------------------------ + + /** + * Close the connection + * + * @access public + * @param string path to source + * @param string path to destination + * @return bool + */ + function close() + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + @ftp_close($this->conn_id); + } + + // ------------------------------------------------------------------------ + + /** + * Display error message + * + * @access private + * @param string + * @return bool + */ + function _error($line) + { + $CI =& get_instance(); + $CI->lang->load('ftp'); + show_error($CI->lang->line($line)); + } + + +} +// END FTP Class +?> \ No newline at end of file diff --git a/system/libraries/Hooks.php b/system/libraries/Hooks.php new file mode 100755 index 0000000..49cb230 --- /dev/null +++ b/system/libraries/Hooks.php @@ -0,0 +1,224 @@ +_initialize(); + log_message('debug', "Hooks Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize the Hooks Preferences + * + * @access private + * @return void + */ + function _initialize() + { + $CFG =& load_class('Config'); + + // If hooks are not enabled in the config file + // there is nothing else to do + + if ($CFG->item('enable_hooks') == FALSE) + { + return; + } + + // Grab the "hooks" definition file. + // If there are no hooks, we're done. + + @include(APPPATH.'config/hooks'.EXT); + + if ( ! isset($hook) OR ! is_array($hook)) + { + return; + } + + $this->hooks =& $hook; + $this->enabled = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Call Hook + * + * Calls a particular hook + * + * @access private + * @param string the hook name + * @return mixed + */ + function _call_hook($which = '') + { + if ( ! $this->enabled OR ! isset($this->hooks[$which])) + { + return FALSE; + } + + if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) + { + foreach ($this->hooks[$which] as $val) + { + $this->_run_hook($val); + } + } + else + { + $this->_run_hook($this->hooks[$which]); + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Run Hook + * + * Runs a particular hook + * + * @access private + * @param array the hook details + * @return bool + */ + function _run_hook($data) + { + if ( ! is_array($data)) + { + return FALSE; + } + + // ----------------------------------- + // Safety - Prevents run-away loops + // ----------------------------------- + + // If the script being called happens to have the same + // hook call within it a loop can happen + + if ($this->in_progress == TRUE) + { + return; + } + + // ----------------------------------- + // Set file path + // ----------------------------------- + + if ( ! isset($data['filepath']) OR ! isset($data['filename'])) + { + return FALSE; + } + + $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; + + if ( ! file_exists($filepath)) + { + return FALSE; + } + + // ----------------------------------- + // Set class/function name + // ----------------------------------- + + $class = FALSE; + $function = FALSE; + $params = ''; + + if (isset($data['class']) AND $data['class'] != '') + { + $class = $data['class']; + } + + if (isset($data['function'])) + { + $function = $data['function']; + } + + if (isset($data['params'])) + { + $params = $data['params']; + } + + if ($class === FALSE AND $function === FALSE) + { + return FALSE; + } + + // ----------------------------------- + // Set the in_progress flag + // ----------------------------------- + + $this->in_progress = TRUE; + + // ----------------------------------- + // Call the requested class and/or function + // ----------------------------------- + + if ($class !== FALSE) + { + if ( ! class_exists($class)) + { + require($filepath); + } + + $HOOK = new $class; + $HOOK->$function($params); + } + else + { + if ( ! function_exists($function)) + { + require($filepath); + } + + $function($params); + } + + $this->in_progress = FALSE; + return TRUE; + } + +} + +// END CI_Hooks class +?> \ No newline at end of file diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php new file mode 100755 index 0000000..dbb6f82 --- /dev/null +++ b/system/libraries/Image_lib.php @@ -0,0 +1,1530 @@ + 0) + { + $this->initialize($props); + } + + log_message('debug', "Image Lib Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize image properties + * + * Resets values in case this class is used in a loop + * + * @access public + * @return void + */ + function clear() + { + $props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity'); + + foreach ($props as $val) + { + $this->$val = ''; + } + + // special consideration for master_dim + $this->master_dim = 'auto'; + } + + // -------------------------------------------------------------------- + + /** + * initialize image preferences + * + * @access public + * @param array + * @return void + */ + function initialize($props = array()) + { + /* + * Convert array elements into class variables + */ + if (count($props) > 0) + { + foreach ($props as $key => $val) + { + $this->$key = $val; + } + } + + /* + * Is there a source image? + * + * If not, there's no reason to continue + * + */ + if ($this->source_image == '') + { + $this->set_error('imglib_source_image_required'); + return FALSE; + } + + /* + * Is getimagesize() Available? + * + * We use it to determine the image properties (width/height). + * Note: We need to figure out how to determine image + * properties using ImageMagick and NetPBM + * + */ + if ( ! function_exists('getimagesize')) + { + $this->set_error('imglib_gd_required_for_props'); + return FALSE; + } + + $this->image_library = strtolower($this->image_library); + + /* + * Set the full server path + * + * The source image may or may not contain a path. + * Either way, we'll try use realpath to generate the + * full server path in order to more reliably read it. + * + */ + if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE) + { + $full_source_path = str_replace("\\", "/", realpath($this->source_image)); + } + else + { + $full_source_path = $this->source_image; + } + + $x = explode('/', $full_source_path); + $this->source_image = end($x); + $this->source_folder = str_replace($this->source_image, '', $full_source_path); + + // Set the Image Properties + if ( ! $this->get_image_properties($this->source_folder.$this->source_image)) + { + return FALSE; + } + + /* + * Assign the "new" image name/path + * + * If the user has set a "new_image" name it means + * we are making a copy of the source image. If not + * it means we are altering the original. We'll + * set the destination filename and path accordingly. + * + */ + if ($this->new_image == '') + { + $this->dest_image = $this->source_image; + $this->dest_folder = $this->source_folder; + } + else + { + if (strpos($this->new_image, '/') === FALSE) + { + $this->dest_folder = $this->source_folder; + $this->dest_image = $this->new_image; + } + else + { + if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE) + { + $full_dest_path = str_replace("\\", "/", realpath($this->new_image)); + } + else + { + $full_dest_path = $this->new_image; + } + + // Is there a file name? + if ( ! preg_match("#[\.jpg|\.jpeg|\.gif|\.png]$#i", $full_dest_path)) + { + $this->dest_folder = $full_dest_path.'/'; + $this->dest_image = $this->source_image; + } + else + { + $x = explode('/', $full_dest_path); + $this->dest_image = end($x); + $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path); + } + } + } + + /* + * Compile the finalized filenames/paths + * + * We'll create two master strings containing the + * full server path to the source image and the + * full server path to the destination image. + * We'll also split the destination image name + * so we can insert the thumbnail marker if needed. + * + */ + if ($this->create_thumb === FALSE OR $this->thumb_marker == '') + { + $this->thumb_marker = ''; + } + + $xp = $this->explode_name($this->dest_image); + + $filename = $xp['name']; + $file_ext = $xp['ext']; + + $this->full_src_path = $this->source_folder.$this->source_image; + $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext; + + /* + * Should we maintain image proportions? + * + * When creating thumbs or copies, the target width/height + * might not be in correct proportion with the source + * image's width/height. We'll recalculate it here. + * + */ + if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != '')) + { + $this->image_reproportion(); + } + + /* + * Was a width and height specified? + * + * If the destination width/height was + * not submitted we will use the values + * from the actual file + * + */ + if ($this->width == '') + $this->width = $this->orig_width; + + if ($this->height == '') + $this->height = $this->orig_height; + + // Set the quality + $this->quality = trim(str_replace("%", "", $this->quality)); + + if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality)) + $this->quality = 90; + + // Set the x/y coordinates + $this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis; + $this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis; + + // Watermark-related Stuff... + if ($this->wm_font_color != '') + { + if (strlen($this->wm_font_color) == 6) + { + $this->wm_font_color = '#'.$this->wm_font_color; + } + } + + if ($this->wm_shadow_color != '') + { + if (strlen($this->wm_shadow_color) == 6) + { + $this->wm_shadow_color = '#'.$this->wm_shadow_color; + } + } + + if ($this->wm_overlay_path != '') + { + $this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path)); + } + + if ($this->wm_shadow_color != '') + { + $this->wm_use_drop_shadow = TRUE; + } + + if ($this->wm_font_path != '') + { + $this->wm_use_truetype = TRUE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Resize + * + * This is a wrapper function that chooses the proper + * resize function based on the protocol specified + * + * @access public + * @return bool + */ + function resize() + { + $protocol = 'image_process_'.$this->image_library; + + if (eregi("gd2$", $protocol)) + { + $protocol = 'image_process_gd'; + } + + return $this->$protocol('resize'); + } + + // -------------------------------------------------------------------- + + /** + * Image Crop + * + * This is a wrapper function that chooses the proper + * cropping function based on the protocol specified + * + * @access public + * @return bool + */ + function crop() + { + $protocol = 'image_process_'.$this->image_library; + + if (eregi("gd2$", $protocol)) + { + $protocol = 'image_process_gd'; + } + + return $this->$protocol('crop'); + } + + // -------------------------------------------------------------------- + + /** + * Image Rotate + * + * This is a wrapper function that chooses the proper + * rotation function based on the protocol specified + * + * @access public + * @return bool + */ + function rotate() + { + // Allowed rotation values + $degs = array(90, 180, 270, 'vrt', 'hor'); + + if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE)) + { + $this->set_error('imglib_rotation_angle_required'); + return FALSE; + } + + // Reassign the width and height + if ($this->rotation_angle == 90 OR $this->rotation_angle == 270) + { + $this->width = $this->orig_height; + $this->height = $this->orig_width; + } + else + { + $this->width = $this->orig_width; + $this->height = $this->orig_height; + } + + + // Choose resizing function + if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm') + { + $protocol = 'image_process_'.$this->image_library; + + return $this->$protocol('rotate'); + } + + if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt') + { + return $this->image_mirror_gd(); + } + else + { + return $this->image_rotate_gd(); + } + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using GD/GD2 + * + * This function will resize or crop + * + * @access public + * @param string + * @return bool + */ + function image_process_gd($action = 'resize') + { + $v2_override = FALSE; + + if ($action == 'crop') + { + // If the target width/height match the source then it's pointless to crop, right? + // So if dynamic output isn't on, then we'll return true so the user thinks + // the process succeeded. It'll be our little secret... + + if ($this->width >= $this->orig_width AND $this->height >= $this->orig_height AND $this->dynamic_output !== TRUE) + { + return TRUE; + } + + // Reassign the source width/height if cropping + $this->orig_width = $this->width; + $this->orig_height = $this->height; + + // GD 2.0 has a cropping bug so we'll test for it + if ($this->gd_version() !== FALSE) + { + $gd_version = str_replace('0', '', $this->gd_version()); + $v2_override = ($gd_version == 2) ? TRUE : FALSE; + } + } + else + { + // If the target width/height match the source, AND if + // the new file name is not equal to the old file name + // we'll simply make a copy of the original with the new name + if (($this->orig_width == $this->width AND $this->orig_height == $this->height) AND ($this->source_image != $this->new_image)) + { + if ( ! @copy($this->full_src_path, $this->full_dst_path)) + { + $this->set_error('imglib_copy_failed'); + return FALSE; + } + + @chmod($this->full_dst_path, 0777); + return TRUE; + } + + // If resizing the x/y axis must be zero + $this->x_axis = 0; + $this->y_axis = 0; + } + + // Create the image handle + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + // Create The Image + if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) + { + $create = 'imagecreatetruecolor'; + $copy = 'imagecopyresampled'; + } + else + { + $create = 'imagecreate'; + $copy = 'imagecopyresized'; + } + + $dst_img = $create($this->width, $this->height); + $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height); + + // Show the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($dst_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($dst_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($dst_img); + imagedestroy($src_img); + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using ImageMagick + * + * This function will resize, crop or rotate + * + * @access public + * @param string + * @return bool + */ + function image_process_imagemagick($action = 'resize') + { + // Do we have a vaild library path? + if ($this->library_path == '') + { + $this->set_error('imglib_libpath_invalid'); + return FALSE; + } + + if ( ! eregi("convert$", $this->library_path)) + { + if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/"; + + $this->library_path .= 'convert'; + } + + // Execute the command + $cmd = $this->library_path." -quality ".$this->quality; + + if ($action == 'crop') + { + $cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + elseif ($action == 'rotate') + { + switch ($this->rotation_angle) + { + case 'hor' : $angle = '-flop'; + break; + case 'vrt' : $angle = '-flip'; + break; + default : $angle = '-rotate '.$this->rotation_angle; + break; + } + + $cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + else // Resize + { + $cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1"; + } + + $retval = 1; + + @exec($cmd, $output, $retval); + + // Did it work? + if ($retval > 0) + { + $this->set_error('imglib_image_process_failed'); + return FALSE; + } + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Process Using NetPBM + * + * This function will resize, crop or rotate + * + * @access public + * @param string + * @return bool + */ + function image_process_netpbm($action = 'resize') + { + if ($this->library_path == '') + { + $this->set_error('imglib_libpath_invalid'); + return FALSE; + } + + // Build the resizing command + switch ($this->image_type) + { + case 1 : + $cmd_in = 'giftopnm'; + $cmd_out = 'ppmtogif'; + break; + case 2 : + $cmd_in = 'jpegtopnm'; + $cmd_out = 'ppmtojpeg'; + break; + case 3 : + $cmd_in = 'pngtopnm'; + $cmd_out = 'ppmtopng'; + break; + } + + if ($action == 'crop') + { + $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height; + } + elseif ($action == 'rotate') + { + switch ($this->rotation_angle) + { + case 90 : $angle = 'r270'; + break; + case 180 : $angle = 'r180'; + break; + case 270 : $angle = 'r90'; + break; + case 'vrt' : $angle = 'tb'; + break; + case 'hor' : $angle = 'lr'; + break; + } + + $cmd_inner = 'pnmflip -'.$angle.' '; + } + else // Resize + { + $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height; + } + + $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp'; + + $retval = 1; + + @exec($cmd, $output, $retval); + + // Did it work? + if ($retval > 0) + { + $this->set_error('imglib_image_process_failed'); + return FALSE; + } + + // With NetPBM we have to create a temporary image. + // If you try manipulating the original it fails so + // we have to rename the temp file. + copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path); + unlink ($this->dest_folder.'netpbm.tmp'); + @chmod($dst_image, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Rotate Using GD + * + * @access public + * @return bool + */ + function image_rotate_gd() + { + // Is Image Rotation Supported? + // this function is only supported as of PHP 4.3 + if ( ! function_exists('imagerotate')) + { + $this->set_error('imglib_rotate_unsupported'); + return FALSE; + } + + // Create the image handle + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + // Set the background color + // This won't work with transparent PNG files so we are + // going to have to figure out how to determine the color + // of the alpha channel in a future release. + + $white = imagecolorallocate($src_img, 255, 255, 255); + + // Rotate it! + $dst_img = imagerotate($src_img, $this->rotation_angle, $white); + + // Save the Image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($dst_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($dst_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($dst_img); + imagedestroy($src_img); + + // Set the file to 777 + + @chmod($this->full_dst_path, 0777); + + return true; + } + + // -------------------------------------------------------------------- + + /** + * Create Mirror Image using GD + * + * This function will flip horizontal or vertical + * + * @access public + * @return bool + */ + function image_mirror_gd() + { + if ( ! $src_img = $this->image_create_gd()) + { + return FALSE; + } + + $width = $this->orig_width; + $height = $this->orig_height; + + if ($this->rotation_angle == 'hor') + { + for ($i = 0; $i < $height; $i++) + { + $left = 0; + $right = $width-1; + + while ($left < $right) + { + $cl = imagecolorat($src_img, $left, $i); + $cr = imagecolorat($src_img, $right, $i); + + imagesetpixel($src_img, $left, $i, $cr); + imagesetpixel($src_img, $right, $i, $cl); + + $left++; + $right--; + } + } + } + else + { + for ($i = 0; $i < $width; $i++) + { + $top = 0; + $bot = $height-1; + + while ($top < $bot) + { + $ct = imagecolorat($src_img, $i, $top); + $cb = imagecolorat($src_img, $i, $bot); + + imagesetpixel($src_img, $i, $top, $cb); + imagesetpixel($src_img, $i, $bot, $ct); + + $top++; + $bot--; + } + } + } + + // Show the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + // Or save it + if ( ! $this->image_save_gd($src_img)) + { + return FALSE; + } + } + + // Kill the file handles + imagedestroy($src_img); + + // Set the file to 777 + @chmod($this->full_dst_path, 0777); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Image Watermark + * + * This is a wrapper function that chooses the type + * of watermarking based on the specified preference. + * + * @access public + * @param string + * @return bool + */ + function watermark() + { + if ($this->wm_type == 'overlay') + { + return $this->overlay_watermark(); + } + else + { + return $this->text_watermark(); + } + } + + // -------------------------------------------------------------------- + + /** + * Watermark - Graphic Version + * + * @access public + * @return bool + */ + function overlay_watermark() + { + if ( ! function_exists('imagecolortransparent')) + { + $this->set_error('imglib_gd_required'); + return FALSE; + } + + // Fetch source image properties + $this->get_image_properties(); + + // Fetch watermark image properties + $props = $this->get_image_properties($this->wm_overlay_path, TRUE); + $wm_img_type = $props['image_type']; + $wm_width = $props['width']; + $wm_height = $props['height']; + + // Create two image resources + $wm_img = $this->image_create_gd($this->wm_overlay_path, $wm_img_type); + $src_img = $this->image_create_gd($this->full_src_path); + + // Reverse the offset if necessary + // When the image is positioned at the bottom + // we don't want the vertical offset to push it + // further down. We want the reverse, so we'll + // invert the offset. Same with the horizontal + // offset when the image is at the right + + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); + $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); + + if ($this->wm_vrt_alignment == 'B') + $this->wm_vrt_offset = $this->wm_vrt_offset * -1; + + if ($this->wm_hor_alignment == 'R') + $this->wm_hor_offset = $this->wm_hor_offset * -1; + + // Set the base x and y axis values + $x_axis = $this->wm_hor_offset + $this->wm_padding; + $y_axis = $this->wm_vrt_offset + $this->wm_padding; + + // Set the vertical position + switch ($this->wm_vrt_alignment) + { + case 'T': + break; + case 'M': $y_axis += ($this->orig_height / 2) - ($wm_height / 2); + break; + case 'B': $y_axis += $this->orig_height - $wm_height; + break; + } + + // Set the horizontal position + switch ($this->wm_hor_alignment) + { + case 'L': + break; + case 'C': $x_axis += ($this->orig_width / 2) - ($wm_width / 2); + break; + case 'R': $x_axis += $this->orig_width - $wm_width; + break; + } + + // Build the finalized image + if ($wm_img_type == 3 AND function_exists('imagealphablending')) + { + @imagealphablending($src_img, TRUE); + } + + // Set RGB values for text and shadow + imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp)); + imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity); + + // Output the image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + if ( ! $this->image_save_gd($src_img)) + { + return FALSE; + } + } + + imagedestroy($src_img); + imagedestroy($wm_img); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Watermark - Text Version + * + * @access public + * @return bool + */ + function text_watermark() + { + if ( ! ($src_img = $this->image_create_gd())) + { + return FALSE; + } + + if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path)) + { + $this->set_error('imglib_missing_font'); + return FALSE; + } + + // Fetch source image properties + $this->get_image_properties(); + + // Set RGB values for text and shadow + $this->wm_font_color = str_replace('#', '', $this->wm_font_color); + $this->wm_shadow_color = str_replace('#', '', $this->wm_shadow_color); + + $R1 = hexdec(substr($this->wm_font_color, 0, 2)); + $G1 = hexdec(substr($this->wm_font_color, 2, 2)); + $B1 = hexdec(substr($this->wm_font_color, 4, 2)); + + $R2 = hexdec(substr($this->wm_shadow_color, 0, 2)); + $G2 = hexdec(substr($this->wm_shadow_color, 2, 2)); + $B2 = hexdec(substr($this->wm_shadow_color, 4, 2)); + + $txt_color = imagecolorclosest($src_img, $R1, $G1, $B1); + $drp_color = imagecolorclosest($src_img, $R2, $G2, $B2); + + // Reverse the vertical offset + // When the image is positioned at the bottom + // we don't want the vertical offset to push it + // further down. We want the reverse, so we'll + // invert the offset. Note: The horizontal + // offset flips itself automatically + + if ($this->wm_vrt_alignment == 'B') + $this->wm_vrt_offset = $this->wm_vrt_offset * -1; + + if ($this->wm_hor_alignment == 'R') + $this->wm_hor_offset = $this->wm_hor_offset * -1; + + // Set font width and height + // These are calculated differently depending on + // whether we are using the true type font or not + if ($this->wm_use_truetype == TRUE) + { + if ($this->wm_font_size == '') + $this->wm_font_size = '17'; + + $fontwidth = $this->wm_font_size-($this->wm_font_size/4); + $fontheight = $this->wm_font_size; + $this->wm_vrt_offset += $this->wm_font_size; + } + else + { + $fontwidth = imagefontwidth($this->wm_font_size); + $fontheight = imagefontheight($this->wm_font_size); + } + + // Set base X and Y axis values + $x_axis = $this->wm_hor_offset + $this->wm_padding; + $y_axis = $this->wm_vrt_offset + $this->wm_padding; + + // Set verticle alignment + if ($this->wm_use_drop_shadow == FALSE) + $this->wm_shadow_distance = 0; + + $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1)); + $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1)); + + switch ($this->wm_vrt_alignment) + { + case "T" : + break; + case "M": $y_axis += ($this->orig_height/2)+($fontheight/2); + break; + case "B": $y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2)); + break; + } + + $x_shad = $x_axis + $this->wm_shadow_distance; + $y_shad = $y_axis + $this->wm_shadow_distance; + + // Set horizontal alignment + switch ($this->wm_hor_alignment) + { + case "L": + break; + case "R": + if ($this->wm_use_drop_shadow) + $x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text)); + $x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text)); + break; + case "C": + if ($this->wm_use_drop_shadow) + $x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2); + $x_axis += floor(($this->orig_width -$fontwidth*strlen($this->wm_text))/2); + break; + } + + // Add the text to the source image + if ($this->wm_use_truetype) + { + if ($this->wm_use_drop_shadow) + imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text); + imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text); + } + else + { + if ($this->wm_use_drop_shadow) + imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color); + imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color); + } + + // Output the final image + if ($this->dynamic_output == TRUE) + { + $this->image_display_gd($src_img); + } + else + { + $this->image_save_gd($src_img); + } + + imagedestroy($src_img); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Create Image - GD + * + * This simply creates an image resource handle + * based on the type of image being processed + * + * @access public + * @param string + * @return resource + */ + function image_create_gd($path = '', $image_type = '') + { + if ($path == '') + $path = $this->full_src_path; + + if ($image_type == '') + $image_type = $this->image_type; + + + switch ($image_type) + { + case 1 : + if ( ! function_exists('imagecreatefromgif')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); + return FALSE; + } + + return imagecreatefromgif($path); + break; + case 2 : + if ( ! function_exists('imagecreatefromjpeg')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); + return FALSE; + } + + return imagecreatefromjpeg($path); + break; + case 3 : + if ( ! function_exists('imagecreatefrompng')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + return FALSE; + } + + return imagecreatefrompng($path); + break; + + } + + $this->set_error(array('imglib_unsupported_imagecreate')); + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Write image file to disk - GD + * + * Takes an image resource as input and writes the file + * to the specified destination + * + * @access public + * @param resource + * @return bool + */ + function image_save_gd($resource) + { + switch ($this->image_type) + { + case 1 : + if ( ! function_exists('imagegif')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported')); + return FALSE; + } + + @imagegif($resource, $this->full_dst_path); + break; + case 2 : + if ( ! function_exists('imagejpeg')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported')); + return FALSE; + } + + if (phpversion() == '4.4.1') + { + @touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround + } + + @imagejpeg($resource, $this->full_dst_path, $this->quality); + break; + case 3 : + if ( ! function_exists('imagepng')) + { + $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported')); + return FALSE; + } + + @imagepng($resource, $this->full_dst_path); + break; + default : + $this->set_error(array('imglib_unsupported_imagecreate')); + return FALSE; + break; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Dynamically outputs an image + * + * @access public + * @param resource + * @return void + */ + function image_display_gd($resource) + { + header("Content-Disposition: filename={$this->source_image};"); + header("Content-Type: {$this->mime_type}"); + header('Content-Transfer-Encoding: binary'); + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + + switch ($this->image_type) + { + case 1 : imagegif($resource); + break; + case 2 : imagejpeg($resource, '', $this->quality); + break; + case 3 : imagepng($resource); + break; + default : echo 'Unable to display the image'; + break; + } + } + + // -------------------------------------------------------------------- + + /** + * Re-proportion Image Width/Height + * + * When creating thumbs, the desired width/height + * can end up warping the image due to an incorrect + * ratio between the full-sized image and the thumb. + * + * This function lets us re-proportion the width/height + * if users choose to maintain the aspect ratio when resizing. + * + * @access public + * @return void + */ + function image_reproportion() + { + if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0) + return; + + if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0) + return; + + $new_width = ceil($this->orig_width*$this->height/$this->orig_height); + $new_height = ceil($this->width*$this->orig_height/$this->orig_width); + + $ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width)); + + if ($this->master_dim != 'width' AND $this->master_dim != 'height') + { + $this->master_dim = ($ratio < 0) ? 'width' : 'height'; + } + + if (($this->width != $new_width) AND ($this->height != $new_height)) + { + if ($this->master_dim == 'height') + { + $this->width = $new_width; + } + else + { + $this->height = $new_height; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Get image properties + * + * A helper function that gets info about the file + * + * @access public + * @param string + * @return mixed + */ + function get_image_properties($path = '', $return = FALSE) + { + // For now we require GD but we should + // find a way to determine this using IM or NetPBM + + if ($path == '') + $path = $this->full_src_path; + + if ( ! file_exists($path)) + { + $this->set_error('imglib_invalid_path'); + return FALSE; + } + + $vals = @getimagesize($path); + + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); + + $mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg'; + + if ($return == TRUE) + { + $v['width'] = $vals['0']; + $v['height'] = $vals['1']; + $v['image_type'] = $vals['2']; + $v['size_str'] = $vals['3']; + $v['mime_type'] = $mime; + + return $v; + } + + $this->orig_width = $vals['0']; + $this->orig_height = $vals['1']; + $this->image_type = $vals['2']; + $this->size_str = $vals['3']; + $this->mime_type = $mime; + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Size calculator + * + * This function takes a known width x height and + * recalculates it to a new size. Only one + * new variable needs to be known + * + * $props = array( + * 'width' => $width, + * 'height' => $height, + * 'new_width' => 40, + * 'new_height' => '' + * ); + * + * @access public + * @param array + * @return array + */ + function size_calculator($vals) + { + if ( ! is_array($vals)) + return; + + $allowed = array('new_width', 'new_height', 'width', 'height'); + + foreach ($allowed as $item) + { + if ( ! isset($vals[$item]) OR $vals[$item] == '') + $vals[$item] = 0; + } + + if ($vals['width'] == 0 OR $vals['height'] == 0) + { + return $vals; + } + + if ($vals['new_width'] == 0) + { + $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']); + } + elseif ($vals['new_height'] == 0) + { + $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']); + } + + return $vals; + } + + // -------------------------------------------------------------------- + + /** + * Explode source_image + * + * This is a helper function that extracts the extension + * from the source_image. This function lets us deal with + * source_images with multiple periods, like: my.cool.jpg + * It returns an associative array with two elements: + * $array['ext'] = '.jpg'; + * $array['name'] = 'my.cool'; + * + * @access public + * @param array + * @return array + */ + function explode_name($source_image) + { + $x = explode('.', $source_image); + $ret['ext'] = '.'.end($x); + + $name = ''; + + $ct = count($x)-1; + + for ($i = 0; $i < $ct; $i++) + { + $name .= $x[$i]; + + if ($i < ($ct - 1)) + { + $name .= '.'; + } + } + + $ret['name'] = $name; + + return $ret; + } + + // -------------------------------------------------------------------- + + /** + * Is GD Installed? + * + * @access public + * @return bool + */ + function gd_loaded() + { + if ( ! extension_loaded('gd')) + { + if ( ! dl('gd.so')) + { + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Get GD version + * + * @access public + * @return mixed + */ + function gd_version() + { + if (function_exists('gd_info')) + { + $gd_version = @gd_info(); + $gd_version = preg_replace("/\D/", "", $gd_version['GD Version']); + + return $gd_version; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + $CI =& get_instance(); + $CI->lang->load('imglib'); + + if (is_array($msg)) + { + foreach ($msg as $val) + { + + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + else + { + $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + + // -------------------------------------------------------------------- + + /** + * Show error messages + * + * @access public + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + +} +// END Image_lib Class +?> \ No newline at end of file diff --git a/system/libraries/Input.php b/system/libraries/Input.php new file mode 100755 index 0000000..1c5682e --- /dev/null +++ b/system/libraries/Input.php @@ -0,0 +1,926 @@ +use_xss_clean = ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE; + $this->allow_get_array = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE; + $this->_sanitize_globals(); + } + + // -------------------------------------------------------------------- + + /** + * Sanitize Globals + * + * This function does the following: + * + * Unsets $_GET data (if query strings are not enabled) + * + * Unsets all globals if register_globals is enabled + * + * Standardizes newline characters to \n + * + * @access private + * @return void + */ + function _sanitize_globals() + { + // Would kind of be "wrong" to unset any of these GLOBALS + $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA', + 'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN'); + + // Unset globals for security. + // This is effectively the same as register_globals = off + foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global) + { + if ( ! is_array($global)) + { + if ( ! in_array($global, $protected)) + { + unset($GLOBALS[$global]); + } + } + else + { + foreach ($global as $key => $val) + { + if ( ! in_array($key, $protected)) + { + unset($GLOBALS[$key]); + } + + if (is_array($val)) + { + foreach($val as $k => $v) + { + if ( ! in_array($k, $protected)) + { + unset($GLOBALS[$k]); + } + } + } + } + } + } + + // Is $_GET data allowed? If not we'll set the $_GET to an empty array + if ($this->allow_get_array == FALSE) + { + $_GET = array(); + } + else + { + if (is_array($_GET) AND count($_GET) > 0) + { + foreach($_GET as $key => $val) + { + $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + } + + // Clean $_POST Data + if (is_array($_POST) AND count($_POST) > 0) + { + foreach($_POST as $key => $val) + { + $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + + // Clean $_COOKIE Data + if (is_array($_COOKIE) AND count($_COOKIE) > 0) + { + foreach($_COOKIE as $key => $val) + { + $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + } + + log_message('debug', "Global POST and COOKIE data sanitized"); + } + + // -------------------------------------------------------------------- + + /** + * Clean Input Data + * + * This is a helper function. It escapes data and + * standardizes newline characters to \n + * + * @access private + * @param string + * @return string + */ + function _clean_input_data($str) + { + if (is_array($str)) + { + $new_array = array(); + foreach ($str as $key => $val) + { + $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); + } + return $new_array; + } + + // We strip slashes if magic quotes is on to keep things consistent + if (get_magic_quotes_gpc()) + { + $str = stripslashes($str); + } + + // Should we filter the input data? + if ($this->use_xss_clean === TRUE) + { + $str = $this->xss_clean($str); + } + + // Standardize newlines + return preg_replace("/\015\012|\015|\012/", "\n", $str); + } + + // -------------------------------------------------------------------- + + /** + * Clean Keys + * + * This is a helper function. To prevent malicious users + * from trying to exploit keys we make sure that keys are + * only named with alpha-numeric text and a few other items. + * + * @access private + * @param string + * @return string + */ + function _clean_input_keys($str) + { + if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) + { + exit('Disallowed Key Characters.'); + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the GET array + * + * @access public + * @param string + * @param bool + * @return string + */ + function get($index = '', $xss_clean = FALSE) + { + if ( ! isset($_GET[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_GET[$index])) + { + foreach($_GET[$index] as $key => $val) + { + $_GET[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_GET[$index]); + } + } + + return $_GET[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the POST array + * + * @access public + * @param string + * @param bool + * @return string + */ + function post($index = '', $xss_clean = FALSE) + { + if ( ! isset($_POST[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_POST[$index])) + { + foreach($_POST[$index] as $key => $val) + { + $_POST[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_POST[$index]); + } + } + + return $_POST[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the COOKIE array + * + * @access public + * @param string + * @param bool + * @return string + */ + function cookie($index = '', $xss_clean = FALSE) + { + if ( ! isset($_COOKIE[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + if (is_array($_COOKIE[$index])) + { + $cookie = array(); + foreach($_COOKIE[$index] as $key => $val) + { + $cookie[$key] = $this->xss_clean($val); + } + + return $cookie; + } + else + { + return $this->xss_clean($_COOKIE[$index]); + } + } + else + { + return $_COOKIE[$index]; + } + } + + // -------------------------------------------------------------------- + + /** + * Fetch an item from the SERVER array + * + * @access public + * @param string + * @param bool + * @return string + */ + function server($index = '', $xss_clean = FALSE) + { + if ( ! isset($_SERVER[$index])) + { + return FALSE; + } + + if ($xss_clean === TRUE) + { + return $this->xss_clean($_SERVER[$index]); + } + + return $_SERVER[$index]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the IP Address + * + * @access public + * @return string + */ + function ip_address() + { + if ($this->ip_address !== FALSE) + { + return $this->ip_address; + } + + if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + elseif ($this->server('REMOTE_ADDR')) + { + $this->ip_address = $_SERVER['REMOTE_ADDR']; + } + elseif ($this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + elseif ($this->server('HTTP_X_FORWARDED_FOR')) + { + $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + + if ($this->ip_address === FALSE) + { + $this->ip_address = '0.0.0.0'; + return $this->ip_address; + } + + if (strstr($this->ip_address, ',')) + { + $x = explode(',', $this->ip_address); + $this->ip_address = end($x); + } + + if ( ! $this->valid_ip($this->ip_address)) + { + $this->ip_address = '0.0.0.0'; + } + + return $this->ip_address; + } + + // -------------------------------------------------------------------- + + /** + * Validate IP Address + * + * Updated version suggested by Geert De Deckere + * + * @access public + * @param string + * @return string + */ + function valid_ip($ip) + { + $ip_segments = explode('.', $ip); + + // Always 4 segments needed + if (count($ip_segments) != 4) + { + return FALSE; + } + // IP can not start with 0 + if (substr($ip_segments[0], 0, 1) == '0') + { + return FALSE; + } + // Check each segment + foreach ($ip_segments as $segment) + { + // IP segments must be digits and can not be + // longer than 3 digits or greater then 255 + if (preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) + { + return FALSE; + } + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * User Agent + * + * @access public + * @return string + */ + function user_agent() + { + if ($this->user_agent !== FALSE) + { + return $this->user_agent; + } + + $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT']; + + return $this->user_agent; + } + + // -------------------------------------------------------------------- + + /** + * Filename Security + * + * @access public + * @param string + * @return string + */ + function filename_security($str) + { + $bad = array( + "../", + "./", + "", + "<", + ">", + "'", + '"', + '&', + '$', + '#', + '{', + '}', + '[', + ']', + '=', + ';', + '?', + "%20", + "%22", + "%3c", // < + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; + "%3d" // = + ); + + return stripslashes(str_replace($bad, '', $str)); + } + + // -------------------------------------------------------------------- + + /** + * XSS Clean + * + * Sanitizes data so that Cross Site Scripting Hacks can be + * prevented.  This function does a fair amount of work but + * it is extremely thorough, designed to prevent even the + * most obscure XSS attempts.  Nothing is ever 100% foolproof, + * of course, but I haven't been able to get anything passed + * the filter. + * + * Note: This function should only be used to deal with data + * upon submission.  It's not something that should + * be used for general runtime processing. + * + * This function was based in part on some code and ideas I + * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention + * + * To help develop this script I used this great list of + * vulnerabilities along with a few other hacks I've + * harvested from examining vulnerabilities in other programs: + * http://ha.ckers.org/xss.html + * + * @access public + * @param string + * @return string + */ + function xss_clean($str) + { + /* + * Remove Null Characters + * + * This prevents sandwiching null characters + * between ascii characters, like Java\0script. + * + */ + $str = preg_replace('/\0+/', '', $str); + $str = preg_replace('/(\\\\0)+/', '', $str); + + /* + * Validate standard character entities + * + * Add a semicolon if missing. We do this to enable + * the conversion of entities to ASCII later. + * + */ + $str = preg_replace('#(&\#?[0-9a-z]+)[\x00-\x20]*;?#i', "\\1;", $str); + + /* + * Validate UTF16 two byte encoding (x00) + * + * Just as above, adds a semicolon if missing. + * + */ + $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str); + + /* + * URL Decode + * + * Just in case stuff like this is submitted: + * + * Google + * + * Note: Use rawurldecode() so it does not remove plus signs + * + */ + $str = rawurldecode($str); + + /* + * Convert character entities to ASCII + * + * This permits our tests below to work reliably. + * We only convert entities that are within tags since + * these are the ones that will pose security problems. + * + */ + + $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_attribute_conversion'), $str); + + $str = preg_replace_callback("/<([\w]+)[^>]*>/si", array($this, '_html_entity_decode_callback'), $str); + + /* + + Old Code that when modified to use preg_replace()'s above became more efficient memory-wise + + if (preg_match_all("/[a-z]+=([\'\"]).*?\\1/si", $str, $matches)) + { + for ($i = 0; $i < count($matches[0]); $i++) + { + if (stristr($matches[0][$i], '>')) + { + $str = str_replace( $matches['0'][$i], + str_replace('>', '<', $matches[0][$i]), + $str); + } + } + } + + if (preg_match_all("/<([\w]+)[^>]*>/si", $str, $matches)) + { + for ($i = 0; $i < count($matches[0]); $i++) + { + $str = str_replace($matches[0][$i], + $this->_html_entity_decode($matches[0][$i], $charset), + $str); + } + } + */ + + /* + * Convert all tabs to spaces + * + * This prevents strings like this: ja vascript + * NOTE: we deal with spaces between characters later. + * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, + * so we use str_replace. + * + */ + + $str = str_replace("\t", " ", $str); + + /* + * Not Allowed Under Any Conditions + */ + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', // CSS and IE + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + /* + * Makes PHP tags safe + * + * Note: XML tags are inadvertently replaced too: + * + * '), array('<?php', '<?PHP', '<?', '?>'), $str); + + /* + * Compact any exploded words + * + * This corrects words like: j a v a s c r i p t + * These words are compacted back to their correct state. + * + */ + $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); + foreach ($words as $word) + { + $temp = ''; + for ($i = 0; $i < strlen($word); $i++) + { + $temp .= substr($word, $i, 1)."\s*"; + } + + // We only want to do this when it is followed by a non-word character + // That way valid stuff like "dealer to" does not become "dealerto" + $str = preg_replace('#('.substr($temp, 0, -3).')(\W)#ise', "preg_replace('/\s+/s', '', '\\1').'\\2'", $str); + } + + /* + * Remove disallowed Javascript in links or img tags + */ + do + { + $original = $str; + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '') !== FALSE) OR + preg_match("/<\/a>/i", $str)) + { + $str = preg_replace_callback("##si", array($this, '_js_link_removal'), $str); + } + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '#si", array($this, '_js_img_removal'), $str); + } + + if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && (stripos($str, 'script') !== FALSE OR stripos($str, 'xss') !== FALSE)) OR + preg_match("/(script|xss)/i", $str)) + { + $str = preg_replace("##si", "", $str); + } + } + while($original != $str); + + unset($original); + + /* + * Remove JavaScript Event Handlers + * + * Note: This code is a little blunt. It removes + * the event handler and anything up to the closing >, + * but it's unlikely to be a problem. + * + */ + $event_handlers = array('onblur','onchange','onclick','onfocus','onload','onmouseover','onmouseup','onmousedown','onselect','onsubmit','onunload','onkeypress','onkeydown','onkeyup','onresize', 'xmlns'); + $str = preg_replace("#<([^>]+)(".implode('|', $event_handlers).")([^>]*)>#iU", "<\\1\\2\\3>", $str); + + /* + * Sanitize naughty HTML elements + * + * If a tag containing any of the words in the list + * below is found, the tag gets converted to entities. + * + * So this: + * Becomes: <blink> + * + */ + $str = preg_replace('#<(/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>#is', "<\\1\\2\\3>", $str); + + /* + * Sanitize naughty scripting elements + * + * Similar to above, only instead of looking for + * tags it looks for PHP and JavaScript commands + * that are disallowed. Rather than removing the + * code, it simply converts the parenthesis to entities + * rendering the code un-executable. + * + * For example: eval('some code') + * Becomes: eval('some code') + * + */ + $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str); + + /* + * Final clean up + * + * This adds a bit of extra precaution in case + * something got through the above filters + * + */ + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', // CSS and IE + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + + log_message('debug', "XSS Filtering completed"); + return $str; + } + + // -------------------------------------------------------------------- + + /** + * JS Link Removal + * + * Callback function for xss_clean() to sanitize links + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on link-heavy strings + * + * @access private + * @param array + * @return string + */ + function _js_link_removal($match) + { + return preg_replace("#.*?#si", "", $match[0]); + } + + /** + * JS Image Removal + * + * Callback function for xss_clean() to sanitize image tags + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on image tag heavy strings + * + * @access private + * @param array + * @return string + */ + function _js_img_removal($match) + { + return preg_replace("##si", "", $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * Attribute Conversion + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ + function _attribute_conversion($match) + { + return str_replace('>', '<', $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * HTML Entity Decode Callback + * + * Used as a callback for XSS Clean + * + * @access public + * @param array + * @return string + */ + function _html_entity_decode_callback($match) + { + global $CFG; + $charset = $CFG->item('charset'); + + return $this->_html_entity_decode($match[0], strtoupper($charset)); + } + + // -------------------------------------------------------------------- + + /** + * HTML Entities Decode + * + * This function is a replacement for html_entity_decode() + * + * In some versions of PHP the native function does not work + * when UTF-8 is the specified character set, so this gives us + * a work-around. More info here: + * http://bugs.php.net/bug.php?id=25670 + * + * @access private + * @param string + * @param string + * @return string + */ + /* ------------------------------------------------- + /* Replacement for html_entity_decode() + /* -------------------------------------------------*/ + + /* + NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the + character set, and the PHP developers said they were not back porting the + fix to versions other than PHP 5.x. + */ + function _html_entity_decode($str, $charset='UTF-8') + { + if (stristr($str, '&') === FALSE) return $str; + + // The reason we are not using html_entity_decode() by itself is because + // while it is not technically correct to leave out the semicolon + // at the end of an entity most browsers will still interpret the entity + // correctly. html_entity_decode() does not convert entities without + // semicolons, so we are left with our own little solution here. Bummer. + + if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>='))) + { + $str = html_entity_decode($str, ENT_COMPAT, $charset); + $str = preg_replace('~&#x([0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); + return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); + } + + // Numeric Entities + $str = preg_replace('~&#x([0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str); + $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str); + + // Literal Entities - Slightly slow so we do another check + if (stristr($str, '&') === FALSE) + { + $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES))); + } + + return $str; + } + +} +// END Input class +?> \ No newline at end of file diff --git a/system/libraries/Language.php b/system/libraries/Language.php new file mode 100755 index 0000000..3dac1a6 --- /dev/null +++ b/system/libraries/Language.php @@ -0,0 +1,121 @@ +is_loaded, TRUE)) + { + return; + } + + if ($idiom == '') + { + $CI =& get_instance(); + $deft_lang = $CI->config->item('language'); + $idiom = ($deft_lang == '') ? 'english' : $deft_lang; + } + + // Determine where the language file is and load it + if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile)) + { + include(APPPATH.'language/'.$idiom.'/'.$langfile); + } + else + { + if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile)) + { + include(BASEPATH.'language/'.$idiom.'/'.$langfile); + } + else + { + show_error('Unable to load the requested language file: language/'.$langfile); + } + } + + + if ( ! isset($lang)) + { + log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); + return; + } + + if ($return == TRUE) + { + return $lang; + } + + $this->is_loaded[] = $langfile; + $this->language = array_merge($this->language, $lang); + unset($lang); + + log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a single line of text from the language array + * + * @access public + * @param string the language line + * @return string + */ + function line($line = '') + { + return ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; + } + +} +// END Language Class +?> \ No newline at end of file diff --git a/system/libraries/Loader.php b/system/libraries/Loader.php new file mode 100755 index 0000000..576cb11 --- /dev/null +++ b/system/libraries/Loader.php @@ -0,0 +1,1028 @@ + 'unit', 'user_agent' => 'agent'); + + + /** + * Constructor + * + * Sets the path to the view files and gets the initial output buffering level + * + * @access public + */ + function CI_Loader() + { + $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE; + $this->_ci_view_path = APPPATH.'views/'; + $this->_ci_ob_level = ob_get_level(); + + log_message('debug', "Loader Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Class Loader + * + * This function lets users load and instantiate classes. + * It is designed to be called from a user's app controllers. + * + * @access public + * @param string the name of the class + * @param mixed the optional parameters + * @return void + */ + function library($library = '', $params = NULL) + { + if ($library == '') + { + return FALSE; + } + + if (is_array($library)) + { + foreach ($library as $class) + { + $this->_ci_load_class($class, $params); + } + } + else + { + $this->_ci_load_class($library, $params); + } + + $this->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Model Loader + * + * This function lets users load and instantiate models. + * + * @access public + * @param string the name of the class + * @param mixed any initialization parameters + * @return void + */ + function model($model, $name = '', $db_conn = FALSE) + { + if (is_array($model)) + { + foreach($model as $babe) + { + $this->model($babe); + } + return; + } + + if ($model == '') + { + return; + } + + // Is the model in a sub-folder? If so, parse out the filename and path. + if (strpos($model, '/') === FALSE) + { + $path = ''; + } + else + { + $x = explode('/', $model); + $model = end($x); + unset($x[count($x)-1]); + $path = implode('/', $x).'/'; + } + + if ($name == '') + { + $name = $model; + } + + if (in_array($name, $this->_ci_models, TRUE)) + { + return; + } + + $CI =& get_instance(); + if (isset($CI->$name)) + { + show_error('The model name you are loading is the name of a resource that is already being used: '.$name); + } + + $model = strtolower($model); + + if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT)) + { + show_error('Unable to locate the model you have specified: '.$model); + } + + if ($db_conn !== FALSE AND ! class_exists('CI_DB')) + { + if ($db_conn === TRUE) + $db_conn = ''; + + $CI->load->database($db_conn, FALSE, TRUE); + } + + if ( ! class_exists('Model')) + { + load_class('Model', FALSE); + } + + require_once(APPPATH.'models/'.$path.$model.EXT); + + $model = ucfirst($model); + + $CI->$name = new $model(); + $CI->$name->_assign_libraries(); + + $this->_ci_models[] = $name; + } + + // -------------------------------------------------------------------- + + /** + * Database Loader + * + * @access public + * @param string the DB credentials + * @param bool whether to return the DB object + * @param bool whether to enable active record (this allows us to override the config setting) + * @return object + */ + function database($params = '', $return = FALSE, $active_record = FALSE) + { + // Grab the super object + $CI =& get_instance(); + + // Do we even need to load the database class? + if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db)) + { + return FALSE; + } + + require_once(BASEPATH.'database/DB'.EXT); + + if ($return === TRUE) + { + return DB($params, $active_record); + } + + // Initialize the db variable. Needed to prevent + // reference errors with some configurations + $CI->db = ''; + + // Load the DB class + $CI->db =& DB($params, $active_record); + + // Assign the DB object to any existing models + $this->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Load the Utilities Class + * + * @access public + * @return string + */ + function dbutil() + { + if ( ! class_exists('CI_DB')) + { + $this->database(); + } + + $CI =& get_instance(); + + // for backwards compatibility, load dbforge so we can extend dbutils off it + // this use is deprecated and strongly discouraged + $CI->load->dbforge(); + + require_once(BASEPATH.'database/DB_utility'.EXT); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT); + $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; + + $CI->dbutil =& new $class(); + + $CI->load->_ci_assign_to_models(); + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Forge Class + * + * @access public + * @return string + */ + function dbforge() + { + if ( ! class_exists('CI_DB')) + { + $this->database(); + } + + $CI =& get_instance(); + + require_once(BASEPATH.'database/DB_forge'.EXT); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT); + $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; + + $CI->dbforge = new $class(); + } + + // -------------------------------------------------------------------- + + /** + * Load View + * + * This function is used to load a "view" file. It has three parameters: + * + * 1. The name of the "view" file to be included. + * 2. An associative array of data to be extracted for use in the view. + * 3. TRUE/FALSE - whether to return the data or load it. In + * some cases it's advantageous to be able to return data so that + * a developer can process it in some way. + * + * @access public + * @param string + * @param array + * @param bool + * @return void + */ + function view($view, $vars = array(), $return = FALSE) + { + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Load File + * + * This is a generic file loader + * + * @access public + * @param string + * @param bool + * @return string + */ + function file($path, $return = FALSE) + { + return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Set Variables + * + * Once variables are set they become available within + * the controller class and its "view" files. + * + * @access public + * @param array + * @return void + */ + function vars($vars = array()) + { + $vars = $this->_ci_object_to_array($vars); + + if (is_array($vars) AND count($vars) > 0) + { + foreach ($vars as $key => $val) + { + $this->_ci_cached_vars[$key] = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Load Helper + * + * This function loads the specified helper file. + * + * @access public + * @param mixed + * @return void + */ + function helper($helpers = array()) + { + if ( ! is_array($helpers)) + { + $helpers = array($helpers); + } + + foreach ($helpers as $helper) + { + $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper'); + + if (isset($this->_ci_helpers[$helper])) + { + continue; + } + + $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT; + + // Is this a helper extension request? + if (file_exists($ext_helper)) + { + $base_helper = BASEPATH.'helpers/'.$helper.EXT; + + if ( ! file_exists($base_helper)) + { + show_error('Unable to load the requested file: helpers/'.$helper.EXT); + } + + include_once($ext_helper); + include_once($base_helper); + } + elseif (file_exists(APPPATH.'helpers/'.$helper.EXT)) + { + include_once(APPPATH.'helpers/'.$helper.EXT); + } + else + { + if (file_exists(BASEPATH.'helpers/'.$helper.EXT)) + { + include(BASEPATH.'helpers/'.$helper.EXT); + } + else + { + show_error('Unable to load the requested file: helpers/'.$helper.EXT); + } + } + + $this->_ci_helpers[$helper] = TRUE; + + } + + log_message('debug', 'Helpers loaded: '.implode(', ', $helpers)); + } + + // -------------------------------------------------------------------- + + /** + * Load Helpers + * + * This is simply an alias to the above function in case the + * user has written the plural form of this function. + * + * @access public + * @param array + * @return void + */ + function helpers($helpers = array()) + { + $this->helper($helpers); + } + + // -------------------------------------------------------------------- + + /** + * Load Plugin + * + * This function loads the specified plugin. + * + * @access public + * @param array + * @return void + */ + function plugin($plugins = array()) + { + if ( ! is_array($plugins)) + { + $plugins = array($plugins); + } + + foreach ($plugins as $plugin) + { + $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi'); + + if (isset($this->_ci_plugins[$plugin])) + { + continue; + } + + if (file_exists(APPPATH.'plugins/'.$plugin.EXT)) + { + include(APPPATH.'plugins/'.$plugin.EXT); + } + else + { + if (file_exists(BASEPATH.'plugins/'.$plugin.EXT)) + { + include(BASEPATH.'plugins/'.$plugin.EXT); + } + else + { + show_error('Unable to load the requested file: plugins/'.$plugin.EXT); + } + } + + $this->_ci_plugins[$plugin] = TRUE; + } + + log_message('debug', 'Plugins loaded: '.implode(', ', $plugins)); + } + + // -------------------------------------------------------------------- + + /** + * Load Plugins + * + * This is simply an alias to the above function in case the + * user has written the plural form of this function. + * + * @access public + * @param array + * @return void + */ + function plugins($plugins = array()) + { + $this->plugin($plugins); + } + + // -------------------------------------------------------------------- + + /** + * Load Script + * + * This function loads the specified include file from the + * application/scripts/ folder. + * + * NOTE: This feature has been deprecated but it will remain available + * for legacy users. + * + * @access public + * @param array + * @return void + */ + function script($scripts = array()) + { + if ( ! is_array($scripts)) + { + $scripts = array($scripts); + } + + foreach ($scripts as $script) + { + $script = strtolower(str_replace(EXT, '', $script)); + + if (isset($this->_ci_scripts[$script])) + { + continue; + } + + if ( ! file_exists(APPPATH.'scripts/'.$script.EXT)) + { + show_error('Unable to load the requested script: scripts/'.$script.EXT); + } + + include(APPPATH.'scripts/'.$script.EXT); + } + + log_message('debug', 'Scripts loaded: '.implode(', ', $scripts)); + } + + // -------------------------------------------------------------------- + + /** + * Loads a language file + * + * @access public + * @param array + * @param string + * @return void + */ + function language($file = array(), $lang = '') + { + $CI =& get_instance(); + + if ( ! is_array($file)) + { + $file = array($file); + } + + foreach ($file as $langfile) + { + $CI->lang->load($langfile, $lang); + } + } + + /** + * Loads language files for scaffolding + * + * @access public + * @param string + * @return arra + */ + function scaffold_language($file = '', $lang = '', $return = FALSE) + { + $CI =& get_instance(); + return $CI->lang->load($file, $lang, $return); + } + + // -------------------------------------------------------------------- + + /** + * Loads a config file + * + * @access public + * @param string + * @return void + */ + function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + { + $CI =& get_instance(); + $CI->config->load($file, $use_sections, $fail_gracefully); + } + + // -------------------------------------------------------------------- + + /** + * Scaffolding Loader + * + * This initializing function works a bit different than the + * others. It doesn't load the class. Instead, it simply + * sets a flag indicating that scaffolding is allowed to be + * used. The actual scaffolding function below is + * called by the front controller based on whether the + * second segment of the URL matches the "secret" scaffolding + * word stored in the application/config/routes.php + * + * @access public + * @param string + * @return void + */ + function scaffolding($table = '') + { + if ($table === FALSE) + { + show_error('You must include the name of the table you would like to access when you initialize scaffolding'); + } + + $CI =& get_instance(); + $CI->_ci_scaffolding = TRUE; + $CI->_ci_scaff_table = $table; + } + + // -------------------------------------------------------------------- + + /** + * Loader + * + * This function is used to load views and files. + * Variables are prefixed with _ci_ to avoid symbol collision with + * variables made available to view files + * + * @access private + * @param array + * @return void + */ + function _ci_load($_ci_data) + { + // Set the default data variables + foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) + { + $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val]; + } + + // Set the path to the requested file + if ($_ci_path == '') + { + $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); + $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view; + $_ci_path = $this->_ci_view_path.$_ci_file; + } + else + { + $_ci_x = explode('/', $_ci_path); + $_ci_file = end($_ci_x); + } + + if ( ! file_exists($_ci_path)) + { + show_error('Unable to load the requested file: '.$_ci_file); + } + + // This allows anything loaded using $this->load (views, files, etc.) + // to become accessible from within the Controller and Model functions. + // Only needed when running PHP 5 + + if ($this->_ci_is_instance()) + { + $_ci_CI =& get_instance(); + foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) + { + if ( ! isset($this->$_ci_key)) + { + $this->$_ci_key =& $_ci_CI->$_ci_key; + } + } + } + + /* + * Extract and cache variables + * + * You can either set variables using the dedicated $this->load_vars() + * function or via the second parameter of this function. We'll merge + * the two types and cache them so that views that are embedded within + * other views can have access to these variables. + */ + if (is_array($_ci_vars)) + { + $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); + } + extract($this->_ci_cached_vars); + + /* + * Buffer the output + * + * We buffer the output for two reasons: + * 1. Speed. You get a significant speed boost. + * 2. So that the final rendered template can be + * post-processed by the output class. Why do we + * need post processing? For one thing, in order to + * show the elapsed page load time. Unless we + * can intercept the content right before it's sent to + * the browser and then stop the timer it won't be accurate. + */ + ob_start(); + + // If the PHP installation does not support short tags we'll + // do a little string replacement, changing the short tags + // to standard PHP echo statements. + + if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE) + { + echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace(' $this->_ci_ob_level + 1) + { + ob_end_flush(); + } + else + { + // PHP 4 requires that we use a global + global $OUT; + $OUT->append_output(ob_get_contents()); + @ob_end_clean(); + } + } + + // -------------------------------------------------------------------- + + /** + * Load class + * + * This function loads the requested class. + * + * @access private + * @param string the item that is being loaded + * @param mixed any additional parameters + * @return void + */ + function _ci_load_class($class, $params = NULL) + { + // Get the class name + $class = str_replace(EXT, '', $class); + + // We'll test for both lowercase and capitalized versions of the file name + foreach (array(ucfirst($class), strtolower($class)) as $class) + { + $subclass = APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT; + + // Is this a class extension request? + if (file_exists($subclass)) + { + $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT; + + if ( ! file_exists($baseclass)) + { + log_message('error', "Unable to load the requested class: ".$class); + show_error("Unable to load the requested class: ".$class); + } + + // Safety: Was the class already loaded by a previous call? + if (in_array($subclass, $this->_ci_classes)) + { + $is_duplicate = TRUE; + log_message('debug', $class." class already loaded. Second attempt ignored."); + return; + } + + include($baseclass); + include($subclass); + $this->_ci_classes[] = $subclass; + + return $this->_ci_init_class($class, config_item('subclass_prefix'), $params); + } + + // Lets search for the requested library file and load it. + $is_duplicate = FALSE; + for ($i = 1; $i < 3; $i++) + { + $path = ($i % 2) ? APPPATH : BASEPATH; + $filepath = $path.'libraries/'.$class.EXT; + + // Does the file exist? No? Bummer... + if ( ! file_exists($filepath)) + { + continue; + } + + // Safety: Was the class already loaded by a previous call? + if (in_array($filepath, $this->_ci_classes)) + { + $is_duplicate = TRUE; + log_message('debug', $class." class already loaded. Second attempt ignored."); + return; + } + + include($filepath); + $this->_ci_classes[] = $filepath; + return $this->_ci_init_class($class, '', $params); + } + } // END FOREACH + + // If we got this far we were unable to find the requested class. + // We do not issue errors if the load call failed due to a duplicate request + if ($is_duplicate == FALSE) + { + log_message('error', "Unable to load the requested class: ".$class); + show_error("Unable to load the requested class: ".$class); + } + } + + // -------------------------------------------------------------------- + + /** + * Instantiates a class + * + * @access private + * @param string + * @param string + * @return null + */ + function _ci_init_class($class, $prefix = '', $config = FALSE) + { + $class = strtolower($class); + + // Is there an associated config file for this class? + if ($config === NULL) + { + if (file_exists(APPPATH.'config/'.$class.EXT)) + { + include(APPPATH.'config/'.$class.EXT); + } + } + + if ($prefix == '') + { + $name = (class_exists('CI_'.$class)) ? 'CI_'.$class : $class; + } + else + { + $name = $prefix.$class; + } + + // Set the variable name we will assign the class to + $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class]; + + // Instantiate the class + $CI =& get_instance(); + if ($config !== NULL) + { + $CI->$classvar = new $name($config); + } + else + { + $CI->$classvar = new $name; + } + } + + // -------------------------------------------------------------------- + + /** + * Autoloader + * + * The config/autoload.php file contains an array that permits sub-systems, + * libraries, plugins, and helpers to be loaded automatically. + * + * @access private + * @param array + * @return void + */ + function _ci_autoloader() + { + include(APPPATH.'config/autoload'.EXT); + + if ( ! isset($autoload)) + { + return FALSE; + } + + // Load any custom config file + if (count($autoload['config']) > 0) + { + $CI =& get_instance(); + foreach ($autoload['config'] as $key => $val) + { + $CI->config->load($val); + } + } + + // Autoload plugins, helpers, scripts and languages + foreach (array('helper', 'plugin', 'script', 'language') as $type) + { + if (isset($autoload[$type]) AND count($autoload[$type]) > 0) + { + $this->$type($autoload[$type]); + } + } + + + + // A little tweak to remain backward compatible + // The $autoload['core'] item was deprecated + if ( ! isset($autoload['libraries'])) + { + $autoload['libraries'] = $autoload['core']; + } + + // Load libraries + if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0) + { + // Load the database driver. + if (in_array('database', $autoload['libraries'])) + { + $this->database(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); + } + + // Load scaffolding + if (in_array('scaffolding', $autoload['libraries'])) + { + $this->scaffolding(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding')); + } + + // Load all other libraries + foreach ($autoload['libraries'] as $item) + { + $this->library($item); + } + } + + // Autoload models + if (isset($autoload['model'])) + { + $this->model($autoload['model']); + } + + } + + // -------------------------------------------------------------------- + + /** + * Assign to Models + * + * Makes sure that anything loaded by the loader class (libraries, plugins, etc.) + * will be available to models, if any exist. + * + * @access private + * @param object + * @return array + */ + function _ci_assign_to_models() + { + if (count($this->_ci_models) == 0) + { + return; + } + + if ($this->_ci_is_instance()) + { + $CI =& get_instance(); + foreach ($this->_ci_models as $model) + { + $CI->$model->_assign_libraries(); + } + } + else + { + foreach ($this->_ci_models as $model) + { + $this->$model->_assign_libraries(); + } + } + } + + // -------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @access private + * @param object + * @return array + */ + function _ci_object_to_array($object) + { + return (is_object($object)) ? get_object_vars($object) : $object; + } + + // -------------------------------------------------------------------- + + /** + * Determines whether we should use the CI instance or $this + * + * @access private + * @return bool + */ + function _ci_is_instance() + { + if ($this->_ci_is_php5 == TRUE) + { + return TRUE; + } + + global $CI; + return (is_object($CI)) ? TRUE : FALSE; + } + +} +?> \ No newline at end of file diff --git a/system/libraries/Log.php b/system/libraries/Log.php new file mode 100755 index 0000000..f9ca85a --- /dev/null +++ b/system/libraries/Log.php @@ -0,0 +1,118 @@ + '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4'); + + /** + * Constructor + * + * @access public + * @param string the log file path + * @param string the error threshold + * @param string the date formatting codes + */ + function CI_Log() + { + $config =& get_config(); + + $this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/'; + + if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path)) + { + $this->_enabled = FALSE; + } + + if (is_numeric($config['log_threshold'])) + { + $this->_threshold = $config['log_threshold']; + } + + if ($config['log_date_format'] != '') + { + $this->_date_fmt = $config['log_date_format']; + } + } + + // -------------------------------------------------------------------- + + /** + * Write Log File + * + * Generally this function will be called using the global log_message() function + * + * @access public + * @param string the error level + * @param string the error message + * @param bool whether the error is a native PHP error + * @return bool + */ + function write_log($level = 'error', $msg, $php_error = FALSE) + { + if ($this->_enabled === FALSE) + { + return FALSE; + } + + $level = strtoupper($level); + + if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) + { + return FALSE; + } + + $filepath = $this->log_path.'log-'.date('Y-m-d').EXT; + $message = ''; + + if ( ! file_exists($filepath)) + { + $message .= "<"."?php if (!defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n"; + } + + if ( ! $fp = @fopen($filepath, "a")) + { + return FALSE; + } + + $message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n"; + + flock($fp, LOCK_EX); + fwrite($fp, $message); + flock($fp, LOCK_UN); + fclose($fp); + + @chmod($filepath, 0666); + return TRUE; + } + +} +// END Log Class +?> \ No newline at end of file diff --git a/system/libraries/Model.php b/system/libraries/Model.php new file mode 100755 index 0000000..8181ead --- /dev/null +++ b/system/libraries/Model.php @@ -0,0 +1,82 @@ +_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE ); + + // We don't want to assign the model object to itself when using the + // assign_libraries function below so we'll grab the name of the model parent + $this->_parent_name = ucfirst(get_class($this)); + + log_message('debug', "Model Class Initialized"); + } + + /** + * Assign Libraries + * + * Creates local references to all currently instantiated objects + * so that any syntax that can be legally used in a controller + * can be used within models. + * + * @access private + */ + function _assign_libraries($use_reference = TRUE) + { + $CI =& get_instance(); + foreach (array_keys(get_object_vars($CI)) as $key) + { + if ( ! isset($this->$key) AND $key != $this->_parent_name) + { + // In some cases using references can cause + // problems so we'll conditionally use them + if ($use_reference == TRUE) + { + // Needed to prevent reference errors with some configurations + $this->$key = ''; + $this->$key =& $CI->$key; + } + else + { + $this->$key = $CI->$key; + } + } + } + } + +} +// END Model Class +?> \ No newline at end of file diff --git a/system/libraries/Output.php b/system/libraries/Output.php new file mode 100755 index 0000000..a4d8d34 --- /dev/null +++ b/system/libraries/Output.php @@ -0,0 +1,386 @@ +final_output; + } + + // -------------------------------------------------------------------- + + /** + * Set Output + * + * Sets the output string + * + * @access public + * @param string + * @return void + */ + function set_output($output) + { + $this->final_output = $output; + } + + // -------------------------------------------------------------------- + + /** + * Append Output + * + * Appends data onto the output string + * + * @access public + * @param string + * @return void + */ + function append_output($output) + { + if ($this->final_output == '') + { + $this->final_output = $output; + } + else + { + $this->final_output .= $output; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Header + * + * Lets you set a server header which will be outputted with the final display. + * + * Note: If a file is cached, headers will not be sent. We need to figure out + * how to permit header data to be saved with the cache data... + * + * @access public + * @param string + * @return void + */ + function set_header($header) + { + $this->headers[] = $header; + } + + // -------------------------------------------------------------------- + + /** + * Enable/disable Profiler + * + * @access public + * @param bool + * @return void + */ + function enable_profiler($val = TRUE) + { + $this->enable_profiler = (is_bool($val)) ? $val : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set Cache + * + * @access public + * @param integer + * @return void + */ + function cache($time) + { + $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time; + } + + // -------------------------------------------------------------------- + + /** + * Display Output + * + * All "view" data is automatically put into this variable by the controller class: + * + * $this->final_output + * + * This function sends the finalized output data to the browser along + * with any server headers and profile data. It also stops the + * benchmark timer so the page rendering speed and memory usage can be shown. + * + * @access public + * @return mixed + */ + function _display($output = '') + { + // Note: We use globals because we can't use $CI =& get_instance() + // since this function is sometimes called by the caching mechanism, + // which happens before the CI super object is available. + global $BM, $CFG; + + // -------------------------------------------------------------------- + + // Set the output data + if ($output == '') + { + $output =& $this->final_output; + } + + // -------------------------------------------------------------------- + + // Do we need to write a cache file? + if ($this->cache_expiration > 0) + { + $this->_write_cache($output); + } + + // -------------------------------------------------------------------- + + // Parse out the elapsed time and memory usage, + // then swap the pseudo-variables with the data + + $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end'); + $output = str_replace('{elapsed_time}', $elapsed, $output); + + $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB'; + $output = str_replace('{memory_usage}', $memory, $output); + + // -------------------------------------------------------------------- + + // Is compression requested? + if ($CFG->item('compress_output') === TRUE) + { + if (extension_loaded('zlib')) + { + if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) + { + ob_start('ob_gzhandler'); + } + } + } + + // -------------------------------------------------------------------- + + // Are there any server headers to send? + if (count($this->headers) > 0) + { + foreach ($this->headers as $header) + { + @header($header); + } + } + + // -------------------------------------------------------------------- + + // Does the get_instance() function exist? + // If not we know we are dealing with a cache file so we'll + // simply echo out the data and exit. + if ( ! function_exists('get_instance')) + { + echo $output; + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: ".$elapsed); + return TRUE; + } + + // -------------------------------------------------------------------- + + // Grab the super object. We'll need it in a moment... + $CI =& get_instance(); + + // Do we need to generate profile data? + // If so, load the Profile class and run it. + if ($this->enable_profiler == TRUE) + { + $CI->load->library('profiler'); + + // If the output data contains closing and tags + // we will remove them and add them back after we insert the profile data + if (preg_match("|.*?|is", $output)) + { + $output = preg_replace("|.*?|is", '', $output); + $output .= $CI->profiler->run(); + $output .= ''; + } + else + { + $output .= $CI->profiler->run(); + } + } + + // -------------------------------------------------------------------- + + // Does the controller contain a function named _output()? + // If so send the output there. Otherwise, echo it. + if (method_exists($CI, '_output')) + { + $CI->_output($output); + } + else + { + echo $output; // Send it to the browser! + } + + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: ".$elapsed); + } + + // -------------------------------------------------------------------- + + /** + * Write a Cache File + * + * @access public + * @return void + */ + function _write_cache($output) + { + $CI =& get_instance(); + $path = $CI->config->item('cache_path'); + + $cache_path = ($path == '') ? BASEPATH.'cache/' : $path; + + if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) + { + return; + } + + $uri = $CI->config->item('base_url'). + $CI->config->item('index_page'). + $CI->uri->uri_string(); + + $cache_path .= md5($uri); + + if ( ! $fp = @fopen($cache_path, 'wb')) + { + log_message('error', "Unable to write cache file: ".$cache_path); + return; + } + + $expire = time() + ($this->cache_expiration * 60); + + flock($fp, LOCK_EX); + fwrite($fp, $expire.'TS--->'.$output); + flock($fp, LOCK_UN); + fclose($fp); + @chmod($cache_path, 0777); + + log_message('debug', "Cache file written: ".$cache_path); + } + + // -------------------------------------------------------------------- + + /** + * Update/serve a cached file + * + * @access public + * @return void + */ + function _display_cache(&$CFG, &$RTR) + { + $URI =& load_class('URI'); + + $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path'); + + if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) + { + return FALSE; + } + + // Build the file path. The file name is an MD5 hash of the full URI + $uri = $CFG->item('base_url'). + $CFG->item('index_page'). + $URI->uri_string; + + $filepath = $cache_path.md5($uri); + + if ( ! @file_exists($filepath)) + { + return FALSE; + } + + if ( ! $fp = @fopen($filepath, 'rb')) + { + return FALSE; + } + + flock($fp, LOCK_SH); + + $cache = ''; + if (filesize($filepath) > 0) + { + $cache = fread($fp, filesize($filepath)); + } + + flock($fp, LOCK_UN); + fclose($fp); + + // Strip out the embedded timestamp + if ( ! preg_match("/(\d+TS--->)/", $cache, $match)) + { + return FALSE; + } + + // Has the file expired? If so we'll delete it. + if (time() >= trim(str_replace('TS--->', '', $match['1']))) + { + @unlink($filepath); + log_message('debug', "Cache file has expired. File deleted"); + return FALSE; + } + + // Display the cache + $this->_display(str_replace($match['0'], '', $cache)); + log_message('debug', "Cache file is current. Sending it to browser."); + return TRUE; + } + + +} +// END Output Class +?> \ No newline at end of file diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php new file mode 100755 index 0000000..28b74f1 --- /dev/null +++ b/system/libraries/Pagination.php @@ -0,0 +1,218 @@ +'; + var $cur_tag_close = ''; + var $next_tag_open = ' '; + var $next_tag_close = ' '; + var $prev_tag_open = ' '; + var $prev_tag_close = ''; + var $num_tag_open = ' '; + var $num_tag_close = ''; + + /** + * Constructor + * + * @access public + * @param array initialization parameters + */ + function CI_Pagination($params = array()) + { + if (count($params) > 0) + { + $this->initialize($params); + } + + log_message('debug', "Pagination Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Preferences + * + * @access public + * @param array initialization parameters + * @return void + */ + function initialize($params = array()) + { + if (count($params) > 0) + { + foreach ($params as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + } + + // -------------------------------------------------------------------- + + /** + * Generate the pagination links + * + * @access public + * @return string + */ + function create_links() + { + // If our item count or per-page total is zero there is no need to continue. + if ($this->total_rows == 0 OR $this->per_page == 0) + { + return ''; + } + + // Calculate the total number of pages + $num_pages = ceil($this->total_rows / $this->per_page); + + // Is there only one page? Hm... nothing more to do here then. + if ($num_pages == 1) + { + return ''; + } + + // Determine the current page number. + $CI =& get_instance(); + if ($CI->uri->segment($this->uri_segment) != 0) + { + $this->cur_page = $CI->uri->segment($this->uri_segment); + + // Prep the current page - no funny business! + $this->cur_page = (int) $this->cur_page; + } + + $this->num_links = (int)$this->num_links; + + if ($this->num_links < 1) + { + show_error('Your number of links must be a positive number.'); + } + + if ( ! is_numeric($this->cur_page)) + { + $this->cur_page = 0; + } + + // Is the page number beyond the result range? + // If so we show the last page + if ($this->cur_page > $this->total_rows) + { + $this->cur_page = ($num_pages - 1) * $this->per_page; + } + + $uri_page_number = $this->cur_page; + $this->cur_page = floor(($this->cur_page/$this->per_page) + 1); + + // Calculate the start and end numbers. These determine + // which number to start and end the digit links with + $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1; + $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages; + + // Add a trailing slash to the base URL if needed + $this->base_url = rtrim($this->base_url, '/') .'/'; + + // And here we go... + $output = ''; + + // Render the "First" link + if ($this->cur_page > $this->num_links) + { + $output .= $this->first_tag_open.''.$this->first_link.''.$this->first_tag_close; + } + + // Render the "previous" link + if ($this->cur_page != 1) + { + $i = $uri_page_number - $this->per_page; + if ($i == 0) $i = ''; + $output .= $this->prev_tag_open.''.$this->prev_link.''.$this->prev_tag_close; + } + + // Write the digit links + for ($loop = $start -1; $loop <= $end; $loop++) + { + $i = ($loop * $this->per_page) - $this->per_page; + + if ($i >= 0) + { + if ($this->cur_page == $loop) + { + $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page + } + else + { + $n = ($i == 0) ? '' : $i; + $output .= $this->num_tag_open.''.$loop.''.$this->num_tag_close; + } + } + } + + // Render the "next" link + if ($this->cur_page < $num_pages) + { + $output .= $this->next_tag_open.''.$this->next_link.''.$this->next_tag_close; + } + + // Render the "Last" link + if (($this->cur_page + $this->num_links) < $num_pages) + { + $i = (($num_pages * $this->per_page) - $this->per_page); + $output .= $this->last_tag_open.''.$this->last_link.''.$this->last_tag_close; + } + + // Kill double slashes. Note: Sometimes we can end up with a double slash + // in the penultimate link so we'll kill all double slashes. + $output = preg_replace("#([^:])//+#", "\\1/", $output); + + // Add the wrapper HTML if exists + $output = $this->full_tag_open.$output.$this->full_tag_close; + + return $output; + } +} +// END Pagination Class +?> \ No newline at end of file diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php new file mode 100755 index 0000000..a0b310f --- /dev/null +++ b/system/libraries/Parser.php @@ -0,0 +1,171 @@ +load->view($template, $data, TRUE); + + if ($template == '') + { + return FALSE; + } + + foreach ($data as $key => $val) + { + if (is_array($val)) + { + $template = $this->_parse_pair($key, $val, $template); + } + else + { + $template = $this->_parse_single($key, (string)$val, $template); + } + } + + if ($return == FALSE) + { + $CI->output->final_output = $template; + } + + return $template; + } + + // -------------------------------------------------------------------- + + /** + * Set the left/right variable delimiters + * + * @access public + * @param string + * @param string + * @return void + */ + function set_delimiters($l = '{', $r = '}') + { + $this->l_delim = $l; + $this->r_delim = $r; + } + + // -------------------------------------------------------------------- + + /** + * Parse a single key/value + * + * @access private + * @param string + * @param string + * @param string + * @return string + */ + function _parse_single($key, $val, $string) + { + return str_replace($this->l_delim.$key.$this->r_delim, $val, $string); + } + + // -------------------------------------------------------------------- + + /** + * Parse a tag pair + * + * Parses tag pairs: {some_tag} string... {/some_tag} + * + * @access private + * @param string + * @param array + * @param string + * @return string + */ + function _parse_pair($variable, $data, $string) + { + if (FALSE === ($match = $this->_match_pair($string, $variable))) + { + return $string; + } + + $str = ''; + foreach ($data as $row) + { + $temp = $match['1']; + foreach ($row as $key => $val) + { + if ( ! is_array($val)) + { + $temp = $this->_parse_single($key, $val, $temp); + } + else + { + $temp = $this->_parse_pair($key, $val, $temp); + } + } + + $str .= $temp; + } + + return str_replace($match['0'], $str, $string); + } + + // -------------------------------------------------------------------- + + /** + * Matches a variable pair + * + * @access private + * @param string + * @param string + * @return mixed + */ + function _match_pair($string, $variable) + { + if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match)) + { + return FALSE; + } + + return $match; + } + +} +// END Parser Class +?> \ No newline at end of file diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php new file mode 100755 index 0000000..8a45933 --- /dev/null +++ b/system/libraries/Profiler.php @@ -0,0 +1,343 @@ +CI =& get_instance(); + $this->CI->load->language('profiler'); + } + + // -------------------------------------------------------------------- + + /** + * Auto Profiler + * + * This function cycles through the entire array of mark points and + * matches any two points that are named identically (ending in "_start" + * and "_end" respectively). It then compiles the execution times for + * all points and returns it as an array + * + * @access private + * @return array + */ + function _compile_benchmarks() + { + $profile = array(); + foreach ($this->CI->benchmark->marker as $key => $val) + { + // We match the "end" marker so that the list ends + // up in the order that it was defined + if (preg_match("/(.+?)_end/i", $key, $match)) + { + if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start'])) + { + $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key); + } + } + } + + // Build a table containing the profile data. + // Note: At some point we should turn this into a template that can + // be modified. We also might want to make this data available to be logged + + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_benchmarks').'  '; + $output .= "\n"; + $output .= "\n\n\n"; + + foreach ($profile as $key => $val) + { + $key = ucwords(str_replace(array('_', '-'), ' ', $key)); + $output .= "\n"; + } + + $output .= "
    ".$key."  ".$val."
    \n"; + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile Queries + * + * @access private + * @return string + */ + function _compile_queries() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + + if ( ! class_exists('CI_DB_driver')) + { + $output .= '  '.$this->CI->lang->line('profiler_queries').'  '; + $output .= "\n"; + $output .= "\n\n\n"; + $output .="\n"; + } + else + { + $output .= '  '.$this->CI->lang->line('profiler_queries').' ('.count($this->CI->db->queries).')  '; + $output .= "\n"; + $output .= "\n\n
    ".$this->CI->lang->line('profiler_no_db')."
    \n"; + + if (count($this->CI->db->queries) == 0) + { + $output .= "\n"; + } + else + { + $highlight = array('SELECT', 'FROM', 'WHERE', 'AND', 'LEFT JOIN', 'ORDER BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR'); + + foreach ($this->CI->db->queries as $key => $val) + { + $val = htmlspecialchars($val, ENT_QUOTES); + $time = number_format($this->CI->db->query_times[$key], 4); + + foreach ($highlight as $bold) + { + $val = str_replace($bold, ''.$bold.'', $val); + } + + $output .= "\n"; + } + } + } + + $output .= "
    ".$this->CI->lang->line('profiler_no_queries')."
    ".$time."  ".$val."
    \n"; + $output .= "
    "; + + return $output; + } + + + // -------------------------------------------------------------------- + + /** + * Compile $_GET Data + * + * @access private + * @return string + */ + function _compile_get() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_get_data').'  '; + $output .= "\n"; + + if (count($_GET) == 0) + { + $output .= "
    ".$this->CI->lang->line('profiler_no_get')."
    "; + } + else + { + $output .= "\n\n\n"; + + foreach ($_GET as $key => $val) + { + if ( ! is_numeric($key)) + { + $key = "'".$key."'"; + } + + $output .= "\n"; + } + + $output .= "
    $_GET[".$key."]   "; + if (is_array($val)) + { + $output .= "
    " . htmlspecialchars(stripslashes(print_r($val, true))) . "
    "; + } + else + { + $output .= htmlspecialchars(stripslashes($val)); + } + $output .= "
    \n"; + } + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile $_POST Data + * + * @access private + * @return string + */ + function _compile_post() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_post_data').'  '; + $output .= "\n"; + + if (count($_POST) == 0) + { + $output .= "
    ".$this->CI->lang->line('profiler_no_post')."
    "; + } + else + { + $output .= "\n\n\n"; + + foreach ($_POST as $key => $val) + { + if ( ! is_numeric($key)) + { + $key = "'".$key."'"; + } + +// $output .= "\n"; + $output .= "\n"; + } + + $output .= "
    $_POST[".$key."]  ".htmlspecialchars(stripslashes($val))."
    $_POST[".$key."]   "; + if (is_array($val)) + { + $output .= "
    " . htmlspecialchars(stripslashes(print_r($val, true))) . "
    "; + } + else + { + $output .= htmlspecialchars(stripslashes($val)); + } + $output .= "
    \n"; + } + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Show query string + * + * @access private + * @return string + */ + function _compile_uri_string() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_uri_string').'  '; + $output .= "\n"; + + if ($this->CI->uri->uri_string == '') + { + $output .= "
    ".$this->CI->lang->line('profiler_no_uri')."
    "; + } + else + { + $output .= "
    ".$this->CI->uri->uri_string."
    "; + } + + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile memory usage + * + * Display total used memory + * + * @access public + * @return string + */ + function _compile_memory_usage() + { + $output = "\n\n"; + $output .= '
    '; + $output .= "\n"; + $output .= '  '.$this->CI->lang->line('profiler_memory_usage').'  '; + $output .= "\n"; + + if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') + { + $output .= "
    ".number_format($usage).' bytes
    '; + } + else + { + $output .= "
    ".$this->CI->lang->line('profiler_no_memory_usage')."
    "; + } + + $output .= "
    "; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Run the Profiler + * + * @access private + * @return string + */ + function run() + { + $output = '
    '; + $output .= "
    "; + + $output .= $this->_compile_memory_usage(); + $output .= $this->_compile_benchmarks(); + $output .= $this->_compile_uri_string(); + $output .= $this->_compile_get(); + $output .= $this->_compile_post(); + $output .= $this->_compile_queries(); + + $output .= '
    '; + + return $output; + } + +} + +// END CI_Profiler class +?> \ No newline at end of file diff --git a/system/libraries/Router.php b/system/libraries/Router.php new file mode 100755 index 0000000..f6464a3 --- /dev/null +++ b/system/libraries/Router.php @@ -0,0 +1,377 @@ +config =& load_class('Config'); + $this->uri =& load_class('URI'); + $this->_set_routing(); + log_message('debug', "Router Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Set the route mapping + * + * This function determines what should be served based on the URI request, + * as well as any "routes" that have been set in the routing config file. + * + * @access private + * @return void + */ + function _set_routing() + { + // Are query strings enabled in the config file? + // If so, we're done since segment based URIs are not used with query strings. + if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')])) + { + $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')]))); + + if (isset($_GET[$this->config->item('function_trigger')])) + { + $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')]))); + } + + return; + } + + // Load the routes.php file. + @include(APPPATH.'config/routes'.EXT); + $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route; + unset($route); + + // Set the default controller so we can display it in the event + // the URI doesn't correlated to a valid controller. + $this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']); + + // Fetch the complete URI string + $this->uri->_fetch_uri_string(); + + // Is there a URI string? If not, the default controller specified in the "routes" file will be shown. + if ($this->uri->uri_string == '') + { + if ($this->default_controller === FALSE) + { + show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); + } + + $this->set_class($this->default_controller); + $this->set_method('index'); + $this->_set_request(array($this->default_controller, 'index')); + + // re-index the routed segments array so it starts with 1 rather than 0 + $this->uri->_reindex_segments(); + + log_message('debug', "No URI present. Default controller set."); + return; + } + unset($this->routes['default_controller']); + + // Do we need to remove the URL suffix? + $this->uri->_remove_url_suffix(); + + // Compile the segments into an array + $this->uri->_explode_segments(); + + // Parse any custom routing that may exist + $this->_parse_routes(); + + // Re-index the segment array so that it starts with 1 rather than 0 + $this->uri->_reindex_segments(); + } + + // -------------------------------------------------------------------- + + /** + * Set the Route + * + * This function takes an array of URI segments as + * input, and sets the current class/method + * + * @access private + * @param array + * @param bool + * @return void + */ + function _set_request($segments = array()) + { + $segments = $this->_validate_request($segments); + + if (count($segments) == 0) + { + return; + } + + $this->set_class($segments[0]); + + if (isset($segments[1])) + { + // A scaffolding request. No funny business with the URL + if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding') + { + $this->scaffolding_request = TRUE; + unset($this->routes['scaffolding_trigger']); + } + else + { + // A standard method request + $this->set_method($segments[1]); + } + } + else + { + // This lets the "routed" segment array identify that the default + // index method is being used. + $segments[1] = 'index'; + } + + // Update our "routed" segment array to contain the segments. + // Note: If there is no custom routing, this array will be + // identical to $this->uri->segments + $this->uri->rsegments = $segments; + } + + // -------------------------------------------------------------------- + + /** + * Validates the supplied segments. Attempts to determine the path to + * the controller. + * + * @access private + * @param array + * @return array + */ + function _validate_request($segments) + { + // Does the requested controller exist in the root folder? + if (file_exists(APPPATH.'controllers/'.$segments[0].EXT)) + { + return $segments; + } + + // Is the controller in a sub-folder? + if (is_dir(APPPATH.'controllers/'.$segments[0])) + { + // Set the directory and remove it from the segment array + $this->set_directory($segments[0]); + $segments = array_slice($segments, 1); + + if (count($segments) > 0) + { + // Does the requested controller exist in the sub-folder? + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT)) + { + show_404(); + } + } + else + { + $this->set_class($this->default_controller); + $this->set_method('index'); + + // Does the default controller exist in the sub-folder? + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT)) + { + $this->directory = ''; + return array(); + } + + } + + return $segments; + } + + // Can't find the requested controller... + show_404(); + } + + // -------------------------------------------------------------------- + + /** + * Parse Routes + * + * This function matches any routes that may exist in + * the config/routes.php file against the URI to + * determine if the class/method need to be remapped. + * + * @access private + * @return void + */ + function _parse_routes() + { + // Do we even have any custom routing to deal with? + // There is a default scaffolding trigger, so we'll look just for 1 + if (count($this->routes) == 1) + { + $this->_set_request($this->uri->segments); + return; + } + + // Turn the segment array into a URI string + $uri = implode('/', $this->uri->segments); + $num = count($this->uri->segments); + + // Is there a literal match? If so we're done + if (isset($this->routes[$uri])) + { + $this->_set_request(explode('/', $this->routes[$uri])); + return; + } + + // Loop through the route array looking for wild-cards + foreach ($this->routes as $key => $val) + { + // Convert wild-cards to RegEx + $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); + + // Does the RegEx match? + if (preg_match('#^'.$key.'$#', $uri)) + { + // Do we have a back-reference? + if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) + { + $val = preg_replace('#^'.$key.'$#', $val, $uri); + } + + $this->_set_request(explode('/', $val)); + return; + } + } + + // If we got this far it means we didn't encounter a + // matching route so we'll set the site default route + $this->_set_request($this->uri->segments); + } + + // -------------------------------------------------------------------- + + /** + * Set the class name + * + * @access public + * @param string + * @return void + */ + function set_class($class) + { + $this->class = $class; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current class + * + * @access public + * @return string + */ + function fetch_class() + { + return $this->class; + } + + // -------------------------------------------------------------------- + + /** + * Set the method name + * + * @access public + * @param string + * @return void + */ + function set_method($method) + { + $this->method = $method; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current method + * + * @access public + * @return string + */ + function fetch_method() + { + if ($this->method == $this->fetch_class()) + { + return 'index'; + } + + return $this->method; + } + + // -------------------------------------------------------------------- + + /** + * Set the directory name + * + * @access public + * @param string + * @return void + */ + function set_directory($dir) + { + $this->directory = $dir.'/'; + } + + // -------------------------------------------------------------------- + + /** + * Fetch the sub-directory (if any) that contains the requested controller class + * + * @access public + * @return string + */ + function fetch_directory() + { + return $this->directory; + } + +} +// END Router Class +?> \ No newline at end of file diff --git a/system/libraries/Session.php b/system/libraries/Session.php new file mode 100755 index 0000000..2cdd50c --- /dev/null +++ b/system/libraries/Session.php @@ -0,0 +1,632 @@ +CI =& get_instance(); + + log_message('debug', "Session Class Initialized"); + $this->sess_run(); + } + + // -------------------------------------------------------------------- + + /** + * Run the session routines + * + * @access public + * @return void + */ + function sess_run() + { + /* + * Set the "now" time + * + * It can either set to GMT or time(). The pref + * is set in the config file. If the developer + * is doing any sort of time localization they + * might want to set the session time to GMT so + * they can offset the "last_activity" time + * based on each user's locale. + * + */ + + if (is_numeric($this->CI->config->item('sess_time_to_update'))) + { + $this->time_to_update = $this->CI->config->item('sess_time_to_update'); + } + + if (strtolower($this->CI->config->item('time_reference')) == 'gmt') + { + $now = time(); + $this->now = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)); + + if (strlen($this->now) < 10) + { + $this->now = time(); + log_message('error', 'The session class could not set a proper GMT timestamp so the local time() value was used.'); + } + } + else + { + $this->now = time(); + } + + /* + * Set the session length + * + * If the session expiration is set to zero in + * the config file we'll set the expiration + * two years from now. + * + */ + $expiration = $this->CI->config->item('sess_expiration'); + + if (is_numeric($expiration)) + { + if ($expiration > 0) + { + $this->sess_length = $this->CI->config->item('sess_expiration'); + } + else + { + $this->sess_length = (60*60*24*365*2); + } + } + + // Do we need encryption? + $this->encryption = $this->CI->config->item('sess_encrypt_cookie'); + + if ($this->encryption == TRUE) + { + $this->CI->load->library('encrypt'); + } + + // Are we using a database? + if ($this->CI->config->item('sess_use_database') === TRUE AND $this->CI->config->item('sess_table_name') != '') + { + $this->use_database = TRUE; + $this->session_table = $this->CI->config->item('sess_table_name'); + $this->CI->load->database(); + } + + // Set the cookie name + if ($this->CI->config->item('sess_cookie_name') != FALSE) + { + $this->sess_cookie = $this->CI->config->item('cookie_prefix').$this->CI->config->item('sess_cookie_name'); + } + + /* + * Fetch the current session + * + * If a session doesn't exist we'll create + * a new one. If it does, we'll update it. + * + */ + if ( ! $this->sess_read()) + { + $this->sess_create(); + } + else + { + // We only update the session every five minutes + if (($this->userdata['last_activity'] + $this->time_to_update) < $this->now) + { + $this->sess_update(); + } + } + + // Delete expired sessions if necessary + if ($this->use_database === TRUE) + { + $this->sess_gc(); + } + + // Delete 'old' flashdata (from last request) + $this->_flashdata_sweep(); + + // Mark all new flashdata as old (data will be deleted before next request) + $this->_flashdata_mark(); + } + + // -------------------------------------------------------------------- + + /** + * Fetch the current session data if it exists + * + * @access public + * @return void + */ + function sess_read() + { + // Fetch the cookie + $session = $this->CI->input->cookie($this->sess_cookie); + + if ($session === FALSE) + { + log_message('debug', 'A session cookie was not found.'); + return FALSE; + } + + // Decrypt and unserialize the data + if ($this->encryption == TRUE) + { + $session = $this->CI->encrypt->decode($session); + } + + $session = @unserialize($this->strip_slashes($session)); + + if ( ! is_array($session) OR ! isset($session['last_activity'])) + { + log_message('error', 'The session cookie data did not contain a valid array. This could be a possible hacking attempt.'); + return FALSE; + } + + // Is the session current? + if (($session['last_activity'] + $this->sess_length) < $this->now) + { + $this->sess_destroy(); + return FALSE; + } + + // Does the IP Match? + if ($this->CI->config->item('sess_match_ip') == TRUE AND $session['ip_address'] != $this->CI->input->ip_address()) + { + $this->sess_destroy(); + return FALSE; + } + + // Does the User Agent Match? + if ($this->CI->config->item('sess_match_useragent') == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))) + { + $this->sess_destroy(); + return FALSE; + } + + // Is there a corresponding session in the DB? + if ($this->use_database === TRUE) + { + $this->CI->db->where('session_id', $session['session_id']); + + if ($this->CI->config->item('sess_match_ip') == TRUE) + { + $this->CI->db->where('ip_address', $session['ip_address']); + } + + if ($this->CI->config->item('sess_match_useragent') == TRUE) + { + $this->CI->db->where('user_agent', $session['user_agent']); + } + + $query = $this->CI->db->get($this->session_table); + + if ($query->num_rows() == 0) + { + $this->sess_destroy(); + return FALSE; + } + else + { + $row = $query->row(); + if (($row->last_activity + $this->sess_length) < $this->now) + { + $this->CI->db->where('session_id', $session['session_id']); + $this->CI->db->delete($this->session_table); + $this->sess_destroy(); + return FALSE; + } + } + } + + // Session is valid! + $this->userdata = $session; + unset($session); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Write the session cookie + * + * @access public + * @return void + */ + function sess_write() + { + $cookie_data = serialize($this->userdata); + + if ($this->encryption == TRUE) + { + $cookie_data = $this->CI->encrypt->encode($cookie_data); + } + + setcookie( + $this->sess_cookie, + $cookie_data, + $this->sess_length + time(), + $this->CI->config->item('cookie_path'), + $this->CI->config->item('cookie_domain'), + 0 + ); + } + + // -------------------------------------------------------------------- + + /** + * Create a new session + * + * @access public + * @return void + */ + function sess_create() + { + $sessid = ''; + while (strlen($sessid) < 32) + { + $sessid .= mt_rand(0, mt_getrandmax()); + } + + $this->userdata = array( + 'session_id' => md5(uniqid($sessid, TRUE)), + 'ip_address' => $this->CI->input->ip_address(), + 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), + 'last_activity' => $this->now + ); + + + // Save the session in the DB if needed + if ($this->use_database === TRUE) + { + $this->CI->db->query($this->CI->db->insert_string($this->session_table, $this->userdata)); + } + + // Write the cookie + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Update an existing session + * + * @access public + * @return void + */ + function sess_update() + { + // Save the old session id so we know which record to + // update in the database if we need it + $old_sessid = $this->userdata['session_id']; + $new_sessid = ''; + while (strlen($new_sessid) < 32) + { + $new_sessid .= mt_rand(0, mt_getrandmax()); + } + $new_sessid = md5(uniqid($new_sessid, TRUE)); + + // Update the session data in the session data array + $this->userdata['session_id'] = $new_sessid; + $this->userdata['last_activity'] = $this->now; + + // Update the session in the DB if needed + if ($this->use_database === TRUE) + { + $this->CI->db->query($this->CI->db->update_string($this->session_table, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid))); + } + + // Write the cookie + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Destroy the current session + * + * @access public + * @return void + */ + function sess_destroy() + { + setcookie( + $this->sess_cookie, + addslashes(serialize(array())), + ($this->now - 31500000), + $this->CI->config->item('cookie_path'), + $this->CI->config->item('cookie_domain'), + 0 + ); + } + + // -------------------------------------------------------------------- + + /** + * Garbage collection + * + * This deletes expired session rows from database + * if the probability percentage is met + * + * @access public + * @return void + */ + function sess_gc() + { + srand(time()); + if ((rand() % 100) < $this->gc_probability) + { + $expire = $this->now - $this->sess_length; + + $this->CI->db->where("last_activity < {$expire}"); + $this->CI->db->delete($this->session_table); + + log_message('debug', 'Session garbage collection performed.'); + } + } + + // -------------------------------------------------------------------- + + /** + * Fetch a specific item from the session array + * + * @access public + * @param string + * @return string + */ + function userdata($item) + { + return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch all session data + * + * @access public + * @return mixed + */ + function all_userdata() + { + return ( ! isset($this->userdata)) ? FALSE : $this->userdata; + } + + // -------------------------------------------------------------------- + + /** + * Add or change data in the "userdata" array + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_userdata($newdata = array(), $newval = '') + { + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $this->userdata[$key] = $val; + } + } + + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Delete a session variable from the "userdata" array + * + * @access array + * @return void + */ + function unset_userdata($newdata = array()) + { + if (is_string($newdata)) + { + $newdata = array($newdata => ''); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + unset($this->userdata[$key]); + } + } + + $this->sess_write(); + } + + // -------------------------------------------------------------------- + + /** + * Strip slashes + * + * @access public + * @param mixed + * @return mixed + */ + function strip_slashes($vals) + { + if (is_array($vals)) + { + foreach ($vals as $key=>$val) + { + $vals[$key] = $this->strip_slashes($val); + } + } + else + { + $vals = stripslashes($vals); + } + + return $vals; + } + + + // ------------------------------------------------------------------------ + + /** + * Add or change flashdata, only available + * until the next request + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_flashdata($newdata = array(), $newval = '') + { + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $flashdata_key = $this->flashdata_key.':new:'.$key; + $this->set_userdata($flashdata_key, $val); + } + } + } + + // ------------------------------------------------------------------------ + + /** + * Keeps existing flashdata available to next request. + * + * @access public + * @param string + * @return void + */ + function keep_flashdata($key) + { + // 'old' flashdata gets removed. Here we mark all + // flashdata as 'new' to preserve it from _flashdata_sweep() + // Note the function will return FALSE if the $key + // provided cannot be found + $old_flashdata_key = $this->flashdata_key.':old:'.$key; + $value = $this->userdata($old_flashdata_key); + + $new_flashdata_key = $this->flashdata_key.':new:'.$key; + $this->set_userdata($new_flashdata_key, $value); + } + + // ------------------------------------------------------------------------ + + /** + * Fetch a specific flashdata item from the session array + * + * @access public + * @param string + * @return string + */ + function flashdata($key) + { + $flashdata_key = $this->flashdata_key.':old:'.$key; + return $this->userdata($flashdata_key); + } + + // ------------------------------------------------------------------------ + + /** + * Identifies flashdata as 'old' for removal + * when _flashdata_sweep() runs. + * + * @access private + * @return void + */ + function _flashdata_mark() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $name => $value) + { + $parts = explode(':new:', $name); + if (is_array($parts) && count($parts) === 2) + { + $new_name = $this->flashdata_key.':old:'.$parts[1]; + $this->set_userdata($new_name, $value); + $this->unset_userdata($name); + } + } + } + + // ------------------------------------------------------------------------ + + /** + * Removes all flashdata marked as 'old' + * + * @access private + * @return void + */ + + function _flashdata_sweep() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $key => $value) + { + if (strpos($key, ':old:')) + { + $this->unset_userdata($key); + } + } + + } + +} +// END Session Class +?> \ No newline at end of file diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php new file mode 100755 index 0000000..6bb8911 --- /dev/null +++ b/system/libraries/Sha1.php @@ -0,0 +1,249 @@ +> 6) + 1; + + for ($i = 0; $i < $n * 16; $i++) + { + $x[$i] = 0; + } + + for ($i = 0; $i < strlen($str); $i++) + { + $x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8); + } + + $x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8); + + $x[$n * 16 - 1] = strlen($str) * 8; + + $a = 1732584193; + $b = -271733879; + $c = -1732584194; + $d = 271733878; + $e = -1009589776; + + for ($i = 0; $i < sizeof($x); $i += 16) + { + $olda = $a; + $oldb = $b; + $oldc = $c; + $oldd = $d; + $olde = $e; + + for($j = 0; $j < 80; $j++) + { + if ($j < 16) + { + $w[$j] = $x[$i + $j]; + } + else + { + $w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1); + } + + $t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j))); + + $e = $d; + $d = $c; + $c = $this->_rol($b, 30); + $b = $a; + $a = $t; + } + + $a = $this->_safe_add($a, $olda); + $b = $this->_safe_add($b, $oldb); + $c = $this->_safe_add($c, $oldc); + $d = $this->_safe_add($d, $oldd); + $e = $this->_safe_add($e, $olde); + } + + return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e); + } + + // -------------------------------------------------------------------- + + /** + * Convert a decimal to hex + * + * @access private + * @param string + * @return string + */ + function _hex($str) + { + $str = dechex($str); + + if (strlen($str) == 7) + { + $str = '0'.$str; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Return result based on iteration + * + * @access private + * @return string + */ + function _ft($t, $b, $c, $d) + { + if ($t < 20) + return ($b & $c) | ((~$b) & $d); + if ($t < 40) + return $b ^ $c ^ $d; + if ($t < 60) + return ($b & $c) | ($b & $d) | ($c & $d); + + return $b ^ $c ^ $d; + } + + // -------------------------------------------------------------------- + + /** + * Determine the additive constant + * + * @access private + * @return string + */ + function _kt($t) + { + if ($t < 20) + { + return 1518500249; + } + else if ($t < 40) + { + return 1859775393; + } + else if ($t < 60) + { + return -1894007588; + } + else + { + return -899497514; + } + } + + // -------------------------------------------------------------------- + + /** + * Add integers, wrapping at 2^32 + * + * @access private + * @return string + */ + function _safe_add($x, $y) + { + $lsw = ($x & 0xFFFF) + ($y & 0xFFFF); + $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16); + + return ($msw << 16) | ($lsw & 0xFFFF); + } + + // -------------------------------------------------------------------- + + /** + * Bitwise rotate a 32-bit number + * + * @access private + * @return integer + */ + function _rol($num, $cnt) + { + return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt); + } + + // -------------------------------------------------------------------- + + /** + * Pad string with zero + * + * @access private + * @return string + */ + function _zero_fill($a, $b) + { + $bin = decbin($a); + + if (strlen($bin) < $b) + { + $bin = 0; + } + else + { + $bin = substr($bin, 0, strlen($bin) - $b); + } + + for ($i=0; $i < $b; $i++) + { + $bin = "0".$bin; + } + + return bindec($bin); + } +} +// END CI_SHA +?> \ No newline at end of file diff --git a/system/libraries/Table.php b/system/libraries/Table.php new file mode 100755 index 0000000..d1c5254 --- /dev/null +++ b/system/libraries/Table.php @@ -0,0 +1,439 @@ +template = $template; + } + + // -------------------------------------------------------------------- + + /** + * Set the table heading + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function set_heading() + { + $args = func_get_args(); + $this->heading = (is_array($args[0])) ? $args[0] : $args; + } + + // -------------------------------------------------------------------- + + /** + * Set columns. Takes a one-dimensional array as input and creates + * a multi-dimensional array with a depth equal to the number of + * columns. This allows a single array with many elements to be + * displayed in a table that has a fixed column count. + * + * @access public + * @param array + * @param int + * @return void + */ + function make_columns($array = array(), $col_limit = 0) + { + if ( ! is_array($array) OR count($array) == 0) + { + return FALSE; + } + + // Turn off the auto-heading feature since it's doubtful we + // will want headings from a one-dimensional array + $this->auto_heading = FALSE; + + if ($col_limit == 0) + { + return $array; + } + + $new = array(); + while(count($array) > 0) + { + $temp = array_slice($array, 0, $col_limit); + $array = array_diff($array, $temp); + + if (count($temp) < $col_limit) + { + for ($i = count($temp); $i < $col_limit; $i++) + { + $temp[] = ' '; + } + } + + $new[] = $temp; + } + + return $new; + } + + // -------------------------------------------------------------------- + + /** + * Set "empty" cells + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function set_empty($value) + { + $this->empty_cells = $value; + } + + // -------------------------------------------------------------------- + + /** + * Add a table row + * + * Can be passed as an array or discreet params + * + * @access public + * @param mixed + * @return void + */ + function add_row() + { + $args = func_get_args(); + $this->rows[] = (is_array($args[0])) ? $args[0] : $args; + } + + // -------------------------------------------------------------------- + + /** + * Add a table caption + * + * @access public + * @param string + * @return void + */ + function set_caption($caption) + { + $this->caption = $caption; + } + + // -------------------------------------------------------------------- + + /** + * Generate the table + * + * @access public + * @param mixed + * @return string + */ + function generate($table_data = NULL) + { + // The table data can optionally be passed to this function + // either as a database result object or an array + if ( ! is_null($table_data)) + { + if (is_object($table_data)) + { + $this->_set_from_object($table_data); + } + elseif (is_array($table_data)) + { + $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE; + $this->_set_from_array($table_data, $set_heading); + } + } + + // Is there anything to display? No? Smite them! + if (count($this->heading) == 0 AND count($this->rows) == 0) + { + return 'Undefined table data'; + } + + // Compile and validate the template date + $this->_compile_template(); + + + // Build the table! + + $out = $this->template['table_open']; + $out .= $this->newline; + + // Add any caption here + if ($this->caption) + { + $out .= $this->newline; + $out .= '' . $this->caption . ''; + $out .= $this->newline; + } + + // Is there a table heading to display? + if (count($this->heading) > 0) + { + $out .= $this->template['heading_row_start']; + $out .= $this->newline; + + foreach($this->heading as $heading) + { + $out .= $this->template['heading_cell_start']; + $out .= $heading; + $out .= $this->template['heading_cell_end']; + } + + $out .= $this->template['heading_row_end']; + $out .= $this->newline; + } + + // Build the table rows + if (count($this->rows) > 0) + { + $i = 1; + foreach($this->rows as $row) + { + if ( ! is_array($row)) + { + break; + } + + // We use modulus to alternate the row colors + $name = (fmod($i++, 2)) ? '' : 'alt_'; + + $out .= $this->template['row_'.$name.'start']; + $out .= $this->newline; + + foreach($row as $cell) + { + $out .= $this->template['cell_'.$name.'start']; + + if ($cell == "") + { + $out .= $this->empty_cells; + } + else + { + $out .= $cell; + } + + $out .= $this->template['cell_'.$name.'end']; + } + + $out .= $this->template['row_'.$name.'end']; + $out .= $this->newline; + } + } + + $out .= $this->template['table_close']; + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Clears the table arrays. Useful if multiple tables are being generated + * + * @access public + * @return void + */ + function clear() + { + $this->rows = array(); + $this->heading = array(); + $this->auto_heading = TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Set table data from a database result object + * + * @access public + * @param object + * @return void + */ + function _set_from_object($query) + { + if ( ! is_object($query)) + { + return FALSE; + } + + // First generate the headings from the table column names + if (count($this->heading) == 0) + { + if ( ! method_exists($query, 'list_fields')) + { + return FALSE; + } + + $this->heading = $query->list_fields(); + } + + // Next blast through the result array and build out the rows + + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $this->rows[] = $row; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set table data from an array + * + * @access public + * @param array + * @return void + */ + function _set_from_array($data, $set_heading = TRUE) + { + if ( ! is_array($data) OR count($data) == 0) + { + return FALSE; + } + + $i = 0; + foreach ($data as $row) + { + if ( ! is_array($row)) + { + $this->rows[] = $data; + break; + } + + // If a heading hasn't already been set we'll use the first row of the array as the heading + if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE) + { + $this->heading = $row; + } + else + { + $this->rows[] = $row; + } + + $i++; + } + } + + // -------------------------------------------------------------------- + + /** + * Compile Template + * + * @access private + * @return void + */ + function _compile_template() + { + if ($this->template == NULL) + { + $this->template = $this->_default_template(); + return; + } + + $this->temp = $this->_default_template(); + foreach (array('table_open','heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val) + { + if ( ! isset($this->template[$val])) + { + $this->template[$val] = $this->temp[$val]; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Default Template + * + * @access private + * @return void + */ + function _default_template() + { + return array ( + 'table_open' => '', + + 'heading_row_start' => '', + 'heading_row_end' => '', + 'heading_cell_start' => '', + + 'row_start' => '', + 'row_end' => '', + 'cell_start' => '', + + 'row_alt_start' => '', + 'row_alt_end' => '', + 'cell_alt_start' => '', + + 'table_close' => '
    ', + 'heading_cell_end' => '
    ', + 'cell_end' => '
    ', + 'cell_alt_end' => '
    ' + ); + } + + +} + +?> \ No newline at end of file diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php new file mode 100755 index 0000000..5371e90 --- /dev/null +++ b/system/libraries/Trackback.php @@ -0,0 +1,548 @@ + '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => ''); + var $convert_ascii = TRUE; + var $response = ''; + var $error_msg = array(); + + /** + * Constructor + * + * @access public + */ + function CI_Trackback() + { + log_message('debug', "Trackback Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback + * + * @access public + * @param array + * @return bool + */ + function send($tb_data) + { + if ( ! is_array($tb_data)) + { + $this->set_error('The send() method must be passed an array'); + return FALSE; + } + + // Pre-process the Trackback Data + foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item) + { + if ( ! isset($tb_data[$item])) + { + $this->set_error('Required item missing: '.$item); + return FALSE; + } + + switch ($item) + { + case 'ping_url' : $$item = $this->extract_urls($tb_data[$item]); + break; + case 'excerpt' : $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); + break; + case 'url' : $$item = str_replace('-', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); + break; + default : $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))); + break; + } + + // Convert High ASCII Characters + if ($this->convert_ascii == TRUE) + { + if ($item == 'excerpt') + { + $$item = $this->convert_ascii($$item); + } + elseif ($item == 'title') + { + $$item = $this->convert_ascii($$item); + } + elseif($item == 'blog_name') + { + $$item = $this->convert_ascii($$item); + } + } + } + + // Build the Trackback data string + $charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset']; + + $data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset); + + // Send Trackback(s) + $return = TRUE; + if (count($ping_url) > 0) + { + foreach ($ping_url as $url) + { + if ($this->process($url, $data) == FALSE) + { + $return = FALSE; + } + } + } + + return $return; + } + + // -------------------------------------------------------------------- + + /** + * Receive Trackback Data + * + * This function simply validates the incoming TB data. + * It returns false on failure and true on success. + * If the data is valid it is set to the $this->data array + * so that it can be inserted into a database. + * + * @access public + * @return bool + */ + function receive() + { + foreach (array('url', 'title', 'blog_name', 'excerpt') as $val) + { + if ( ! isset($_POST[$val]) OR $_POST[$val] == '') + { + $this->set_error('The following required POST variable is missing: '.$val); + return FALSE; + } + + $this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset'])); + + if ($val != 'url' && function_exists('mb_convert_encoding')) + { + $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']); + } + + $_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]); + + if ($val == 'excerpt') + { + $_POST['excerpt'] = $this->limit_characters($_POST['excerpt']); + } + + $this->data[$val] = $_POST[$val]; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback Error Message + * + * Allows custom errors to be set. By default it + * sends the "incomplete information" error, as that's + * the most common one. + * + * @access public + * @param string + * @return void + */ + function send_error($message = 'Incomplete Information') + { + echo "\n\n1\n".$message."\n"; + exit; + } + + // -------------------------------------------------------------------- + + /** + * Send Trackback Success Message + * + * This should be called when a trackback has been + * successfully received and inserted. + * + * @access public + * @return void + */ + function send_success() + { + echo "\n\n0\n"; + exit; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a particular item + * + * @access public + * @param string + * @return string + */ + function data($item) + { + return ( ! isset($this->data[$item])) ? '' : $this->data[$item]; + } + + // -------------------------------------------------------------------- + + /** + * Process Trackback + * + * Opens a socket connection and passes the data to + * the server. Returns true on success, false on failure + * + * @access public + * @param string + * @param string + * @return bool + */ + function process($url, $data) + { + $target = parse_url($url); + + // Open the socket + if ( ! $fp = @fsockopen($target['host'], 80)) + { + $this->set_error('Invalid Connection: '.$url); + return FALSE; + } + + // Build the path + $ppath = ( ! isset($target['path'])) ? $url : $target['path']; + + $path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath; + + // Add the Trackback ID to the data string + if ($id = $this->get_id($url)) + { + $data = "tb_id=".$id."&".$data; + } + + // Transfer the data + fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" ); + fputs ($fp, "Host: " . $target['host'] . "\r\n" ); + fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" ); + fputs ($fp, "Content-length: " . strlen($data) . "\r\n" ); + fputs ($fp, "Connection: close\r\n\r\n" ); + fputs ($fp, $data); + + // Was it successful? + $this->response = ""; + + while(!feof($fp)) + { + $this->response .= fgets($fp, 128); + } + @fclose($fp); + + if ( ! eregi("0", $this->response)) + { + $message = 'An unknown error was encountered'; + + if (preg_match("/(.*?)<\/message>/is", $this->response, $match)) + { + $message = trim($match['1']); + } + + $this->set_error($message); + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Extract Trackback URLs + * + * This function lets multiple trackbacks be sent. + * It takes a string of URLs (separated by comma or + * space) and puts each URL into an array + * + * @access public + * @param string + * @return string + */ + function extract_urls($urls) + { + // Remove the pesky white space and replace with a comma. + $urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls); + + // If they use commas get rid of the doubles. + $urls = str_replace(",,", ",", $urls); + + // Remove any comma that might be at the end + if (substr($urls, -1) == ",") + { + $urls = substr($urls, 0, -1); + } + + // Break into an array via commas + $urls = preg_split('/[,]/', $urls); + + // Removes duplicates + $urls = array_unique($urls); + + array_walk($urls, array($this, 'validate_url')); + + return $urls; + } + + // -------------------------------------------------------------------- + + /** + * Validate URL + * + * Simply adds "http://" if missing + * + * @access public + * @param string + * @return string + */ + function validate_url($url) + { + $url = trim($url); + + if (substr($url, 0, 4) != "http") + { + $url = "http://".$url; + } + } + + // -------------------------------------------------------------------- + + /** + * Find the Trackback URL's ID + * + * @access public + * @param string + * @return string + */ + function get_id($url) + { + $tb_id = ""; + + if (strstr($url, '?')) + { + $tb_array = explode('/', $url); + $tb_end = $tb_array[count($tb_array)-1]; + + if ( ! is_numeric($tb_end)) + { + $tb_end = $tb_array[count($tb_array)-2]; + } + + $tb_array = explode('=', $tb_end); + $tb_id = $tb_array[count($tb_array)-1]; + } + else + { + if (ereg("/$", $url)) + { + $url = substr($url, 0, -1); + } + + $tb_array = explode('/', $url); + $tb_id = $tb_array[count($tb_array)-1]; + + if ( ! is_numeric($tb_id)) + { + $tb_id = $tb_array[count($tb_array)-2]; + } + } + + if ( ! preg_match ("/^([0-9]+)$/", $tb_id)) + { + return false; + } + else + { + return $tb_id; + } + } + + // -------------------------------------------------------------------- + + /** + * Convert Reserved XML characters to Entities + * + * @access public + * @param string + * @return string + */ + function convert_xml($str) + { + $temp = '__TEMP_AMPERSANDS__'; + + $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); + $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); + + $str = str_replace(array("&","<",">","\"", "'", "-"), + array("&", "<", ">", """, "'", "-"), + $str); + + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); + $str = preg_replace("/$temp(\w+);/","&\\1;", $str); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Character limiter + * + * Limits the string based on the character count. Will preserve complete words. + * + * @access public + * @param string + * @param integer + * @param string + * @return string + */ + function limit_characters($str, $n = 500, $end_char = '…') + { + if (strlen($str) < $n) + { + return $str; + } + + $str = preg_replace("/\s+/", ' ', preg_replace("/(\r\n|\r|\n)/", " ", $str)); + + if (strlen($str) <= $n) + { + return $str; + } + + $out = ""; + foreach (explode(' ', trim($str)) as $val) + { + $out .= $val.' '; + if (strlen($out) >= $n) + { + return trim($out).$end_char; + } + } + } + + // -------------------------------------------------------------------- + + /** + * High ASCII to Entities + * + * Converts Hight ascii text and MS Word special chars + * to character entities + * + * @access public + * @param string + * @return string + */ + function convert_ascii($str) + { + $count = 1; + $out = ''; + $temp = array(); + + for ($i = 0, $s = strlen($str); $i < $s; $i++) + { + $ordinal = ord($str[$i]); + + if ($ordinal < 128) + { + $out .= $str[$i]; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + + $out .= '&#'.$number.';'; + $count = 1; + $temp = array(); + } + } + } + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * Set error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + log_message('error', $msg); + $this->error_msg[] = $msg; + } + + // -------------------------------------------------------------------- + + /** + * Show error messages + * + * @access public + * @param string + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + +} +// END Trackback Class +?> \ No newline at end of file diff --git a/system/libraries/URI.php b/system/libraries/URI.php new file mode 100755 index 0000000..aecf051 --- /dev/null +++ b/system/libraries/URI.php @@ -0,0 +1,588 @@ +config =& load_class('Config'); + log_message('debug', "URI Class Initialized"); + } + + + // -------------------------------------------------------------------- + + /** + * Get the URI String + * + * @access private + * @return string + */ + function _fetch_uri_string() + { + if (strtoupper($this->config->item('uri_protocol')) == 'AUTO') + { + // If the URL has a question mark then it's simplest to just + // build the URI string from the zero index of the $_GET array. + // This avoids having to deal with $_SERVER variables, which + // can be unreliable in some environments + if (is_array($_GET) AND count($_GET) == 1) + { + $this->uri_string = key($_GET); + return; + } + + // Is there a PATH_INFO variable? + // Note: some servers seem to have trouble with getenv() so we'll test it two ways + $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); + if ($path != '' AND $path != '/' AND $path != "/".SELF) + { + $this->uri_string = $path; + return; + } + + // No PATH_INFO?... What about QUERY_STRING? + $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + if ($path != '' AND $path != '/') + { + $this->uri_string = $path; + return; + } + + // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists? + $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'); + if ($path != '' AND $path != '/' AND $path != "/".SELF) + { + $this->uri_string = $path; + return; + } + + // We've exhausted all our options... + $this->uri_string = ''; + } + else + { + $uri = strtoupper($this->config->item('uri_protocol')); + + if ($uri == 'REQUEST_URI') + { + $this->uri_string = $this->_parse_request_uri(); + return; + } + + $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); + } + + // If the URI contains only a slash we'll kill it + if ($this->uri_string == '/') + { + $this->uri_string = ''; + } + } + + // -------------------------------------------------------------------- + + /** + * Parse the REQUEST_URI + * + * Due to the way REQUEST_URI works it usually contains path info + * that makes it unusable as URI data. We'll trim off the unnecessary + * data, hopefully arriving at a valid URI that we can use. + * + * @access private + * @return string + */ + function _parse_request_uri() + { + if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '') + { + return ''; + } + + $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI'])); + + if ($request_uri == '' OR $request_uri == SELF) + { + return ''; + } + + $fc_path = FCPATH; + if (strpos($request_uri, '?') !== FALSE) + { + $fc_path .= '?'; + } + + $parsed_uri = explode("/", $request_uri); + + $i = 0; + foreach(explode("/", $fc_path) as $segment) + { + if (isset($parsed_uri[$i]) AND $segment == $parsed_uri[$i]) + { + $i++; + } + } + + $parsed_uri = implode("/", array_slice($parsed_uri, $i)); + + if ($parsed_uri != '') + { + $parsed_uri = '/'.$parsed_uri; + } + + return $parsed_uri; + } + + // -------------------------------------------------------------------- + + /** + * Filter segments for malicious characters + * + * @access private + * @param string + * @return string + */ + function _filter_uri($str) + { + if ($str != '' AND $this->config->item('permitted_uri_chars') != '') + { + if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str)) + { + exit('The URI you submitted has disallowed characters.'); + } + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Remove the suffix from the URL if needed + * + * @access private + * @return void + */ + function _remove_url_suffix() + { + if ($this->config->item('url_suffix') != "") + { + $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string); + } + } + + // -------------------------------------------------------------------- + + /** + * Explode the URI Segments. The individual segments will + * be stored in the $this->segments array. + * + * @access private + * @return void + */ + function _explode_segments() + { + foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) + { + // Filter segments for security + $val = trim($this->_filter_uri($val)); + + if ($val != '') + $this->segments[] = $val; + } + } + + // -------------------------------------------------------------------- + /** + * Re-index Segments + * + * This function re-indexes the $this->segment array so that it + * starts at 1 rather then 0. Doing so makes it simpler to + * use functions like $this->uri->segment(n) since there is + * a 1:1 relationship between the segment array and the actual segments. + * + * @access private + * @return void + */ + function _reindex_segments() + { + $i = 1; + + foreach ($this->segments as $val) + { + $this->segments[$i++] = $val; + } + + unset($this->segments[0]); + + $i = 1; + + foreach ($this->rsegments as $val) + { + $this->rsegments[$i++] = $val; + } + + unset($this->rsegments[0]); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment + * + * This function returns the URI segment based on the number provided. + * + * @access public + * @param integer + * @param bool + * @return string + */ + function segment($n, $no_result = FALSE) + { + return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n]; + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI "routed" Segment + * + * This function returns the re-routed URI segment (assuming routing rules are used) + * based on the number provided. If there is no routing this function returns the + * same result as $this->segment() + * + * @access public + * @param integer + * @param bool + * @return string + */ + function rsegment($n, $no_result = FALSE) + { + return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n]; + } + + // -------------------------------------------------------------------- + + /** + * Generate a key value pair from the URI string + * + * This function generates and associative array of URI data starting + * at the supplied segment. For example, if this is your URI: + * + * www.your-site.com/user/search/name/joe/location/UK/gender/male + * + * You can use this function to generate an array with this prototype: + * + * array ( + * name => joe + * location => UK + * gender => male + * ) + * + * @access public + * @param integer the starting segment number + * @param array an array of default values + * @return array + */ + function uri_to_assoc($n = 3, $default = array()) + { + return $this->_uri_to_assoc($n, $default, 'segment'); + } + /** + * Identical to above only it uses the re-routed segment array + * + */ + function ruri_to_assoc($n = 3, $default = array()) + { + return $this->_uri_to_assoc($n, $default, 'rsegment'); + } + + // -------------------------------------------------------------------- + + /** + * Generate a key value pair from the URI string or Re-routed URI string + * + * @access private + * @param integer the starting segment number + * @param array an array of default values + * @param string which array we should use + * @return array + */ + function _uri_to_assoc($n = 3, $default = array(), $which = 'segment') + { + if ($which == 'segment') + { + $total_segments = 'total_segments'; + $segment_array = 'segment_array'; + } + else + { + $total_segments = 'total_rsegments'; + $segment_array = 'rsegment_array'; + } + + if ( ! is_numeric($n)) + { + return $default; + } + + if (isset($this->keyval[$n])) + { + return $this->keyval[$n]; + } + + if ($this->$total_segments() < $n) + { + if (count($default) == 0) + { + return array(); + } + + $retval = array(); + foreach ($default as $val) + { + $retval[$val] = FALSE; + } + return $retval; + } + + $segments = array_slice($this->$segment_array(), ($n - 1)); + + $i = 0; + $lastval = ''; + $retval = array(); + foreach ($segments as $seg) + { + if ($i % 2) + { + $retval[$lastval] = $seg; + } + else + { + $retval[$seg] = FALSE; + $lastval = $seg; + } + + $i++; + } + + if (count($default) > 0) + { + foreach ($default as $val) + { + if ( ! array_key_exists($val, $retval)) + { + $retval[$val] = FALSE; + } + } + } + + // Cache the array for reuse + $this->keyval[$n] = $retval; + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Generate a URI string from an associative array + * + * + * @access public + * @param array an associative array of key/values + * @return array + */ + function assoc_to_uri($array) + { + $temp = array(); + foreach ((array)$array as $key => $val) + { + $temp[] = $key; + $temp[] = $val; + } + + return implode('/', $temp); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash + * + * @access public + * @param integer + * @param string + * @return string + */ + function slash_segment($n, $where = 'trailing') + { + return $this->_slash_segment($n, $where, 'segment'); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash + * + * @access public + * @param integer + * @param string + * @return string + */ + function slash_rsegment($n, $where = 'trailing') + { + return $this->_slash_segment($n, $where, 'rsegment'); + } + + // -------------------------------------------------------------------- + + /** + * Fetch a URI Segment and add a trailing slash - helper function + * + * @access private + * @param integer + * @param string + * @param string + * @return string + */ + function _slash_segment($n, $where = 'trailing', $which = 'segment') + { + if ($where == 'trailing') + { + $trailing = '/'; + $leading = ''; + } + elseif ($where == 'leading') + { + $leading = '/'; + $trailing = ''; + } + else + { + $leading = '/'; + $trailing = '/'; + } + return $leading.$this->$which($n).$trailing; + } + + // -------------------------------------------------------------------- + + /** + * Segment Array + * + * @access public + * @return array + */ + function segment_array() + { + return $this->segments; + } + + // -------------------------------------------------------------------- + + /** + * Routed Segment Array + * + * @access public + * @return array + */ + function rsegment_array() + { + return $this->rsegments; + } + + // -------------------------------------------------------------------- + + /** + * Total number of segments + * + * @access public + * @return integer + */ + function total_segments() + { + return count($this->segments); + } + + // -------------------------------------------------------------------- + + /** + * Total number of routed segments + * + * @access public + * @return integer + */ + function total_rsegments() + { + return count($this->rsegments); + } + + // -------------------------------------------------------------------- + + /** + * Fetch the entire URI string + * + * @access public + * @return string + */ + function uri_string() + { + return $this->uri_string; + } + + + // -------------------------------------------------------------------- + + /** + * Fetch the entire Re-routed URI string + * + * @access public + * @return string + */ + function ruri_string() + { + return '/'.implode('/', $this->rsegment_array()).'/'; + } + +} +// END URI Class +?> \ No newline at end of file diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php new file mode 100755 index 0000000..33a8f31 --- /dev/null +++ b/system/libraries/Unit_test.php @@ -0,0 +1,331 @@ +active == FALSE) + return FALSE; + + if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE)) + { + $expected = str_replace('is_float', 'is_double', $expected); + $result = ($expected($test)) ? TRUE : FALSE; + $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected)); + } + else + { + if ($this->strict == TRUE) + $result = ($test === $expected) ? TRUE : FALSE; + else + $result = ($test == $expected) ? TRUE : FALSE; + + $extype = gettype($expected); + } + + $back = $this->_backtrace(); + + $report[] = array ( + 'test_name' => $test_name, + 'test_datatype' => gettype($test), + 'res_datatype' => $extype, + 'result' => ($result === TRUE) ? 'passed' : 'failed', + 'file' => $back['file'], + 'line' => $back['line'] + ); + + $this->results[] = $report; + + return($this->report($this->result($report))); + } + + // -------------------------------------------------------------------- + + /** + * Generate a report + * + * Displays a table with the test data + * + * @access public + * @return string + */ + function report($result = array()) + { + if (count($result) == 0) + { + $result = $this->result(); + } + + $this->_parse_template(); + + $r = ''; + foreach ($result as $res) + { + $table = ''; + + foreach ($res as $key => $val) + { + $temp = $this->_template_rows; + $temp = str_replace('{item}', $key, $temp); + $temp = str_replace('{result}', $val, $temp); + $table .= $temp; + } + + $r .= str_replace('{rows}', $table, $this->_template); + } + + return $r; + } + + // -------------------------------------------------------------------- + + /** + * Use strict comparison + * + * Causes the evaluation to use === rather then == + * + * @access public + * @param bool + * @return null + */ + function use_strict($state = TRUE) + { + $this->strict = ($state == FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Make Unit testing active + * + * Enables/disables unit testing + * + * @access public + * @param bool + * @return null + */ + function active($state = TRUE) + { + $this->active = ($state == FALSE) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Result Array + * + * Returns the raw result data + * + * @access public + * @return array + */ + function result($results = array()) + { + $CI =& get_instance(); + $CI->load->language('unit_test'); + + if (count($results) == 0) + { + $results = $this->results; + } + + $retval = array(); + foreach ($results as $result) + { + $temp = array(); + foreach ($result as $key => $val) + { + if (is_array($val)) + { + foreach ($val as $k => $v) + { + if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v)))) + { + $v = $line; + } + $temp[$CI->lang->line('ut_'.$k)] = $v; + } + } + else + { + if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val)))) + { + $val = $line; + } + $temp[$CI->lang->line('ut_'.$key)] = $val; + } + } + + $retval[] = $temp; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Set the template + * + * This lets us set the template to be used to display results + * + * @access public + * @param string + * @return void + */ + function set_template($template) + { + $this->_template = $template; + } + + // -------------------------------------------------------------------- + + /** + * Generate a backtrace + * + * This lets us show file names and line numbers + * + * @access private + * @return array + */ + function _backtrace() + { + if (function_exists('debug_backtrace')) + { + $back = debug_backtrace(); + + $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file']; + $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line']; + + return array('file' => $file, 'line' => $line); + } + return array('file' => 'Unknown', 'line' => 'Unknown'); + } + + // -------------------------------------------------------------------- + + /** + * Get Default Template + * + * @access private + * @return string + */ + function _default_template() + { + $this->_template = ' +
    + + {rows} +
    '; + + $this->_template_rows = ' + + {item} + {result} + + '; + } + + // -------------------------------------------------------------------- + + /** + * Parse Template + * + * Harvests the data within the template {pseudo-variables} + * + * @access private + * @return void + */ + function _parse_template() + { + if ( ! is_null($this->_template_rows)) + { + return; + } + + if (is_null($this->_template)) + { + $this->_default_template(); + return; + } + + if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match)) + { + $this->_default_template(); + return; + } + + $this->_template_rows = $match['1']; + $this->_template = str_replace($match['0'], '{rows}', $this->_template); + } + +} +// END Unit_test Class + +/** + * Helper functions to test boolean true/false + * + * + * @access private + * @return bool + */ +function is_true($test) +{ + return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE; +} +function is_false($test) +{ + return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE; +} + +?> \ No newline at end of file diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php new file mode 100755 index 0000000..2a3f53d --- /dev/null +++ b/system/libraries/Upload.php @@ -0,0 +1,838 @@ + 0) + { + $this->initialize($props); + } + + log_message('debug', "Upload Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + $defaults = array( + 'max_size' => 0, + 'max_width' => 0, + 'max_height' => 0, + 'allowed_types' => "", + 'file_temp' => "", + 'file_name' => "", + 'orig_name' => "", + 'file_type' => "", + 'file_size' => "", + 'file_ext' => "", + 'upload_path' => "", + 'overwrite' => FALSE, + 'encrypt_name' => FALSE, + 'is_image' => FALSE, + 'image_width' => '', + 'image_height' => '', + 'image_type' => '', + 'image_size_str' => '', + 'error_msg' => array(), + 'mimes' => array(), + 'remove_spaces' => TRUE, + 'xss_clean' => FALSE, + 'temp_prefix' => "temp_file_" + ); + + + foreach ($defaults as $key => $val) + { + if (isset($config[$key])) + { + $method = 'set_'.$key; + if (method_exists($this, $method)) + { + $this->$method($config[$key]); + } + else + { + $this->$key = $config[$key]; + } + } + else + { + $this->$key = $val; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Perform the file upload + * + * @access public + * @return bool + */ + function do_upload($field = 'userfile') + { + // Is $_FILES[$field] set? If not, no reason to continue. + if ( ! isset($_FILES[$field])) + { + $this->set_error('upload_no_file_selected'); + return FALSE; + } + + // Is the upload path valid? + if ( ! $this->validate_upload_path()) + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + // Was the file able to be uploaded? If not, determine the reason why. + if ( ! is_uploaded_file($_FILES[$field]['tmp_name'])) + { + $error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error']; + + switch($error) + { + case 1: // UPLOAD_ERR_INI_SIZE + $this->set_error('upload_file_exceeds_limit'); + break; + case 2: // UPLOAD_ERR_FORM_SIZE + $this->set_error('upload_file_exceeds_form_limit'); + break; + case 3: // UPLOAD_ERR_PARTIAL + $this->set_error('upload_file_partial'); + break; + case 4: // UPLOAD_ERR_NO_FILE + $this->set_error('upload_no_file_selected'); + break; + case 6: // UPLOAD_ERR_NO_TMP_DIR + $this->set_error('upload_no_temp_directory'); + break; + case 7: // UPLOAD_ERR_CANT_WRITE + $this->set_error('upload_unable_to_write_file'); + break; + case 8: // UPLOAD_ERR_EXTENSION + $this->set_error('upload_stopped_by_extension'); + break; + default : $this->set_error('upload_no_file_selected'); + break; + } + + return FALSE; + } + + // Set the uploaded data as class variables + $this->file_temp = $_FILES[$field]['tmp_name']; + $this->file_name = $_FILES[$field]['name']; + $this->file_size = $_FILES[$field]['size']; + $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); + $this->file_type = strtolower($this->file_type); + $this->file_ext = $this->get_extension($_FILES[$field]['name']); + + // Convert the file size to kilobytes + if ($this->file_size > 0) + { + $this->file_size = round($this->file_size/1024, 2); + } + + // Is the file type allowed to be uploaded? + if ( ! $this->is_allowed_filetype()) + { + $this->set_error('upload_invalid_filetype'); + return FALSE; + } + + // Is the file size within the allowed maximum? + if ( ! $this->is_allowed_filesize()) + { + $this->set_error('upload_invalid_filesize'); + return FALSE; + } + + // Are the image dimensions within the allowed size? + // Note: This can fail if the server has an open_basdir restriction. + if ( ! $this->is_allowed_dimensions()) + { + $this->set_error('upload_invalid_dimensions'); + return FALSE; + } + + // Sanitize the file name for security + $this->file_name = $this->clean_file_name($this->file_name); + + // Remove white spaces in the name + if ($this->remove_spaces == TRUE) + { + $this->file_name = preg_replace("/\s+/", "_", $this->file_name); + } + + /* + * Validate the file name + * This function appends an number onto the end of + * the file if one with the same name already exists. + * If it returns false there was a problem. + */ + $this->orig_name = $this->file_name; + + if ($this->overwrite == FALSE) + { + $this->file_name = $this->set_filename($this->upload_path, $this->file_name); + + if ($this->file_name === FALSE) + { + return FALSE; + } + } + + /* + * Move the file to the final destination + * To deal with different server configurations + * we'll attempt to use copy() first. If that fails + * we'll use move_uploaded_file(). One of the two should + * reliably work in most environments + */ + if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name)) + { + if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) + { + $this->set_error('upload_destination_error'); + return FALSE; + } + } + + /* + * Run the file through the XSS hacking filter + * This helps prevent malicious code from being + * embedded within a file. Scripts can easily + * be disguised as images or other file types. + */ + if ($this->xss_clean == TRUE) + { + $this->do_xss_clean(); + } + + /* + * Set the finalized image dimensions + * This sets the image width/height (assuming the + * file was an image). We use this information + * in the "data" function. + */ + $this->set_image_properties($this->upload_path.$this->file_name); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Finalized Data Array + * + * Returns an associative array containing all of the information + * related to the upload, allowing the developer easy access in one array. + * + * @access public + * @return array + */ + function data() + { + return array ( + 'file_name' => $this->file_name, + 'file_type' => $this->file_type, + 'file_path' => $this->upload_path, + 'full_path' => $this->upload_path.$this->file_name, + 'raw_name' => str_replace($this->file_ext, '', $this->file_name), + 'orig_name' => $this->orig_name, + 'file_ext' => $this->file_ext, + 'file_size' => $this->file_size, + 'is_image' => $this->is_image(), + 'image_width' => $this->image_width, + 'image_height' => $this->image_height, + 'image_type' => $this->image_type, + 'image_size_str' => $this->image_size_str, + ); + } + + // -------------------------------------------------------------------- + + /** + * Set Upload Path + * + * @access public + * @param string + * @return void + */ + function set_upload_path($path) + { + $this->upload_path = $path; + } + + // -------------------------------------------------------------------- + + /** + * Set the file name + * + * This function takes a filename/path as input and looks for the + * existence of a file with the same name. If found, it will append a + * number to the end of the filename to avoid overwriting a pre-existing file. + * + * @access public + * @param string + * @param string + * @return string + */ + function set_filename($path, $filename) + { + if ($this->encrypt_name == TRUE) + { + mt_srand(); + $filename = md5(uniqid(mt_rand())).$this->file_ext; + } + + if ( ! file_exists($path.$filename)) + { + return $filename; + } + + $filename = str_replace($this->file_ext, '', $filename); + + $new_filename = ''; + for ($i = 1; $i < 100; $i++) + { + if ( ! file_exists($path.$filename.$i.$this->file_ext)) + { + $new_filename = $filename.$i.$this->file_ext; + break; + } + } + + if ($new_filename == '') + { + $this->set_error('upload_bad_filename'); + return FALSE; + } + else + { + return $new_filename; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum File Size + * + * @access public + * @param integer + * @return void + */ + function set_max_filesize($n) + { + $this->max_size = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum Image Width + * + * @access public + * @param integer + * @return void + */ + function set_max_width($n) + { + $this->max_width = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Maximum Image Height + * + * @access public + * @param integer + * @return void + */ + function set_max_height($n) + { + $this->max_height = ( ! eregi("^[[:digit:]]+$", $n)) ? 0 : $n; + } + + // -------------------------------------------------------------------- + + /** + * Set Allowed File Types + * + * @access public + * @param string + * @return void + */ + function set_allowed_types($types) + { + $this->allowed_types = explode('|', $types); + } + + // -------------------------------------------------------------------- + + /** + * Set Image Properties + * + * Uses GD to determine the width/height/type of image + * + * @access public + * @param string + * @return void + */ + function set_image_properties($path = '') + { + if ( ! $this->is_image()) + { + return; + } + + if (function_exists('getimagesize')) + { + if (FALSE !== ($D = @getimagesize($path))) + { + $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); + + $this->image_width = $D['0']; + $this->image_height = $D['1']; + $this->image_type = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']]; + $this->image_size_str = $D['3']; // string containing height and width + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set XSS Clean + * + * Enables the XSS flag so that the file that was uploaded + * will be run through the XSS filter. + * + * @access public + * @param bool + * @return void + */ + function set_xss_clean($flag = FALSE) + { + $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Validate the image + * + * @access public + * @return bool + */ + function is_image() + { + // IE will sometimes return odd mime-types during upload, so here we just standardize all + // jpegs or pngs to the same file type. + + $png_mimes = array('image/x-png'); + $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg'); + + if (in_array($this->file_type, $png_mimes)) + { + $this->file_type = 'image/png'; + } + + if (in_array($this->file_type, $jpeg_mimes)) + { + $this->file_type = 'image/jpeg'; + } + + $img_mimes = array( + 'image/gif', + 'image/jpeg', + 'image/png', + ); + + return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Verify that the filetype is allowed + * + * @access public + * @return bool + */ + function is_allowed_filetype() + { + if (count($this->allowed_types) == 0 || ! is_array($this->allowed_types)) + { + $this->set_error('upload_no_file_types'); + return FALSE; + } + + foreach ($this->allowed_types as $val) + { + $mime = $this->mimes_types(strtolower($val)); + + if (is_array($mime)) + { + if (in_array($this->file_type, $mime, TRUE)) + { + return TRUE; + } + } + else + { + if ($mime == $this->file_type) + { + return TRUE; + } + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Verify that the file is within the allowed size + * + * @access public + * @return bool + */ + function is_allowed_filesize() + { + if ($this->max_size != 0 AND $this->file_size > $this->max_size) + { + return FALSE; + } + else + { + return TRUE; + } + } + + // -------------------------------------------------------------------- + + /** + * Verify that the image is within the allowed width/height + * + * @access public + * @return bool + */ + function is_allowed_dimensions() + { + if ( ! $this->is_image()) + { + return TRUE; + } + + if (function_exists('getimagesize')) + { + $D = @getimagesize($this->file_temp); + + if ($this->max_width > 0 AND $D['0'] > $this->max_width) + { + return FALSE; + } + + if ($this->max_height > 0 AND $D['1'] > $this->max_height) + { + return FALSE; + } + + return TRUE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Validate Upload Path + * + * Verifies that it is a valid upload path with proper permissions. + * + * + * @access public + * @return bool + */ + function validate_upload_path() + { + if ($this->upload_path == '') + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE) + { + $this->upload_path = str_replace("\\", "/", realpath($this->upload_path)); + } + + if ( ! @is_dir($this->upload_path)) + { + $this->set_error('upload_no_filepath'); + return FALSE; + } + + if ( ! is_really_writable($this->upload_path)) + { + $this->set_error('upload_not_writable'); + return FALSE; + } + + $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path); + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Extract the file extension + * + * @access public + * @param string + * @return string + */ + function get_extension($filename) + { + $x = explode('.', $filename); + return '.'.end($x); + } + + // -------------------------------------------------------------------- + + /** + * Clean the file name for security + * + * @access public + * @param string + * @return string + */ + function clean_file_name($filename) + { + $bad = array( + "", + "'", + "<", + ">", + '"', + '&', + '$', + '=', + ';', + '?', + '/', + "%20", + "%22", + "%3c", // < + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; + "%3d" // = + ); + + foreach ($bad as $val) + { + $filename = str_replace($val, '', $filename); + } + + return stripslashes($filename); + } + + // -------------------------------------------------------------------- + + /** + * Runs the file through the XSS clean function + * + * This prevents people from embedding malicious code in their files. + * I'm not sure that it won't negatively affect certain files in unexpected ways, + * but so far I haven't found that it causes trouble. + * + * @access public + * @return void + */ + function do_xss_clean() + { + $file = $this->upload_path.$this->file_name; + + if (filesize($file) == 0) + { + return FALSE; + } + + if (($data = @file_get_contents($file)) === FALSE) + { + return FALSE; + } + + if ( ! $fp = @fopen($file, 'r+b')) + { + return FALSE; + } + + $CI =& get_instance(); + $data = $CI->input->xss_clean($data); + + flock($fp, LOCK_EX); + fwrite($fp, $data); + flock($fp, LOCK_UN); + fclose($fp); + } + + // -------------------------------------------------------------------- + + /** + * Set an error message + * + * @access public + * @param string + * @return void + */ + function set_error($msg) + { + $CI =& get_instance(); + $CI->lang->load('upload'); + + if (is_array($msg)) + { + foreach ($msg as $val) + { + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + else + { + $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg); + $this->error_msg[] = $msg; + log_message('error', $msg); + } + } + + // -------------------------------------------------------------------- + + /** + * Display the error message + * + * @access public + * @param string + * @param string + * @return string + */ + function display_errors($open = '

    ', $close = '

    ') + { + $str = ''; + foreach ($this->error_msg as $val) + { + $str .= $open.$val.$close; + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * List of Mime Types + * + * This is a list of mime types. We use it to validate + * the "allowed types" set by the developer + * + * @access public + * @param string + * @return string + */ + function mimes_types($mime) + { + if (count($this->mimes) == 0) + { + if (@include(APPPATH.'config/mimes'.EXT)) + { + $this->mimes = $mimes; + unset($mimes); + } + } + + return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime]; + } + +} +// END Upload Class +?> \ No newline at end of file diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php new file mode 100755 index 0000000..ff6d4a9 --- /dev/null +++ b/system/libraries/User_agent.php @@ -0,0 +1,500 @@ +agent = trim($_SERVER['HTTP_USER_AGENT']); + } + + if ( ! is_null($this->agent)) + { + if ($this->_load_agent_file()) + { + $this->_compile_data(); + } + } + + log_message('debug', "User Agent Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Compile the User Agent Data + * + * @access private + * @return bool + */ + function _load_agent_file() + { + if ( ! @include(APPPATH.'config/user_agents'.EXT)) + { + return FALSE; + } + + $return = FALSE; + + if (isset($platforms)) + { + $this->platforms = $platforms; + unset($platforms); + $return = TRUE; + } + + if (isset($browsers)) + { + $this->browsers = $browsers; + unset($browsers); + $return = TRUE; + } + + if (isset($mobiles)) + { + $this->mobiles = $mobiles; + unset($mobiles); + $return = TRUE; + } + + if (isset($robots)) + { + $this->robots = $robots; + unset($robots); + $return = TRUE; + } + + return $return; + } + + // -------------------------------------------------------------------- + + /** + * Compile the User Agent Data + * + * @access private + * @return bool + */ + function _compile_data() + { + $this->_set_platform(); + + foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function) + { + if ($this->$function() === TRUE) + { + break; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set the Platform + * + * @access private + * @return mixed + */ + function _set_platform() + { + if (is_array($this->platforms) AND count($this->platforms) > 0) + { + foreach ($this->platforms as $key => $val) + { + if (preg_match("|".preg_quote($key)."|i", $this->agent)) + { + $this->platform = $val; + return TRUE; + } + } + } + $this->platform = 'Unknown Platform'; + } + + // -------------------------------------------------------------------- + + /** + * Set the Browser + * + * @access private + * @return bool + */ + function _set_browser() + { + if (is_array($this->browsers) AND count($this->browsers) > 0) + { + foreach ($this->browsers as $key => $val) + { + if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match)) + { + $this->is_browser = TRUE; + $this->version = $match[1]; + $this->browser = $val; + $this->_set_mobile(); + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the Robot + * + * @access private + * @return bool + */ + function _set_robot() + { + if (is_array($this->robots) AND count($this->robots) > 0) + { + foreach ($this->robots as $key => $val) + { + if (preg_match("|".preg_quote($key)."|i", $this->agent)) + { + $this->is_robot = TRUE; + $this->robot = $val; + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the Mobile Device + * + * @access private + * @return bool + */ + function _set_mobile() + { + if (is_array($this->mobiles) AND count($this->mobiles) > 0) + { + foreach ($this->mobiles as $key => $val) + { + if (FALSE !== (strpos(strtolower($this->agent), $key))) + { + $this->is_mobile = TRUE; + $this->mobile = $val; + return TRUE; + } + } + } + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Set the accepted languages + * + * @access private + * @return void + */ + function _set_languages() + { + if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '') + { + $languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))); + + $this->languages = explode(',', $languages); + } + + if (count($this->languages) == 0) + { + $this->languages = array('Undefined'); + } + } + + // -------------------------------------------------------------------- + + /** + * Set the accepted character sets + * + * @access private + * @return void + */ + function _set_charsets() + { + if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '') + { + $charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))); + + $this->charsets = explode(',', $charsets); + } + + if (count($this->charsets) == 0) + { + $this->charsets = array('Undefined'); + } + } + + // -------------------------------------------------------------------- + + /** + * Is Browser + * + * @access public + * @return bool + */ + function is_browser() + { + return $this->is_browser; + } + + // -------------------------------------------------------------------- + + /** + * Is Robot + * + * @access public + * @return bool + */ + function is_robot() + { + return $this->is_robot; + } + + // -------------------------------------------------------------------- + + /** + * Is Mobile + * + * @access public + * @return bool + */ + function is_mobile() + { + return $this->is_mobile; + } + + // -------------------------------------------------------------------- + + /** + * Is this a referral from another site? + * + * @access public + * @return bool + */ + function is_referral() + { + return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Agent String + * + * @access public + * @return string + */ + function agent_string() + { + return $this->agent; + } + + // -------------------------------------------------------------------- + + /** + * Get Platform + * + * @access public + * @return string + */ + function platform() + { + return $this->platform; + } + + // -------------------------------------------------------------------- + + /** + * Get Browser Name + * + * @access public + * @return string + */ + function browser() + { + return $this->browser; + } + + // -------------------------------------------------------------------- + + /** + * Get the Browser Version + * + * @access public + * @return string + */ + function version() + { + return $this->version; + } + + // -------------------------------------------------------------------- + + /** + * Get The Robot Name + * + * @access public + * @return string + */ + function robot() + { + return $this->robot; + } + // -------------------------------------------------------------------- + + /** + * Get the Mobile Device + * + * @access public + * @return string + */ + function mobile() + { + return $this->mobile; + } + + // -------------------------------------------------------------------- + + /** + * Get the referrer + * + * @access public + * @return bool + */ + function referrer() + { + return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']); + } + + // -------------------------------------------------------------------- + + /** + * Get the accepted languages + * + * @access public + * @return array + */ + function languages() + { + if (count($this->languages) == 0) + { + $this->_set_languages(); + } + + return $this->languages; + } + + // -------------------------------------------------------------------- + + /** + * Get the accepted Character Sets + * + * @access public + * @return array + */ + function charsets() + { + if (count($this->charsets) == 0) + { + $this->_set_charsets(); + } + + return $this->charsets; + } + + // -------------------------------------------------------------------- + + /** + * Test for a particular language + * + * @access public + * @return bool + */ + function accept_lang($lang = 'en') + { + return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Test for a particular character set + * + * @access public + * @return bool + */ + function accept_charset($charset = 'utf-8') + { + return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE; + } + + +} + +?> \ No newline at end of file diff --git a/system/libraries/Validation.php b/system/libraries/Validation.php new file mode 100755 index 0000000..d0714d0 --- /dev/null +++ b/system/libraries/Validation.php @@ -0,0 +1,781 @@ +'; + var $_error_suffix = '

    '; + + + + /** + * Constructor + * + */ + function CI_Validation() + { + $this->CI =& get_instance(); + log_message('debug', "Validation Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Set Fields + * + * This function takes an array of field names as input + * and generates class variables with the same name, which will + * either be blank or contain the $_POST value corresponding to it + * + * @access public + * @param string + * @param string + * @return void + */ + function set_fields($data = '', $field = '') + { + if ($data == '') + { + if (count($this->_fields) == 0) + { + return FALSE; + } + } + else + { + if ( ! is_array($data)) + { + $data = array($data => $field); + } + + if (count($data) > 0) + { + $this->_fields = $data; + } + } + + foreach($this->_fields as $key => $val) + { + $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]); + + $error = $key.'_error'; + if ( ! isset($this->$error)) + { + $this->$error = ''; + } + } + } + + // -------------------------------------------------------------------- + + /** + * Set Rules + * + * This function takes an array of field names and validation + * rules as input ad simply stores is for use later. + * + * @access public + * @param mixed + * @param string + * @return void + */ + function set_rules($data, $rules = '') + { + if ( ! is_array($data)) + { + if ($rules == '') + return; + + $data[$data] = $rules; + } + + foreach ($data as $key => $val) + { + $this->_rules[$key] = $val; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Error Message + * + * Lets users set their own error messages on the fly. Note: The key + * name has to match the function name that it corresponds to. + * + * @access public + * @param string + * @param string + * @return string + */ + function set_message($lang, $val = '') + { + if ( ! is_array($lang)) + { + $lang = array($lang => $val); + } + + $this->_error_messages = array_merge($this->_error_messages, $lang); + } + + // -------------------------------------------------------------------- + + /** + * Set The Error Delimiter + * + * Permits a prefix/suffix to be added to each error message + * + * @access public + * @param string + * @param string + * @return void + */ + function set_error_delimiters($prefix = '

    ', $suffix = '

    ') + { + $this->_error_prefix = $prefix; + $this->_error_suffix = $suffix; + } + + // -------------------------------------------------------------------- + + /** + * Run the Validator + * + * This function does all the work. + * + * @access public + * @return bool + */ + function run() + { + // Do we even have any data to process? Mm? + if (count($_POST) == 0 OR count($this->_rules) == 0) + { + return FALSE; + } + + // Load the language file containing error messages + $this->CI->lang->load('validation'); + + // Cycle through the rules and test for errors + foreach ($this->_rules as $field => $rules) + { + //Explode out the rules! + $ex = explode('|', $rules); + + // Is the field required? If not, if the field is blank we'll move on to the next test + if ( ! in_array('required', $ex, TRUE)) + { + if ( ! isset($_POST[$field]) OR $_POST[$field] == '') + { + continue; + } + } + + /* + * Are we dealing with an "isset" rule? + * + * Before going further, we'll see if one of the rules + * is to check whether the item is set (typically this + * applies only to checkboxes). If so, we'll + * test for it here since there's not reason to go + * further + */ + if ( ! isset($_POST[$field])) + { + if (in_array('isset', $ex, TRUE) OR in_array('required', $ex)) + { + if ( ! isset($this->_error_messages['isset'])) + { + if (FALSE === ($line = $this->CI->lang->line('isset'))) + { + $line = 'The field was not set'; + } + } + else + { + $line = $this->_error_messages['isset']; + } + + // Build the error message + $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; + $message = sprintf($line, $mfield); + + // Set the error variable. Example: $this->username_error + $error = $field.'_error'; + $this->$error = $this->_error_prefix.$message.$this->_error_suffix; + $this->_error_array[] = $message; + } + + continue; + } + + /* + * Set the current field + * + * The various prepping functions need to know the + * current field name so they can do this: + * + * $_POST[$this->_current_field] == 'bla bla'; + */ + $this->_current_field = $field; + + // Cycle through the rules! + foreach ($ex As $rule) + { + // Is the rule a callback? + $callback = FALSE; + if (substr($rule, 0, 9) == 'callback_') + { + $rule = substr($rule, 9); + $callback = TRUE; + } + + // Strip the parameter (if exists) from the rule + // Rules can contain a parameter: max_length[5] + $param = FALSE; + if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) + { + $rule = $match[1]; + $param = $match[2]; + } + + // Call the function that corresponds to the rule + if ($callback === TRUE) + { + if ( ! method_exists($this->CI, $rule)) + { + continue; + } + + $result = $this->CI->$rule($_POST[$field], $param); + + // If the field isn't required and we just processed a callback we'll move on... + if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE) + { + continue 2; + } + + } + else + { + if ( ! method_exists($this, $rule)) + { + /* + * Run the native PHP function if called for + * + * If our own wrapper function doesn't exist we see + * if a native PHP function does. Users can use + * any native PHP function call that has one param. + */ + if (function_exists($rule)) + { + $_POST[$field] = $rule($_POST[$field]); + $this->$field = $_POST[$field]; + } + + continue; + } + + $result = $this->$rule($_POST[$field], $param); + } + + // Did the rule test negatively? If so, grab the error. + if ($result === FALSE) + { + if ( ! isset($this->_error_messages[$rule])) + { + if (FALSE === ($line = $this->CI->lang->line($rule))) + { + $line = 'Unable to access an error message corresponding to your field name.'; + } + } + else + { + $line = $this->_error_messages[$rule]; + } + + // Build the error message + $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; + $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param]; + $message = sprintf($line, $mfield, $mparam); + + // Set the error variable. Example: $this->username_error + $error = $field.'_error'; + $this->$error = $this->_error_prefix.$message.$this->_error_suffix; + + // Add the error to the error array + $this->_error_array[] = $message; + continue 2; + } + } + + } + + $total_errors = count($this->_error_array); + + /* + * Recompile the class variables + * + * If any prepping functions were called the $_POST data + * might now be different then the corresponding class + * variables so we'll set them anew. + */ + if ($total_errors > 0) + { + $this->_safe_form_data = TRUE; + } + + $this->set_fields(); + + // Did we end up with any errors? + if ($total_errors == 0) + { + return TRUE; + } + + // Generate the error string + foreach ($this->_error_array as $val) + { + $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n"; + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Required + * + * @access public + * @param string + * @return bool + */ + function required($str) + { + if ( ! is_array($str)) + { + return (trim($str) == '') ? FALSE : TRUE; + } + else + { + return ( ! empty($str)); + } + } + + // -------------------------------------------------------------------- + + /** + * Match one field to another + * + * @access public + * @param string + * @return bool + */ + function matches($str, $field) + { + if ( ! isset($_POST[$field])) + { + return FALSE; + } + + return ($str !== $_POST[$field]) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Minimum Length + * + * @access public + * @param string + * @return bool + */ + function min_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) < $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Max Length + * + * @access public + * @param string + * @return bool + */ + function max_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) > $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Exact Length + * + * @access public + * @param string + * @return bool + */ + function exact_length($str, $val) + { + if (preg_match("/[^0-9]/", $val)) + { + return FALSE; + } + + return (strlen($str) != $val) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Valid Email + * + * @access public + * @param string + * @return bool + */ + function valid_email($str) + { + return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Validate IP Address + * + * @access public + * @param string + * @return string + */ + function valid_ip($ip) + { + return $this->CI->input->valid_ip($ip); + } + + // -------------------------------------------------------------------- + + /** + * Alpha + * + * @access public + * @param string + * @return bool + */ + function alpha($str) + { + return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Alpha-numeric + * + * @access public + * @param string + * @return bool + */ + function alpha_numeric($str) + { + return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Alpha-numeric with underscores and dashes + * + * @access public + * @param string + * @return bool + */ + function alpha_dash($str) + { + return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Numeric + * + * @access public + * @param string + * @return bool + */ + function numeric($str) + { + return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str); + + } + + // -------------------------------------------------------------------- + + /** + * Is Numeric + * + * @access public + * @param string + * @return bool + */ + function is_numeric($str) + { + return ( ! is_numeric($str)) ? FALSE : TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Integer + * + * @access public + * @param string + * @return bool + */ + function integer($str) + { + return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str); + } + + // -------------------------------------------------------------------- + + /** + * Valid Base64 + * + * Tests a string for characters outside of the Base64 alphabet + * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045 + * + * @access public + * @param string + * @return bool + */ + function valid_base64($str) + { + return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str); + } + + // -------------------------------------------------------------------- + + /** + * Set Select + * + * Enables pull-down lists to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_select($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' selected="selected"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Radio + * + * Enables radio buttons to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_radio($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' checked="checked"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Set Checkbox + * + * Enables checkboxes to be set to the value the user + * selected in the event of an error + * + * @access public + * @param string + * @param string + * @return string + */ + function set_checkbox($field = '', $value = '') + { + if ($field == '' OR $value == '' OR ! isset($_POST[$field])) + { + return ''; + } + + if ($_POST[$field] == $value) + { + return ' checked="checked"'; + } + } + + // -------------------------------------------------------------------- + + /** + * Prep data for form + * + * This function allows HTML to be safely shown in a form. + * Special characters are converted. + * + * @access public + * @param string + * @return string + */ + function prep_for_form($data = '') + { + if (is_array($data)) + { + foreach ($data as $key => $val) + { + $data[$key] = $this->prep_for_form($val); + } + } + + if ($this->_safe_form_data == FALSE OR $data == '') + { + return $data; + } + + return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data)); + } + + // -------------------------------------------------------------------- + + /** + * Prep URL + * + * @access public + * @param string + * @return string + */ + function prep_url($str = '') + { + if ($str == 'http://' OR $str == '') + { + $_POST[$this->_current_field] = ''; + return; + } + + if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') + { + $str = 'http://'.$str; + } + + $_POST[$this->_current_field] = $str; + } + + // -------------------------------------------------------------------- + + /** + * Strip Image Tags + * + * @access public + * @param string + * @return string + */ + function strip_image_tags($str) + { + $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str); + } + + // -------------------------------------------------------------------- + + /** + * XSS Clean + * + * @access public + * @param string + * @return string + */ + function xss_clean($str) + { + $_POST[$this->_current_field] = $this->CI->input->xss_clean($str); + } + + // -------------------------------------------------------------------- + + /** + * Convert PHP tags to entities + * + * @access public + * @param string + * @return string + */ + function encode_php_tags($str) + { + $_POST[$this->_current_field] = str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $str); + } + +} +// END Validation Class +?> \ No newline at end of file diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php new file mode 100755 index 0000000..f90ee56 --- /dev/null +++ b/system/libraries/Xmlrpc.php @@ -0,0 +1,1419 @@ +xmlrpcName = $this->xmlrpcName; + $this->xmlrpc_backslash = chr(92).chr(92); + + // Types for info sent back and forth + $this->xmlrpcTypes = array( + $this->xmlrpcI4 => '1', + $this->xmlrpcInt => '1', + $this->xmlrpcBoolean => '1', + $this->xmlrpcString => '1', + $this->xmlrpcDouble => '1', + $this->xmlrpcDateTime => '1', + $this->xmlrpcBase64 => '1', + $this->xmlrpcArray => '2', + $this->xmlrpcStruct => '3' + ); + + // Array of Valid Parents for Various XML-RPC elements + $this->valid_parents = array('BOOLEAN' => array('VALUE'), + 'I4' => array('VALUE'), + 'INT' => array('VALUE'), + 'STRING' => array('VALUE'), + 'DOUBLE' => array('VALUE'), + 'DATETIME.ISO8601' => array('VALUE'), + 'BASE64' => array('VALUE'), + 'ARRAY' => array('VALUE'), + 'STRUCT' => array('VALUE'), + 'PARAM' => array('PARAMS'), + 'METHODNAME' => array('METHODCALL'), + 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'), + 'MEMBER' => array('STRUCT'), + 'NAME' => array('MEMBER'), + 'DATA' => array('ARRAY'), + 'FAULT' => array('METHODRESPONSE'), + 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT') + ); + + + // XML-RPC Responses + $this->xmlrpcerr['unknown_method'] = '1'; + $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server'; + $this->xmlrpcerr['invalid_return'] = '2'; + $this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.'; + $this->xmlrpcerr['incorrect_params'] = '3'; + $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method'; + $this->xmlrpcerr['introspect_unknown'] = '4'; + $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown"; + $this->xmlrpcerr['http_error'] = '5'; + $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server."; + $this->xmlrpcerr['no_data'] = '6'; + $this->xmlrpcstr['no_data'] ='No data received from server.'; + + $this->initialize($config); + + log_message('debug', "XML-RPC Class Initialized"); + } + + + //------------------------------------- + // Initialize Prefs + //------------------------------------- + + function initialize($config = array()) + { + if (sizeof($config) > 0) + { + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + } + // END + + //------------------------------------- + // Take URL and parse it + //------------------------------------- + + function server($url, $port=80) + { + if (substr($url, 0, 4) != "http") + { + $url = "http://".$url; + } + + $parts = parse_url($url); + + $path = (!isset($parts['path'])) ? '/' : $parts['path']; + + if (isset($parts['query']) && $parts['query'] != '') + { + $path .= '?'.$parts['query']; + } + + $this->client = new XML_RPC_Client($path, $parts['host'], $port); + } + // END + + //------------------------------------- + // Set Timeout + //------------------------------------- + + function timeout($seconds=5) + { + if ( ! is_null($this->client) && is_int($seconds)) + { + $this->client->timeout = $seconds; + } + } + // END + + //------------------------------------- + // Set Methods + //------------------------------------- + + function method($function) + { + $this->method = $function; + } + // END + + //------------------------------------- + // Take Array of Data and Create Objects + //------------------------------------- + + function request($incoming) + { + if ( ! is_array($incoming)) + { + // Send Error + } + + $this->data = array(); + + foreach($incoming as $key => $value) + { + $this->data[$key] = $this->values_parsing($value); + } + } + // END + + + //------------------------------------- + // Set Debug + //------------------------------------- + + function set_debug($flag = TRUE) + { + $this->debug = ($flag == TRUE) ? TRUE : FALSE; + } + + //------------------------------------- + // Values Parsing + //------------------------------------- + + function values_parsing($value, $return = FALSE) + { + if (is_array($value) && isset($value['0'])) + { + if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])])) + { + if (is_array($value[0])) + { + $temp = new XML_RPC_Values($value['0'], 'array'); + } + else + { + $temp = new XML_RPC_Values($value['0'], 'string'); + } + } + elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array')) + { + while (list($k) = each($value['0'])) + { + $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE); + } + + $temp = new XML_RPC_Values($value['0'], $value['1']); + } + else + { + $temp = new XML_RPC_Values($value['0'], $value['1']); + } + } + else + { + $temp = new XML_RPC_Values($value, 'string'); + } + + return $temp; + } + // END + + + //------------------------------------- + // Sends XML-RPC Request + //------------------------------------- + + function send_request() + { + $this->message = new XML_RPC_Message($this->method,$this->data); + $this->message->debug = $this->debug; + + if ( ! $this->result = $this->client->send($this->message)) + { + $this->error = $this->result->errstr; + return FALSE; + } + elseif( ! is_object($this->result->val)) + { + $this->error = $this->result->errstr; + return FALSE; + } + + $this->response = $this->result->decode(); + + return TRUE; + } + // END + + //------------------------------------- + // Returns Error + //------------------------------------- + + function display_error() + { + return $this->error; + } + // END + + //------------------------------------- + // Returns Remote Server Response + //------------------------------------- + + function display_response() + { + return $this->response; + } + // END + + //------------------------------------- + // Sends an Error Message for Server Request + //------------------------------------- + + function send_error_message($number, $message) + { + return new XML_RPC_Response('0',$number, $message); + } + // END + + + //------------------------------------- + // Send Response for Server Request + //------------------------------------- + + function send_response($response) + { + // $response should be array of values, which will be parsed + // based on their data and type into a valid group of XML-RPC values + + $response = $this->values_parsing($response); + + return new XML_RPC_Response($response); + } + // END + +} // END XML_RPC Class + + + +/** + * XML-RPC Client class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Client extends CI_Xmlrpc +{ + var $path = ''; + var $server = ''; + var $port = 80; + var $errno = ''; + var $errstring = ''; + var $timeout = 5; + var $no_multicall = false; + + function XML_RPC_Client($path, $server, $port=80) + { + parent::CI_Xmlrpc(); + + $this->port = $port; + $this->server = $server; + $this->path = $path; + } + + function send($msg) + { + if (is_array($msg)) + { + // Multi-call disabled + $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']); + return $r; + } + + return $this->sendPayload($msg); + } + + function sendPayload($msg) + { + $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout); + + if (! is_resource($fp)) + { + error_log($this->xmlrpcstr['http_error']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']); + return $r; + } + + if(empty($msg->payload)) + { + // $msg = XML_RPC_Messages + $msg->createPayload(); + } + + $r = "\r\n"; + $op = "POST {$this->path} HTTP/1.0$r"; + $op .= "Host: {$this->server}$r"; + $op .= "Content-Type: text/xml$r"; + $op .= "User-Agent: {$this->xmlrpcName}$r"; + $op .= "Content-Length: ".strlen($msg->payload). "$r$r"; + $op .= $msg->payload; + + + if (!fputs($fp, $op, strlen($op))) + { + error_log($this->xmlrpcstr['http_error']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']); + return $r; + } + $resp = $msg->parseResponse($fp); + fclose($fp); + return $resp; + } + +} // end class XML_RPC_Client + + +/** + * XML-RPC Response class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Response +{ + var $val = 0; + var $errno = 0; + var $errstr = ''; + var $headers = array(); + + function XML_RPC_Response($val, $code = 0, $fstr = '') + { + if ($code != 0) + { + // error + $this->errno = $code; + $this->errstr = htmlentities($fstr); + } + else if (!is_object($val)) + { + // programmer error, not an object + error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response. Defaulting to empty value."); + $this->val = new XML_RPC_Values(); + } + else + { + $this->val = $val; + } + } + + function faultCode() + { + return $this->errno; + } + + function faultString() + { + return $this->errstr; + } + + function value() + { + return $this->val; + } + + function prepare_response() + { + $result = "\n"; + if ($this->errno) + { + $result .= ' + + + + faultCode + ' . $this->errno . ' + + + faultString + ' . $this->errstr . ' + + + +'; + } + else + { + $result .= "\n\n" . + $this->val->serialize_class() . + "\n"; + } + $result .= "\n"; + return $result; + } + + function decode($array=FALSE) + { + $CI =& get_instance(); + + if ($array !== FALSE && is_array($array)) + { + while (list($key) = each($array)) + { + if (is_array($array[$key])) + { + $array[$key] = $this->decode($array[$key]); + } + else + { + $array[$key] = $CI->input->xss_clean($array[$key]); + } + } + + $result = $array; + } + else + { + $result = $this->xmlrpc_decoder($this->val); + + if (is_array($result)) + { + $result = $this->decode($result); + } + else + { + $result = $CI->input->xss_clean($result); + } + } + + return $result; + } + + + + //------------------------------------- + // XML-RPC Object to PHP Types + //------------------------------------- + + function xmlrpc_decoder($xmlrpc_val) + { + $kind = $xmlrpc_val->kindOf(); + + if($kind == 'scalar') + { + return $xmlrpc_val->scalarval(); + } + elseif($kind == 'array') + { + reset($xmlrpc_val->me); + list($a,$b) = each($xmlrpc_val->me); + $size = sizeof($b); + + $arr = array(); + + for($i = 0; $i < $size; $i++) + { + $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]); + } + return $arr; + } + elseif($kind == 'struct') + { + reset($xmlrpc_val->me['struct']); + $arr = array(); + + while(list($key,$value) = each($xmlrpc_val->me['struct'])) + { + $arr[$key] = $this->xmlrpc_decoder($value); + } + return $arr; + } + } + + + //------------------------------------- + // ISO-8601 time to server or UTC time + //------------------------------------- + + function iso8601_decode($time, $utc=0) + { + // return a timet in the localtime, or UTC + $t = 0; + if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs)) + { + if ($utc == 1) + $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + else + $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } + return $t; + } + +} // End Response Class + + + +/** + * XML-RPC Message class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Message extends CI_Xmlrpc +{ + var $payload; + var $method_name; + var $params = array(); + var $xh = array(); + + function XML_RPC_Message($method, $pars=0) + { + parent::CI_Xmlrpc(); + + $this->method_name = $method; + if (is_array($pars) && sizeof($pars) > 0) + { + for($i=0; $iparams[] = $pars[$i]; + } + } + } + + //------------------------------------- + // Create Payload to Send + //------------------------------------- + + function createPayload() + { + $this->payload = "\r\n\r\n"; + $this->payload .= '' . $this->method_name . "\r\n"; + $this->payload .= "\r\n"; + + for($i=0; $iparams); $i++) + { + // $p = XML_RPC_Values + $p = $this->params[$i]; + $this->payload .= "\r\n".$p->serialize_class()."\r\n"; + } + + $this->payload .= "\r\n\r\n"; + } + + //------------------------------------- + // Parse External XML-RPC Server's Response + //------------------------------------- + + function parseResponse($fp) + { + $data = ''; + + while($datum = fread($fp, 4096)) + { + $data .= $datum; + } + + //------------------------------------- + // DISPLAY HTTP CONTENT for DEBUGGING + //------------------------------------- + + if ($this->debug === TRUE) + { + echo "
    ";
    +			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
    +			echo "
    "; + } + + //------------------------------------- + // Check for data + //------------------------------------- + + if($data == "") + { + error_log($this->xmlrpcstr['no_data']); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']); + return $r; + } + + + //------------------------------------- + // Check for HTTP 200 Response + //------------------------------------- + + if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data)) + { + $errstr= substr($data, 0, strpos($data, "\n")-1); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')'); + return $r; + } + + //------------------------------------- + // Create and Set Up XML Parser + //------------------------------------- + + $parser = xml_parser_create($this->xmlrpc_defencoding); + + $this->xh[$parser] = array(); + $this->xh[$parser]['isf'] = 0; + $this->xh[$parser]['ac'] = ''; + $this->xh[$parser]['headers'] = array(); + $this->xh[$parser]['stack'] = array(); + $this->xh[$parser]['valuestack'] = array(); + $this->xh[$parser]['isf_reason'] = 0; + + xml_set_object($parser, $this); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'open_tag', 'closing_tag'); + xml_set_character_data_handler($parser, 'character_data'); + //xml_set_default_handler($parser, 'default_handler'); + + + //------------------------------------- + // GET HEADERS + //------------------------------------- + + $lines = explode("\r\n", $data); + while (($line = array_shift($lines))) + { + if (strlen($line) < 1) + { + break; + } + $this->xh[$parser]['headers'][] = $line; + } + $data = implode("\r\n", $lines); + + + //------------------------------------- + // PARSE XML DATA + //------------------------------------- + + if (!xml_parse($parser, $data, sizeof($data))) + { + $errstr = sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser)); + //error_log($errstr); + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']); + xml_parser_free($parser); + return $r; + } + xml_parser_free($parser); + + // --------------------------------------- + // Got Ourselves Some Badness, It Seems + // --------------------------------------- + + if ($this->xh[$parser]['isf'] > 1) + { + if ($this->debug === TRUE) + { + echo "---Invalid Return---\n"; + echo $this->xh[$parser]['isf_reason']; + echo "---Invalid Return---\n\n"; + } + + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return $r; + } + elseif ( ! is_object($this->xh[$parser]['value'])) + { + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); + return $r; + } + + //------------------------------------- + // DISPLAY XML CONTENT for DEBUGGING + //------------------------------------- + + if ($this->debug === TRUE) + { + echo "
    ";
    +			
    +			if (count($this->xh[$parser]['headers'] > 0))
    +			{
    +				echo "---HEADERS---\n";
    +				foreach ($this->xh[$parser]['headers'] as $header)
    +				{
    +					echo "$header\n";
    +				}
    +				echo "---END HEADERS---\n\n";
    +			}
    +			
    +			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
    +			
    +			echo "---PARSED---\n" ;
    +			var_dump($this->xh[$parser]['value']);
    +			echo "\n---END PARSED---
    "; + } + + //------------------------------------- + // SEND RESPONSE + //------------------------------------- + + $v = $this->xh[$parser]['value']; + + if ($this->xh[$parser]['isf']) + { + $errno_v = $v->me['struct']['faultCode']; + $errstr_v = $v->me['struct']['faultString']; + $errno = $errno_v->scalarval(); + + if ($errno == 0) + { + // FAULT returned, errno needs to reflect that + $errno = -1; + } + + $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval()); + } + else + { + $r = new XML_RPC_Response($v); + } + + $r->headers = $this->xh[$parser]['headers']; + return $r; + } + + // ------------------------------------ + // Begin Return Message Parsing section + // ------------------------------------ + + // quick explanation of components: + // ac - used to accumulate values + // isf - used to indicate a fault + // lv - used to indicate "looking for a value": implements + // the logic to allow values with no types to be strings + // params - used to store parameters in method calls + // method - used to store method name + // stack - array with parent tree of the xml element, + // used to validate the nesting of elements + + //------------------------------------- + // Start Element Handler + //------------------------------------- + + function open_tag($the_parser, $name, $attrs) + { + // If invalid nesting, then return + if ($this->xh[$the_parser]['isf'] > 1) return; + + // Evaluate and check for correct nesting of XML elements + + if (count($this->xh[$the_parser]['stack']) == 0) + { + if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') + { + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing'; + return; + } + } + else + { + // not top level element: see if parent is OK + if (!in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE)) + { + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0]; + return; + } + } + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + // Creates array for child elements + + $cur_val = array('value' => array(), + 'type' => $name); + + array_unshift($this->xh[$the_parser]['valuestack'], $cur_val); + break; + case 'METHODNAME': + case 'NAME': + $this->xh[$the_parser]['ac'] = ''; + break; + case 'FAULT': + $this->xh[$the_parser]['isf'] = 1; + break; + case 'PARAM': + $this->xh[$the_parser]['value'] = null; + break; + case 'VALUE': + $this->xh[$the_parser]['vt'] = 'value'; + $this->xh[$the_parser]['ac'] = ''; + $this->xh[$the_parser]['lv'] = 1; + break; + case 'I4': + case 'INT': + case 'STRING': + case 'BOOLEAN': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + if ($this->xh[$the_parser]['vt'] != 'value') + { + //two data elements inside a value: an error occurred! + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value"; + return; + } + + $this->xh[$the_parser]['ac'] = ''; + break; + case 'MEMBER': + // Set name of to nothing to prevent errors later if no is found + $this->xh[$the_parser]['valuestack'][0]['name'] = ''; + + // Set NULL value to check to see if value passed for this param/member + $this->xh[$the_parser]['value'] = null; + break; + case 'DATA': + case 'METHODCALL': + case 'METHODRESPONSE': + case 'PARAMS': + // valid elements that add little to processing + break; + default: + /// An Invalid Element is Found, so we have trouble + $this->xh[$the_parser]['isf'] = 2; + $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name"; + break; + } + + // Add current element name to stack, to allow validation of nesting + array_unshift($this->xh[$the_parser]['stack'], $name); + + if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0; + } + // END + + + //------------------------------------- + // End Element Handler + //------------------------------------- + + function closing_tag($the_parser, $name) + { + if ($this->xh[$the_parser]['isf'] > 1) return; + + // Remove current element from stack and set variable + // NOTE: If the XML validates, then we do not have to worry about + // the opening and closing of elements. Nesting is checked on the opening + // tag so we be safe there as well. + + $curr_elem = array_shift($this->xh[$the_parser]['stack']); + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + $cur_val = array_shift($this->xh[$the_parser]['valuestack']); + $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values']; + $this->xh[$the_parser]['vt'] = strtolower($name); + break; + case 'NAME': + $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac']; + break; + case 'BOOLEAN': + case 'I4': + case 'INT': + case 'STRING': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + $this->xh[$the_parser]['vt'] = strtolower($name); + + if ($name == 'STRING') + { + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + } + elseif ($name=='DATETIME.ISO8601') + { + $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime; + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + } + elseif ($name=='BASE64') + { + $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']); + } + elseif ($name=='BOOLEAN') + { + // Translated BOOLEAN values to TRUE AND FALSE + if ($this->xh[$the_parser]['ac'] == '1') + { + $this->xh[$the_parser]['value'] = TRUE; + } + else + { + $this->xh[$the_parser]['value'] = FALSE; + } + } + elseif ($name=='DOUBLE') + { + // we have a DOUBLE + // we must check that only 0123456789-. are characters here + if (! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND'; + } + else + { + $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac']; + } + } + else + { + // we have an I4/INT + // we must check that only 0123456789- are characters here + if (! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND'; + } + else + { + $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac']; + } + } + $this->xh[$the_parser]['ac'] = ''; + $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value + break; + case 'VALUE': + // This if() detects if no scalar was inside + if ($this->xh[$the_parser]['vt']=='value') + { + $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; + $this->xh[$the_parser]['vt'] = $this->xmlrpcString; + } + + // build the XML-RPC value out of the data received, and substitute it + $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']); + + if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY') + { + // Array + $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp; + } + else + { + // Struct + $this->xh[$the_parser]['value'] = $temp; + } + break; + case 'MEMBER': + $this->xh[$the_parser]['ac']=''; + + // If value add to array in the stack for the last element built + if ($this->xh[$the_parser]['value']) + { + $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value']; + } + break; + case 'DATA': + $this->xh[$the_parser]['ac']=''; + break; + case 'PARAM': + if ($this->xh[$the_parser]['value']) + { + $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value']; + } + break; + case 'METHODNAME': + $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']); + break; + case 'PARAMS': + case 'FAULT': + case 'METHODCALL': + case 'METHORESPONSE': + // We're all good kids with nuthin' to do + break; + default: + // End of an Invalid Element. Taken care of during the opening tag though + break; + } + } + + //------------------------------------- + // Parses Character Data + //------------------------------------- + + function character_data($the_parser, $data) + { + if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already + + // If a value has not been found + if ($this->xh[$the_parser]['lv'] != 3) + { + if ($this->xh[$the_parser]['lv'] == 1) + { + $this->xh[$the_parser]['lv'] = 2; // Found a value + } + + if( ! @isset($this->xh[$the_parser]['ac'])) + { + $this->xh[$the_parser]['ac'] = ''; + } + + $this->xh[$the_parser]['ac'] .= $data; + } + } + + + function addParam($par) { $this->params[]=$par; } + + function output_parameters($array=FALSE) + { + $CI =& get_instance(); + + if ($array !== FALSE && is_array($array)) + { + while (list($key) = each($array)) + { + if (is_array($array[$key])) + { + $array[$key] = $this->output_parameters($array[$key]); + } + else + { + $array[$key] = $CI->input->xss_clean($array[$key]); + } + } + + $parameters = $array; + } + else + { + $parameters = array(); + + for ($i = 0; $i < sizeof($this->params); $i++) + { + $a_param = $this->decode_message($this->params[$i]); + + if (is_array($a_param)) + { + $parameters[] = $this->output_parameters($a_param); + } + else + { + $parameters[] = $CI->input->xss_clean($a_param); + } + } + } + + return $parameters; + } + + + function decode_message($param) + { + $kind = $param->kindOf(); + + if($kind == 'scalar') + { + return $param->scalarval(); + } + elseif($kind == 'array') + { + reset($param->me); + list($a,$b) = each($param->me); + + $arr = array(); + + for($i = 0; $i < sizeof($b); $i++) + { + $arr[] = $this->decode_message($param->me['array'][$i]); + } + + return $arr; + } + elseif($kind == 'struct') + { + reset($param->me['struct']); + + $arr = array(); + + while(list($key,$value) = each($param->me['struct'])) + { + $arr[$key] = $this->decode_message($value); + } + + return $arr; + } + } + +} // End XML_RPC_Messages class + + + +/** + * XML-RPC Values class + * + * @category XML-RPC + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html + */ +class XML_RPC_Values extends CI_Xmlrpc +{ + var $me = array(); + var $mytype = 0; + + function XML_RPC_Values($val=-1, $type='') + { + parent::CI_Xmlrpc(); + + if ($val != -1 || $type != '') + { + $type = $type == '' ? 'string' : $type; + + if ($this->xmlrpcTypes[$type] == 1) + { + $this->addScalar($val,$type); + } + elseif ($this->xmlrpcTypes[$type] == 2) + { + $this->addArray($val); + } + elseif ($this->xmlrpcTypes[$type] == 3) + { + $this->addStruct($val); + } + } + } + + function addScalar($val, $type='string') + { + $typeof = $this->xmlrpcTypes[$type]; + + if ($this->mytype==1) + { + echo 'XML_RPC_Values: scalar can have only one value
    '; + return 0; + } + + if ($typeof != 1) + { + echo 'XML_RPC_Values: not a scalar type (${typeof})
    '; + return 0; + } + + if ($type == $this->xmlrpcBoolean) + { + if (strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false'))) + { + $val = 1; + } + else + { + $val=0; + } + } + + if ($this->mytype == 2) + { + // adding to an array here + $ar = $this->me['array']; + $ar[] = new XML_RPC_Values($val, $type); + $this->me['array'] = $ar; + } + else + { + // a scalar, so set the value and remember we're scalar + $this->me[$type] = $val; + $this->mytype = $typeof; + } + return 1; + } + + function addArray($vals) + { + if ($this->mytype != 0) + { + echo 'XML_RPC_Values: already initialized as a [' . $this->kindOf() . ']
    '; + return 0; + } + + $this->mytype = $this->xmlrpcTypes['array']; + $this->me['array'] = $vals; + return 1; + } + + function addStruct($vals) + { + if ($this->mytype != 0) + { + echo 'XML_RPC_Values: already initialized as a [' . $this->kindOf() . ']
    '; + return 0; + } + $this->mytype = $this->xmlrpcTypes['struct']; + $this->me['struct'] = $vals; + return 1; + } + + function kindOf() + { + switch($this->mytype) + { + case 3: + return 'struct'; + break; + case 2: + return 'array'; + break; + case 1: + return 'scalar'; + break; + default: + return 'undef'; + } + } + + function serializedata($typ, $val) + { + $rs = ''; + + switch($this->xmlrpcTypes[$typ]) + { + case 3: + // struct + $rs .= "\n"; + reset($val); + while(list($key2, $val2) = each($val)) + { + $rs .= "\n{$key2}\n"; + $rs .= $this->serializeval($val2); + $rs .= "\n"; + } + $rs .= ''; + break; + case 2: + // array + $rs .= "\n\n"; + for($i=0; $i < sizeof($val); $i++) + { + $rs .= $this->serializeval($val[$i]); + } + $rs.="\n\n"; + break; + case 1: + // others + switch ($typ) + { + case $this->xmlrpcBase64: + $rs .= "<{$typ}>" . base64_encode($val) . "\n"; + break; + case $this->xmlrpcBoolean: + $rs .= "<{$typ}>" . ($val ? '1' : '0') . "\n"; + break; + case $this->xmlrpcString: + $rs .= "<{$typ}>" . htmlspecialchars($val). "\n"; + break; + default: + $rs .= "<{$typ}>{$val}\n"; + break; + } + default: + break; + } + return $rs; + } + + function serialize_class() + { + return $this->serializeval($this); + } + + function serializeval($o) + { + $ar = $o->me; + reset($ar); + + list($typ, $val) = each($ar); + $rs = "\n".$this->serializedata($typ, $val)."\n"; + return $rs; + } + + function scalarval() + { + reset($this->me); + list($a,$b) = each($this->me); + return $b; + } + + + //------------------------------------- + // Encode time in ISO-8601 form. + //------------------------------------- + + // Useful for sending time in XML-RPC + + function iso8601_encode($time, $utc=0) + { + if ($utc == 1) + { + $t = strftime("%Y%m%dT%H:%M:%S", $time); + } + else + { + if (function_exists('gmstrftime')) + $t = gmstrftime("%Y%m%dT%H:%M:%S", $time); + else + $t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z')); + } + return $t; + } + +} +// END XML_RPC_Values Class +?> \ No newline at end of file diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php new file mode 100755 index 0000000..ac644d8 --- /dev/null +++ b/system/libraries/Xmlrpcs.php @@ -0,0 +1,522 @@ +set_system_methods(); + + if (isset($config['functions']) && is_array($config['functions'])) + { + $this->methods = array_merge($this->methods, $config['functions']); + } + + log_message('debug', "XML-RPC Server Class Initialized"); + } + + //------------------------------------- + // Initialize Prefs and Serve + //------------------------------------- + + function initialize($config=array()) + { + if (isset($config['functions']) && is_array($config['functions'])) + { + $this->methods = array_merge($this->methods, $config['functions']); + } + + if (isset($config['debug'])) + { + $this->debug = $config['debug']; + } + } + + //------------------------------------- + // Setting of System Methods + //------------------------------------- + + function set_system_methods () + { + $this->methods = array( + 'system.listMethods' => array( + 'function' => 'this.listMethods', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)), + 'docstring' => 'Returns an array of available methods on this server'), + 'system.methodHelp' => array( + 'function' => 'this.methodHelp', + 'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)), + 'docstring' => 'Returns a documentation string for the specified method'), + 'system.methodSignature' => array( + 'function' => 'this.methodSignature', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)), + 'docstring' => 'Returns an array describing the return type and required parameters of a method'), + 'system.multicall' => array( + 'function' => 'this.multicall', + 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)), + 'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details') + ); + } + + + //------------------------------------- + // Main Server Function + //------------------------------------- + + function serve() + { + $r = $this->parseRequest(); + $payload = 'xmlrpc_defencoding.'"?'.'>'."\n"; + $payload .= $this->debug_msg; + $payload .= $r->prepare_response(); + + header("Content-Type: text/xml"); + header("Content-Length: ".strlen($payload)); + echo $payload; + } + + //------------------------------------- + // Add Method to Class + //------------------------------------- + + function add_to_map($methodname,$function,$sig,$doc) + { + $this->methods[$methodname] = array( + 'function' => $function, + 'signature' => $sig, + 'docstring' => $doc + ); + } + + + //------------------------------------- + // Parse Server Request + //------------------------------------- + + function parseRequest($data='') + { + global $HTTP_RAW_POST_DATA; + + //------------------------------------- + // Get Data + //------------------------------------- + + if ($data == '') + { + $data = $HTTP_RAW_POST_DATA; + } + + //------------------------------------- + // Set up XML Parser + //------------------------------------- + + $parser = xml_parser_create($this->xmlrpc_defencoding); + $parser_object = new XML_RPC_Message("filler"); + + $parser_object->xh[$parser] = array(); + $parser_object->xh[$parser]['isf'] = 0; + $parser_object->xh[$parser]['isf_reason'] = ''; + $parser_object->xh[$parser]['params'] = array(); + $parser_object->xh[$parser]['stack'] = array(); + $parser_object->xh[$parser]['valuestack'] = array(); + $parser_object->xh[$parser]['method'] = ''; + + xml_set_object($parser, $parser_object); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'open_tag', 'closing_tag'); + xml_set_character_data_handler($parser, 'character_data'); + //xml_set_default_handler($parser, 'default_handler'); + + + //------------------------------------- + // PARSE + PROCESS XML DATA + //------------------------------------- + + if ( ! xml_parse($parser, $data, 1)) + { + // return XML error as a faultCode + $r = new XML_RPC_Response(0, + $this->xmlrpcerrxml + xml_get_error_code($parser), + sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + xml_parser_free($parser); + } + elseif($parser_object->xh[$parser]['isf']) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']); + } + else + { + xml_parser_free($parser); + + $m = new XML_RPC_Message($parser_object->xh[$parser]['method']); + $plist=''; + + for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++) + { + if ($this->debug === TRUE) + { + $plist .= "$i - " . print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n"; + } + + $m->addParam($parser_object->xh[$parser]['params'][$i]); + } + + if ($this->debug === TRUE) + { + echo "
    ";
    +				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
    +				echo "
    "; + } + + $r = $this->_execute($m); + } + + //------------------------------------- + // SET DEBUGGING MESSAGE + //------------------------------------- + + if ($this->debug === TRUE) + { + $this->debug_msg = "\n"; + } + + return $r; + } + + //------------------------------------- + // Executes the Method + //------------------------------------- + + function _execute($m) + { + $methName = $m->method_name; + + // Check to see if it is a system call + $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE; + + //------------------------------------- + // Valid Method + //------------------------------------- + + if ( ! isset($this->methods[$methName]['function'])) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + + //------------------------------------- + // Check for Method (and Object) + //------------------------------------- + + $method_parts = explode(".", $this->methods[$methName]['function']); + $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE; + + if ($system_call === TRUE) + { + if (! is_callable(array($this,$method_parts['1']))) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + } + else + { + if ($objectCall && !is_callable(array($method_parts['0'],$method_parts['1']))) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + elseif (!$objectCall && !is_callable($this->methods[$methName]['function'])) + { + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + } + } + + //------------------------------------- + // Checking Methods Signature + //------------------------------------- + + if (isset($this->methods[$methName]['signature'])) + { + $sig = $this->methods[$methName]['signature']; + for($i=0; $iparams)+1) + { + for($n=0; $n < sizeof($m->params); $n++) + { + $p = $m->params[$n]; + $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf(); + + if ($pt != $current_sig[$n+1]) + { + $pno = $n+1; + $wanted = $current_sig[$n+1]; + + return new XML_RPC_Response(0, + $this->xmlrpcerr['incorrect_params'], + $this->xmlrpcstr['incorrect_params'] . + ": Wanted {$wanted}, got {$pt} at param {$pno})"); + } + } + } + } + } + + //------------------------------------- + // Calls the Function + //------------------------------------- + + if ($objectCall === TRUE) + { + if ($method_parts[0] == "this" && $system_call == TRUE) + { + return call_user_func(array($this, $method_parts[1]), $m); + } + else + { + $CI =& get_instance(); + return $CI->$method_parts['1']($m); + //$class = new $method_parts['0']; + //return $class->$method_parts['1']($m); + //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m); + } + } + else + { + return call_user_func($this->methods[$methName]['function'], $m); + } + } + + + //------------------------------------- + // Server Function: List Methods + //------------------------------------- + + function listMethods($m) + { + $v = new XML_RPC_Values(); + $output = array(); + + foreach($this->methods as $key => $value) + { + $output[] = new XML_RPC_Values($key, 'string'); + } + + foreach($this->system_methods as $key => $value) + { + $output[]= new XML_RPC_Values($key, 'string'); + } + + $v->addArray($output); + return new XML_RPC_Response($v); + } + + //------------------------------------- + // Server Function: Return Signature for Method + //------------------------------------- + + function methodSignature($m) + { + $parameters = $m->output_parameters(); + $method_name = $parameters[0]; + + if (isset($this->methods[$method_name])) + { + if ($this->methods[$method_name]['signature']) + { + $sigs = array(); + $signature = $this->methods[$method_name]['signature']; + + for($i=0; $i < sizeof($signature); $i++) + { + $cursig = array(); + $inSig = $signature[$i]; + for($j=0; $jxmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); + } + return $r; + } + + //------------------------------------- + // Server Function: Doc String for Method + //------------------------------------- + + function methodHelp($m) + { + $parameters = $m->output_parameters(); + $method_name = $parameters[0]; + + if (isset($this->methods[$method_name])) + { + $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : ''; + + return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string')); + } + else + { + return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']); + } + } + + //------------------------------------- + // Server Function: Multi-call + //------------------------------------- + + function multicall($m) + { + // Disabled + return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); + + $parameters = $m->output_parameters(); + $calls = $parameters[0]; + + $result = array(); + + foreach ($calls as $value) + { + //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1])); + + $m = new XML_RPC_Message($value[0]); + $plist=''; + + for($i=0; $i < sizeof($value[1]); $i++) + { + $m->addParam(new XML_RPC_Values($value[1][$i], 'string')); + } + + $attempt = $this->_execute($m); + + if ($attempt->faultCode() != 0) + { + return $attempt; + } + + $result[] = new XML_RPC_Values(array($attempt->value()), 'array'); + } + + return new XML_RPC_Response(new XML_RPC_Values($result, 'array')); + } + + + //------------------------------------- + // Multi-call Function: Error Handling + //------------------------------------- + + function multicall_error($err) + { + $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString(); + $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode(); + + $struct['faultCode'] = new XML_RPC_Values($code, 'int'); + $struct['faultString'] = new XML_RPC_Values($str, 'string'); + + return new XML_RPC_Values($struct, 'struct'); + } + + + //------------------------------------- + // Multi-call Function: Processes method + //------------------------------------- + + function do_multicall($call) + { + if ($call->kindOf() != 'struct') + return $this->multicall_error('notstruct'); + elseif (!$methName = $call->me['struct']['methodName']) + return $this->multicall_error('nomethod'); + + list($scalar_type,$scalar_value)=each($methName->me); + $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type; + + if ($methName->kindOf() != 'scalar' || $scalar_type != 'string') + return $this->multicall_error('notstring'); + elseif ($scalar_value == 'system.multicall') + return $this->multicall_error('recursion'); + elseif (!$params = $call->me['struct']['params']) + return $this->multicall_error('noparams'); + elseif ($params->kindOf() != 'array') + return $this->multicall_error('notarray'); + + list($a,$b)=each($params->me); + $numParams = sizeof($b); + + $msg = new XML_RPC_Message($scalar_value); + for ($i = 0; $i < $numParams; $i++) + { + $msg->params[] = $params->me['array'][$i]; + } + + $result = $this->_execute($msg); + + if ($result->faultCode() != 0) + { + return $this->multicall_error($result); + } + + return new XML_RPC_Values(array($result->value()), 'array'); + } + +} +// END XML_RPC_Server class + +?> \ No newline at end of file diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php new file mode 100755 index 0000000..a3d42f3 --- /dev/null +++ b/system/libraries/Zip.php @@ -0,0 +1,377 @@ +_add_dir($dir); + } + } + + // -------------------------------------------------------------------- + + /** + * Add Directory + * + * @access private + * @param string the directory name + * @return void + */ + function _add_dir($dir) + { + $dir = str_replace("\\", "/", $dir); + + $this->zipdata[] = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + .pack('V', 0) + .pack('V', 0) + .pack('V', 0) + .pack('v', strlen($dir)) + .pack('v', 0) + .$dir + .pack('V', 0) + .pack('V', 0) + .pack('V', 0); + + $newoffset = strlen(implode('', $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + .pack('V',0) + .pack('V',0) + .pack('V',0) + .pack('v', strlen($dir)) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('V', 16) + .pack('V', $this->offset) + .$dir; + + $this->offset = $newoffset; + $this->directory[] = $record; + } + + // -------------------------------------------------------------------- + + /** + * Add Data to Zip + * + * Lets you add files to the archive. If the path is included + * in the filename it will be placed within a directory. Make + * sure you use add_dir() first to create the folder. + * + * @access public + * @param mixed + * @param string + * @return void + */ + function add_data($filepath, $data = NULL) + { + if (is_array($filepath)) + { + foreach ($filepath as $path => $data) + { + $this->_add_data($path, $data); + } + } + else + { + $this->_add_data($filepath, $data); + } + } + + // -------------------------------------------------------------------- + + /** + * Add Data to Zip + * + * @access private + * @param string the file name/path + * @param string the data to be encoded + * @return void + */ + function _add_data($filepath, $data) + { + $filepath = str_replace("\\", "/", $filepath); + + $oldlen = strlen($data); + $crc32 = crc32($data); + + $gzdata = gzcompress($data); + $gzdata = substr($gzdata, 2, -4); + $newlen = strlen($gzdata); + + $this->zipdata[] = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + .pack('V', $crc32) + .pack('V', $newlen) + .pack('V', $oldlen) + .pack('v', strlen($filepath)) + .pack('v', 0) + .$filepath + .$gzdata; + + $newoffset = strlen(implode("", $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + .pack('V', $crc32) + .pack('V', $newlen) + .pack('V', $oldlen) + .pack('v', strlen($filepath)) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('v', 0) + .pack('V', 32) + .pack('V', $this->offset); + + $this->offset = $newoffset; + $this->directory[] = $record.$filepath; + } + + // -------------------------------------------------------------------- + + /** + * Read the contents of a file and add it to the zip + * + * @access public + * @return bool + */ + function read_file($path, $preserve_filepath = FALSE) + { + if ( ! file_exists($path)) + { + return FALSE; + } + + if (FALSE !== ($data = file_get_contents($path))) + { + $name = str_replace("\\", "/", $path); + + if ($preserve_filepath === FALSE) + { + $name = preg_replace("|.*/(.+)|", "\\1", $name); + } + + $this->add_data($name, $data); + return TRUE; + } + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Read a directory and add it to the zip. + * + * This function recursively reads a folder and everything it contains (including + * sub-folders) and creates a zip based on it. Whatever directory structure + * is in the original file path will be recreated in the zip file. + * + * @access public + * @param string path to source + * @return bool + */ + function read_dir($path) + { + if ($fp = @opendir($path)) + { + while (FALSE !== ($file = readdir($fp))) + { + if (@is_dir($path.$file) && substr($file, 0, 1) != '.') + { + $this->read_dir($path.$file."/"); + } + elseif (substr($file, 0, 1) != ".") + { + if (FALSE !== ($data = file_get_contents($path.$file))) + { + $this->add_data(str_replace("\\", "/", $path).$file, $data); + } + } + } + return TRUE; + } + } + + // -------------------------------------------------------------------- + + /** + * Get the Zip file + * + * @access public + * @return binary string + */ + function get_zip() + { + // We cache the zip data so multiple calls + // do not require recompiling + if ($this->zipfile != '') + { + return $this->zipfile; + } + + // Is there any data to return? + if (count($this->zipdata) == 0) + { + return FALSE; + } + + $data = implode('', $this->zipdata); + $dir = implode('', $this->directory); + + $this->zipfile = $data.$dir."\x50\x4b\x05\x06\x00\x00\x00\x00" + .pack('v', sizeof($this->directory)) + .pack('v', sizeof($this->directory)) + .pack('V', strlen($dir)) + .pack('V', strlen($data)) + ."\x00\x00"; + + return $this->zipfile; + } + + // -------------------------------------------------------------------- + + /** + * Write File to the specified directory + * + * Lets you write a file + * + * @access public + * @param string the file name + * @param string the data to be encoded + * @return bool + */ + function archive($filepath) + { + if ( ! ($fp = @fopen($filepath, "wb"))) + { + return FALSE; + } + + flock($fp, LOCK_EX); + fwrite($fp, $this->get_zip()); + flock($fp, LOCK_UN); + fclose($fp); + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Download + * + * @access public + * @param string the file name + * @param string the data to be encoded + * @return bool + */ + function download($filename = 'backup.zip') + { + if ( ! preg_match("|.+?\.zip$|", $filename)) + { + $filename .= '.zip'; + } + + if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: inline; filename="'.$filename.'"'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header("Content-Transfer-Encoding: binary"); + header('Pragma: public'); + header("Content-Length: ".strlen($this->get_zip())); + } + else + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: attachment; filename="'.$filename.'"'); + header("Content-Transfer-Encoding: binary"); + header('Expires: 0'); + header('Pragma: no-cache'); + header("Content-Length: ".strlen($this->get_zip())); + } + + echo $this->get_zip(); + } + + // -------------------------------------------------------------------- + + /** + * Initialize Data + * + * Lets you clear current zip data. Useful if you need to create + * multiple zips with different data. + * + * @access public + * @return void + */ + function clear_data() + { + $this->zipfile = ''; + $this->zipdata = array(); + $this->directory = array(); + $this->offset = array(); + } + +} +?> \ No newline at end of file diff --git a/system/libraries/index.html b/system/libraries/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/libraries/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/logs/.svn/all-wcprops b/system/logs/.svn/all-wcprops new file mode 100644 index 0000000..085f5c4 --- /dev/null +++ b/system/logs/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 34 +/svn/!svn/ver/18/trunk/system/logs +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/!svn/ver/18/trunk/system/logs/index.html +END diff --git a/system/logs/.svn/entries b/system/logs/.svn/entries new file mode 100644 index 0000000..5044bc3 --- /dev/null +++ b/system/logs/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/logs +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +index.html +file + + + + +2009-09-15T00:18:12.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/logs/.svn/prop-base/index.html.svn-base b/system/logs/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/logs/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/logs/.svn/text-base/index.html.svn-base b/system/logs/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/logs/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/logs/index.html b/system/logs/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/logs/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/plugins/.svn/all-wcprops b/system/plugins/.svn/all-wcprops new file mode 100644 index 0000000..e8d245e --- /dev/null +++ b/system/plugins/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 37 +/svn/!svn/ver/18/trunk/system/plugins +END +captcha_pi.php +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/plugins/captcha_pi.php +END +js_calendar_pi.php +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/!svn/ver/18/trunk/system/plugins/js_calendar_pi.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/18/trunk/system/plugins/index.html +END diff --git a/system/plugins/.svn/entries b/system/plugins/.svn/entries new file mode 100644 index 0000000..f793239 --- /dev/null +++ b/system/plugins/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/plugins +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +captcha_pi.php +file + + + + +2009-09-15T00:17:42.000000Z +e9cfb8bcbaa7f21c7e1ef339ff2de3a1 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +9066 + +js_calendar_pi.php +file + + + + +2009-09-15T00:17:42.000000Z +7d9bbabdfbf9ed5d4dc8f60773c75969 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +15634 + +index.html +file + + + + +2009-09-15T00:17:42.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + diff --git a/system/plugins/.svn/prop-base/captcha_pi.php.svn-base b/system/plugins/.svn/prop-base/captcha_pi.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/plugins/.svn/prop-base/captcha_pi.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/plugins/.svn/prop-base/index.html.svn-base b/system/plugins/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/plugins/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/plugins/.svn/prop-base/js_calendar_pi.php.svn-base b/system/plugins/.svn/prop-base/js_calendar_pi.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/plugins/.svn/prop-base/js_calendar_pi.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/plugins/.svn/text-base/captcha_pi.php.svn-base b/system/plugins/.svn/text-base/captcha_pi.php.svn-base new file mode 100644 index 0000000..693fd91 --- /dev/null +++ b/system/plugins/.svn/text-base/captcha_pi.php.svn-base @@ -0,0 +1,346 @@ +load->plugin('captcha'); + +Once loaded you can generate a captcha like this: + + $vals = array( + 'word' => 'Random word', + 'img_path' => './captcha/', + 'img_url' => 'http://www.your-site.com/captcha/', + 'font_path' => './system/texb.ttf', + 'img_width' => '150', + 'img_height' => 30, + 'expiration' => 7200 + ); + + $cap = create_captcha($vals); + echo $cap['image']; + + +NOTES: + + The captcha function requires the GD image library. + + Only the img_path and img_url are required. + + If a "word" is not supplied, the function will generate a random + ASCII string. You might put together your own word library that + you can draw randomly from. + + If you do not specify a path to a TRUE TYPE font, the native ugly GD + font will be used. + + The "captcha" folder must be writable (666, or 777) + + The "expiration" (in seconds) signifies how long an image will + remain in the captcha folder before it will be deleted. The default + is two hours. + +RETURNED DATA + +The create_captcha() function returns an associative array with this data: + + [array] + ( + 'image' => IMAGE TAG + 'time' => TIMESTAMP (in microtime) + 'word' => CAPTCHA WORD + ) + +The "image" is the actual image tag: + + +The "time" is the micro timestamp used as the image name without the file +extension. It will be a number like this: 1139612155.3422 + +The "word" is the word that appears in the captcha image, which if not +supplied to the function, will be a random string. + + +ADDING A DATABASE + +In order for the captcha function to prevent someone from posting, you will need +to add the information returned from create_captcha() function to your database. +Then, when the data from the form is submitted by the user you will need to verify +that the data exists in the database and has not expired. + +Here is a table prototype: + + CREATE TABLE captcha ( + captcha_id bigint(13) unsigned NOT NULL auto_increment, + captcha_time int(10) unsigned NOT NULL, + ip_address varchar(16) default '0' NOT NULL, + word varchar(20) NOT NULL, + PRIMARY KEY (captcha_id), + KEY (word) + ) + + +Here is an example of usage with a DB. + +On the page where the captcha will be shown you'll have something like this: + + $this->load->plugin('captcha'); + $vals = array( + 'img_path' => './captcha/', + 'img_url' => 'http://www.your-site.com/captcha/' + ); + + $cap = create_captcha($vals); + + $data = array( + 'captcha_id' => '', + 'captcha_time' => $cap['time'], + 'ip_address' => $this->input->ip_address(), + 'word' => $cap['word'] + ); + + $query = $this->db->insert_string('captcha', $data); + $this->db->query($query); + + echo 'Submit the word you see below:'; + echo $cap['image']; + echo ''; + + +Then, on the page that accepts the submission you'll have something like this: + + // First, delete old captchas + $expiration = time()-7200; // Two hour limit + $DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration); + + // Then see if a captcha exists: + $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?"; + $binds = array($_POST['captcha'], $this->input->ip_address(), $expiration); + $query = $this->db->query($sql, $binds); + $row = $query->row(); + + if ($row->count == 0) + { + echo "You must submit the word that appears in the image"; + } + +*/ + + + +/** +|========================================================== +| Create Captcha +|========================================================== +| +*/ +function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') +{ + $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200); + + foreach ($defaults as $key => $val) + { + if ( ! is_array($data)) + { + if ( ! isset($$key) OR $$key == '') + { + $$key = $val; + } + } + else + { + $$key = ( ! isset($data[$key])) ? $val : $data[$key]; + } + } + + if ($img_path == '' OR $img_url == '') + { + return FALSE; + } + + if ( ! @is_dir($img_path)) + { + return FALSE; + } + + if ( ! is_really_writable($img_path)) + { + return FALSE; + } + + if ( ! extension_loaded('gd')) + { + return FALSE; + } + + // ----------------------------------- + // Remove old images + // ----------------------------------- + + list($usec, $sec) = explode(" ", microtime()); + $now = ((float)$usec + (float)$sec); + + $current_dir = @opendir($img_path); + + while($filename = @readdir($current_dir)) + { + if ($filename != "." and $filename != ".." and $filename != "index.html") + { + $name = str_replace(".jpg", "", $filename); + + if (($name + $expiration) < $now) + { + @unlink($img_path.$filename); + } + } + } + + @closedir($current_dir); + + // ----------------------------------- + // Do we have a "word" yet? + // ----------------------------------- + + if ($word == '') + { + $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + $str = ''; + for ($i = 0; $i < 8; $i++) + { + $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); + } + + $word = $str; + } + + // ----------------------------------- + // Determine angle and position + // ----------------------------------- + + $length = strlen($word); + $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0; + $x_axis = rand(6, (360/$length)-16); + $y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height); + + // ----------------------------------- + // Create image + // ----------------------------------- + + $im = ImageCreate($img_width, $img_height); + + // ----------------------------------- + // Assign colors + // ----------------------------------- + + $bg_color = imagecolorallocate ($im, 255, 255, 255); + $border_color = imagecolorallocate ($im, 153, 102, 102); + $text_color = imagecolorallocate ($im, 204, 153, 153); + $grid_color = imagecolorallocate($im, 255, 182, 182); + $shadow_color = imagecolorallocate($im, 255, 240, 240); + + // ----------------------------------- + // Create the rectangle + // ----------------------------------- + + ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color); + + // ----------------------------------- + // Create the spiral pattern + // ----------------------------------- + + $theta = 1; + $thetac = 7; + $radius = 16; + $circles = 20; + $points = 32; + + for ($i = 0; $i < ($circles * $points) - 1; $i++) + { + $theta = $theta + $thetac; + $rad = $radius * ($i / $points ); + $x = ($rad * cos($theta)) + $x_axis; + $y = ($rad * sin($theta)) + $y_axis; + $theta = $theta + $thetac; + $rad1 = $radius * (($i + 1) / $points); + $x1 = ($rad1 * cos($theta)) + $x_axis; + $y1 = ($rad1 * sin($theta )) + $y_axis; + imageline($im, $x, $y, $x1, $y1, $grid_color); + $theta = $theta - $thetac; + } + + // ----------------------------------- + // Write the text + // ----------------------------------- + + $use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE; + + if ($use_font == FALSE) + { + $font_size = 5; + $x = rand(0, $img_width/($length/3)); + $y = 0; + } + else + { + $font_size = 16; + $x = rand(0, $img_width/($length/1.5)); + $y = $font_size+2; + } + + for ($i = 0; $i < strlen($word); $i++) + { + if ($use_font == FALSE) + { + $y = rand(0 , $img_height/2); + imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color); + $x += ($font_size*2); + } + else + { + $y = rand($img_height/2, $img_height-3); + imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1)); + $x += $font_size; + } + } + + + // ----------------------------------- + // Create the border + // ----------------------------------- + + imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color); + + // ----------------------------------- + // Generate the image + // ----------------------------------- + + $img_name = $now.'.jpg'; + + ImageJPEG($im, $img_path.$img_name); + + $img = "\""; + + ImageDestroy($im); + + return array('word' => $word, 'time' => $now, 'image' => $img); +} + +?> \ No newline at end of file diff --git a/system/plugins/.svn/text-base/index.html.svn-base b/system/plugins/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/plugins/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/plugins/.svn/text-base/js_calendar_pi.php.svn-base b/system/plugins/.svn/text-base/js_calendar_pi.php.svn-base new file mode 100644 index 0000000..86270ca --- /dev/null +++ b/system/plugins/.svn/text-base/js_calendar_pi.php.svn-base @@ -0,0 +1,627 @@ +load->plugin('js_calendar'); + +Once loaded you'll add the calendar script to the of your page like this: + + + +The above function will be passed the name of your form. + +Then to show the actual calendar you'll do this: + + +

    + +

    Today

    +
    + + +Note: The first parameter is the name of the field containing your date, the second parameter contains the "now" time, +and the third tells the calendar whether to highlight the current day or not. + +Lastly, you'll need some CSS for your calendar: + +.calendar { + border: 1px #6975A3 solid; + background-color: transparent; +} +.calheading { + background-color: #7C8BC0; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + font-weight: bold; + text-align: center; +} +.calnavleft { + background-color: #7C8BC0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + font-weight: bold; + color: #fff; + padding: 4px; + cursor: pointer; +} +.calnavright { + background-color: #7C8BC0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + font-weight: bold; + color: #fff; + text-align: right; + padding: 4px; + cursor: pointer; +} +.caldayheading { + background-color: #000; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + text-align: center; + padding: 6px 2px 6px 2px; +} +.caldaycells{ + color: #000; + background-color: #D1D7E6; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + text-align: center; + padding: 4px; + border: 1px #E0E5F1 solid; + cursor: pointer; +} +.caldaycellhover{ + color: #fff; + background-color: #B3BCD4; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + text-align: center; + padding: 4px; + border: 1px #B3BCD4 solid; + cursor: pointer; +} +.caldayselected{ + background-color: #737FAC; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + font-weight: bold; + text-align: center; + border: 1px #566188 solid; + padding: 3px; + cursor: pointer; +} +.calblanktop { + background-color: #fff; + padding: 4px; +} +.calblankbot { + background-color: #fff; + padding: 4px; +} + + +*/ + +function js_calendar_script($form_name = 'entryform') +{ +$CI =& get_instance(); +$CI->load->language('calendar'); +ob_start(); +?> + + + var '.$field_id.' = new calendar("'.$field_id.'", '.$time.', '.(($highlight == TRUE) ? 'true' : 'false').'); + document.write('.$field_id.'.write()); + '; +} + +?> \ No newline at end of file diff --git a/system/plugins/captcha_pi.php b/system/plugins/captcha_pi.php new file mode 100755 index 0000000..693fd91 --- /dev/null +++ b/system/plugins/captcha_pi.php @@ -0,0 +1,346 @@ +load->plugin('captcha'); + +Once loaded you can generate a captcha like this: + + $vals = array( + 'word' => 'Random word', + 'img_path' => './captcha/', + 'img_url' => 'http://www.your-site.com/captcha/', + 'font_path' => './system/texb.ttf', + 'img_width' => '150', + 'img_height' => 30, + 'expiration' => 7200 + ); + + $cap = create_captcha($vals); + echo $cap['image']; + + +NOTES: + + The captcha function requires the GD image library. + + Only the img_path and img_url are required. + + If a "word" is not supplied, the function will generate a random + ASCII string. You might put together your own word library that + you can draw randomly from. + + If you do not specify a path to a TRUE TYPE font, the native ugly GD + font will be used. + + The "captcha" folder must be writable (666, or 777) + + The "expiration" (in seconds) signifies how long an image will + remain in the captcha folder before it will be deleted. The default + is two hours. + +RETURNED DATA + +The create_captcha() function returns an associative array with this data: + + [array] + ( + 'image' => IMAGE TAG + 'time' => TIMESTAMP (in microtime) + 'word' => CAPTCHA WORD + ) + +The "image" is the actual image tag: + + +The "time" is the micro timestamp used as the image name without the file +extension. It will be a number like this: 1139612155.3422 + +The "word" is the word that appears in the captcha image, which if not +supplied to the function, will be a random string. + + +ADDING A DATABASE + +In order for the captcha function to prevent someone from posting, you will need +to add the information returned from create_captcha() function to your database. +Then, when the data from the form is submitted by the user you will need to verify +that the data exists in the database and has not expired. + +Here is a table prototype: + + CREATE TABLE captcha ( + captcha_id bigint(13) unsigned NOT NULL auto_increment, + captcha_time int(10) unsigned NOT NULL, + ip_address varchar(16) default '0' NOT NULL, + word varchar(20) NOT NULL, + PRIMARY KEY (captcha_id), + KEY (word) + ) + + +Here is an example of usage with a DB. + +On the page where the captcha will be shown you'll have something like this: + + $this->load->plugin('captcha'); + $vals = array( + 'img_path' => './captcha/', + 'img_url' => 'http://www.your-site.com/captcha/' + ); + + $cap = create_captcha($vals); + + $data = array( + 'captcha_id' => '', + 'captcha_time' => $cap['time'], + 'ip_address' => $this->input->ip_address(), + 'word' => $cap['word'] + ); + + $query = $this->db->insert_string('captcha', $data); + $this->db->query($query); + + echo 'Submit the word you see below:'; + echo $cap['image']; + echo ''; + + +Then, on the page that accepts the submission you'll have something like this: + + // First, delete old captchas + $expiration = time()-7200; // Two hour limit + $DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration); + + // Then see if a captcha exists: + $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?"; + $binds = array($_POST['captcha'], $this->input->ip_address(), $expiration); + $query = $this->db->query($sql, $binds); + $row = $query->row(); + + if ($row->count == 0) + { + echo "You must submit the word that appears in the image"; + } + +*/ + + + +/** +|========================================================== +| Create Captcha +|========================================================== +| +*/ +function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') +{ + $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200); + + foreach ($defaults as $key => $val) + { + if ( ! is_array($data)) + { + if ( ! isset($$key) OR $$key == '') + { + $$key = $val; + } + } + else + { + $$key = ( ! isset($data[$key])) ? $val : $data[$key]; + } + } + + if ($img_path == '' OR $img_url == '') + { + return FALSE; + } + + if ( ! @is_dir($img_path)) + { + return FALSE; + } + + if ( ! is_really_writable($img_path)) + { + return FALSE; + } + + if ( ! extension_loaded('gd')) + { + return FALSE; + } + + // ----------------------------------- + // Remove old images + // ----------------------------------- + + list($usec, $sec) = explode(" ", microtime()); + $now = ((float)$usec + (float)$sec); + + $current_dir = @opendir($img_path); + + while($filename = @readdir($current_dir)) + { + if ($filename != "." and $filename != ".." and $filename != "index.html") + { + $name = str_replace(".jpg", "", $filename); + + if (($name + $expiration) < $now) + { + @unlink($img_path.$filename); + } + } + } + + @closedir($current_dir); + + // ----------------------------------- + // Do we have a "word" yet? + // ----------------------------------- + + if ($word == '') + { + $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + $str = ''; + for ($i = 0; $i < 8; $i++) + { + $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); + } + + $word = $str; + } + + // ----------------------------------- + // Determine angle and position + // ----------------------------------- + + $length = strlen($word); + $angle = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0; + $x_axis = rand(6, (360/$length)-16); + $y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height); + + // ----------------------------------- + // Create image + // ----------------------------------- + + $im = ImageCreate($img_width, $img_height); + + // ----------------------------------- + // Assign colors + // ----------------------------------- + + $bg_color = imagecolorallocate ($im, 255, 255, 255); + $border_color = imagecolorallocate ($im, 153, 102, 102); + $text_color = imagecolorallocate ($im, 204, 153, 153); + $grid_color = imagecolorallocate($im, 255, 182, 182); + $shadow_color = imagecolorallocate($im, 255, 240, 240); + + // ----------------------------------- + // Create the rectangle + // ----------------------------------- + + ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color); + + // ----------------------------------- + // Create the spiral pattern + // ----------------------------------- + + $theta = 1; + $thetac = 7; + $radius = 16; + $circles = 20; + $points = 32; + + for ($i = 0; $i < ($circles * $points) - 1; $i++) + { + $theta = $theta + $thetac; + $rad = $radius * ($i / $points ); + $x = ($rad * cos($theta)) + $x_axis; + $y = ($rad * sin($theta)) + $y_axis; + $theta = $theta + $thetac; + $rad1 = $radius * (($i + 1) / $points); + $x1 = ($rad1 * cos($theta)) + $x_axis; + $y1 = ($rad1 * sin($theta )) + $y_axis; + imageline($im, $x, $y, $x1, $y1, $grid_color); + $theta = $theta - $thetac; + } + + // ----------------------------------- + // Write the text + // ----------------------------------- + + $use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE; + + if ($use_font == FALSE) + { + $font_size = 5; + $x = rand(0, $img_width/($length/3)); + $y = 0; + } + else + { + $font_size = 16; + $x = rand(0, $img_width/($length/1.5)); + $y = $font_size+2; + } + + for ($i = 0; $i < strlen($word); $i++) + { + if ($use_font == FALSE) + { + $y = rand(0 , $img_height/2); + imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color); + $x += ($font_size*2); + } + else + { + $y = rand($img_height/2, $img_height-3); + imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1)); + $x += $font_size; + } + } + + + // ----------------------------------- + // Create the border + // ----------------------------------- + + imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color); + + // ----------------------------------- + // Generate the image + // ----------------------------------- + + $img_name = $now.'.jpg'; + + ImageJPEG($im, $img_path.$img_name); + + $img = "\""; + + ImageDestroy($im); + + return array('word' => $word, 'time' => $now, 'image' => $img); +} + +?> \ No newline at end of file diff --git a/system/plugins/index.html b/system/plugins/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/plugins/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/plugins/js_calendar_pi.php b/system/plugins/js_calendar_pi.php new file mode 100755 index 0000000..86270ca --- /dev/null +++ b/system/plugins/js_calendar_pi.php @@ -0,0 +1,627 @@ +load->plugin('js_calendar'); + +Once loaded you'll add the calendar script to the of your page like this: + + + +The above function will be passed the name of your form. + +Then to show the actual calendar you'll do this: + + +

    + +

    Today

    +
    + + +Note: The first parameter is the name of the field containing your date, the second parameter contains the "now" time, +and the third tells the calendar whether to highlight the current day or not. + +Lastly, you'll need some CSS for your calendar: + +.calendar { + border: 1px #6975A3 solid; + background-color: transparent; +} +.calheading { + background-color: #7C8BC0; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + font-weight: bold; + text-align: center; +} +.calnavleft { + background-color: #7C8BC0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + font-weight: bold; + color: #fff; + padding: 4px; + cursor: pointer; +} +.calnavright { + background-color: #7C8BC0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + font-weight: bold; + color: #fff; + text-align: right; + padding: 4px; + cursor: pointer; +} +.caldayheading { + background-color: #000; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 10px; + text-align: center; + padding: 6px 2px 6px 2px; +} +.caldaycells{ + color: #000; + background-color: #D1D7E6; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + text-align: center; + padding: 4px; + border: 1px #E0E5F1 solid; + cursor: pointer; +} +.caldaycellhover{ + color: #fff; + background-color: #B3BCD4; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + text-align: center; + padding: 4px; + border: 1px #B3BCD4 solid; + cursor: pointer; +} +.caldayselected{ + background-color: #737FAC; + color: #fff; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + font-weight: bold; + text-align: center; + border: 1px #566188 solid; + padding: 3px; + cursor: pointer; +} +.calblanktop { + background-color: #fff; + padding: 4px; +} +.calblankbot { + background-color: #fff; + padding: 4px; +} + + +*/ + +function js_calendar_script($form_name = 'entryform') +{ +$CI =& get_instance(); +$CI->load->language('calendar'); +ob_start(); +?> + + + var '.$field_id.' = new calendar("'.$field_id.'", '.$time.', '.(($highlight == TRUE) ? 'true' : 'false').'); + document.write('.$field_id.'.write()); + '; +} + +?> \ No newline at end of file diff --git a/system/scaffolding/.svn/all-wcprops b/system/scaffolding/.svn/all-wcprops new file mode 100644 index 0000000..ca4ce68 --- /dev/null +++ b/system/scaffolding/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 41 +/svn/!svn/ver/18/trunk/system/scaffolding +END +Scaffolding.php +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/scaffolding/Scaffolding.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/18/trunk/system/scaffolding/index.html +END diff --git a/system/scaffolding/.svn/entries b/system/scaffolding/.svn/entries new file mode 100644 index 0000000..119bb81 --- /dev/null +++ b/system/scaffolding/.svn/entries @@ -0,0 +1,102 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/scaffolding +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +images +dir + +Scaffolding.php +file + + + + +2009-09-15T00:17:42.000000Z +124549cd8da0a2bbd13561f3d01fd20a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +7737 + +index.html +file + + + + +2009-09-15T00:17:42.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +views +dir + diff --git a/system/scaffolding/.svn/prop-base/Scaffolding.php.svn-base b/system/scaffolding/.svn/prop-base/Scaffolding.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/.svn/prop-base/Scaffolding.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/.svn/prop-base/index.html.svn-base b/system/scaffolding/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/.svn/text-base/Scaffolding.php.svn-base b/system/scaffolding/.svn/text-base/Scaffolding.php.svn-base new file mode 100644 index 0000000..a977704 --- /dev/null +++ b/system/scaffolding/.svn/text-base/Scaffolding.php.svn-base @@ -0,0 +1,289 @@ +CI =& get_instance(); + + $this->CI->load->database("", FALSE, TRUE); + $this->CI->load->library('pagination'); + + // Turn off caching + $this->CI->db->cache_off(); + + /** + * Set the current table name + * This is done when initializing scaffolding: + * $this->load->scaffolding('table_name') + * + */ + $this->current_table = $db_table; + + /** + * Set the path to the "view" files + * We'll manually override the "view" path so that + * the load->view function knows where to look. + */ + + $this->CI->load->_ci_view_path = BASEPATH.'scaffolding/views/'; + + // Set the base URL + $this->base_url = $this->CI->config->site_url().'/'.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'both'); + $this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'leading'); + + // Set a few globals + $data = array( + 'image_url' => $this->CI->config->system_url().'scaffolding/images/', + 'base_uri' => $this->base_uri, + 'base_url' => $this->base_url, + 'title' => $this->current_table + ); + + $this->CI->load->vars($data); + + // Load the language file and create variables + $this->lang = $this->CI->load->scaffold_language('scaffolding', '', TRUE); + $this->CI->load->vars($this->lang); + + // Load the helper files we plan to use + $this->CI->load->helper(array('url', 'form')); + + + log_message('debug', 'Scaffolding Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * "Add" Page + * + * Shows a form representing the currently selected DB + * so that data can be inserted + * + * @access public + * @return string the HTML "add" page + */ + function add() + { + $data = array( + 'title' => ( ! isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'], + 'fields' => $this->CI->db->field_data($this->current_table), + 'action' => $this->base_uri.'/insert' + ); + + $this->CI->load->view('add', $data); + } + + // -------------------------------------------------------------------- + + /** + * Insert the data + * + * @access public + * @return void redirects to the view page + */ + function insert() + { + if ($this->CI->db->insert($this->current_table, $_POST) === FALSE) + { + $this->add(); + } + else + { + redirect($this->base_uri.'/view/'); + } + } + + // -------------------------------------------------------------------- + + /** + * "View" Page + * + * Shows a table containing the data in the currently + * selected DB + * + * @access public + * @return string the HTML "view" page + */ + function view() + { + // Fetch the total number of DB rows + $total_rows = $this->CI->db->count_all($this->current_table); + + if ($total_rows < 1) + { + return $this->CI->load->view('no_data'); + } + + // Set the query limit/offset + $per_page = 20; + $offset = $this->CI->uri->segment(4, 0); + + // Run the query + $query = $this->CI->db->get($this->current_table, $per_page, $offset); + + // Now let's get the field names + $fields = $this->CI->db->list_fields($this->current_table); + + // We assume that the column in the first position is the primary field. + $primary = current($fields); + + // Pagination! + $this->CI->pagination->initialize( + array( + 'base_url' => $this->base_url.'/view', + 'total_rows' => $total_rows, + 'per_page' => $per_page, + 'uri_segment' => 4, + 'full_tag_open' => '

    ', + 'full_tag_close' => '

    ' + ) + ); + + $data = array( + 'title' => ( ! isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'], + 'query' => $query, + 'fields' => $fields, + 'primary' => $primary, + 'paginate' => $this->CI->pagination->create_links() + ); + + $this->CI->load->view('view', $data); + } + + // -------------------------------------------------------------------- + + /** + * "Edit" Page + * + * Shows a form representing the currently selected DB + * so that data can be edited + * + * @access public + * @return string the HTML "edit" page + */ + function edit() + { + if (FALSE === ($id = $this->CI->uri->segment(4))) + { + return $this->view(); + } + + // Fetch the primary field name + $primary = $this->CI->db->primary($this->current_table); + + // Run the query + $query = $this->CI->db->get_where($this->current_table, array($primary => $id)); + + $data = array( + 'title' => ( ! isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'], + 'fields' => $query->field_data(), + 'query' => $query->row(), + 'action' => $this->base_uri.'/update/'.$this->CI->uri->segment(4) + ); + + $this->CI->load->view('edit', $data); + } + + // -------------------------------------------------------------------- + + /** + * Update + * + * @access public + * @return void redirects to the view page + */ + function update() + { + // Fetch the primary key + $primary = $this->CI->db->primary($this->current_table); + + // Now do the query + $this->CI->db->update($this->current_table, $_POST, array($primary => $this->CI->uri->segment(4))); + + redirect($this->base_uri.'/view/'); + } + + // -------------------------------------------------------------------- + + /** + * Delete Confirmation + * + * @access public + * @return string the HTML "delete confirm" page + */ + function delete() + { + if ( ! isset($this->lang['scaff_del_confirm'])) + { + $message = 'Are you sure you want to delete the following row: '.$this->CI->uri->segment(4); + } + else + { + $message = $this->lang['scaff_del_confirm'].' '.$this->CI->uri->segment(4); + } + + $data = array( + 'title' => ( ! isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'], + 'message' => $message, + 'no' => anchor(array($this->base_uri, 'view'), ( ! isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']), + 'yes' => anchor(array($this->base_uri, 'do_delete', $this->CI->uri->segment(4)), ( ! isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes']) + ); + + $this->CI->load->view('delete', $data); + } + + // -------------------------------------------------------------------- + + /** + * Delete + * + * @access public + * @return void redirects to the view page + */ + function do_delete() + { + // Fetch the primary key + $primary = $this->CI->db->primary($this->current_table); + + // Now do the query + $this->CI->db->where($primary, $this->CI->uri->segment(4)); + $this->CI->db->delete($this->current_table); + + header("Refresh:0;url=".site_url(array($this->base_uri, 'view'))); + exit; + } + +} +?> \ No newline at end of file diff --git a/system/scaffolding/.svn/text-base/index.html.svn-base b/system/scaffolding/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/Scaffolding.php b/system/scaffolding/Scaffolding.php new file mode 100755 index 0000000..a977704 --- /dev/null +++ b/system/scaffolding/Scaffolding.php @@ -0,0 +1,289 @@ +CI =& get_instance(); + + $this->CI->load->database("", FALSE, TRUE); + $this->CI->load->library('pagination'); + + // Turn off caching + $this->CI->db->cache_off(); + + /** + * Set the current table name + * This is done when initializing scaffolding: + * $this->load->scaffolding('table_name') + * + */ + $this->current_table = $db_table; + + /** + * Set the path to the "view" files + * We'll manually override the "view" path so that + * the load->view function knows where to look. + */ + + $this->CI->load->_ci_view_path = BASEPATH.'scaffolding/views/'; + + // Set the base URL + $this->base_url = $this->CI->config->site_url().'/'.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'both'); + $this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'leading'); + + // Set a few globals + $data = array( + 'image_url' => $this->CI->config->system_url().'scaffolding/images/', + 'base_uri' => $this->base_uri, + 'base_url' => $this->base_url, + 'title' => $this->current_table + ); + + $this->CI->load->vars($data); + + // Load the language file and create variables + $this->lang = $this->CI->load->scaffold_language('scaffolding', '', TRUE); + $this->CI->load->vars($this->lang); + + // Load the helper files we plan to use + $this->CI->load->helper(array('url', 'form')); + + + log_message('debug', 'Scaffolding Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * "Add" Page + * + * Shows a form representing the currently selected DB + * so that data can be inserted + * + * @access public + * @return string the HTML "add" page + */ + function add() + { + $data = array( + 'title' => ( ! isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'], + 'fields' => $this->CI->db->field_data($this->current_table), + 'action' => $this->base_uri.'/insert' + ); + + $this->CI->load->view('add', $data); + } + + // -------------------------------------------------------------------- + + /** + * Insert the data + * + * @access public + * @return void redirects to the view page + */ + function insert() + { + if ($this->CI->db->insert($this->current_table, $_POST) === FALSE) + { + $this->add(); + } + else + { + redirect($this->base_uri.'/view/'); + } + } + + // -------------------------------------------------------------------- + + /** + * "View" Page + * + * Shows a table containing the data in the currently + * selected DB + * + * @access public + * @return string the HTML "view" page + */ + function view() + { + // Fetch the total number of DB rows + $total_rows = $this->CI->db->count_all($this->current_table); + + if ($total_rows < 1) + { + return $this->CI->load->view('no_data'); + } + + // Set the query limit/offset + $per_page = 20; + $offset = $this->CI->uri->segment(4, 0); + + // Run the query + $query = $this->CI->db->get($this->current_table, $per_page, $offset); + + // Now let's get the field names + $fields = $this->CI->db->list_fields($this->current_table); + + // We assume that the column in the first position is the primary field. + $primary = current($fields); + + // Pagination! + $this->CI->pagination->initialize( + array( + 'base_url' => $this->base_url.'/view', + 'total_rows' => $total_rows, + 'per_page' => $per_page, + 'uri_segment' => 4, + 'full_tag_open' => '

    ', + 'full_tag_close' => '

    ' + ) + ); + + $data = array( + 'title' => ( ! isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'], + 'query' => $query, + 'fields' => $fields, + 'primary' => $primary, + 'paginate' => $this->CI->pagination->create_links() + ); + + $this->CI->load->view('view', $data); + } + + // -------------------------------------------------------------------- + + /** + * "Edit" Page + * + * Shows a form representing the currently selected DB + * so that data can be edited + * + * @access public + * @return string the HTML "edit" page + */ + function edit() + { + if (FALSE === ($id = $this->CI->uri->segment(4))) + { + return $this->view(); + } + + // Fetch the primary field name + $primary = $this->CI->db->primary($this->current_table); + + // Run the query + $query = $this->CI->db->get_where($this->current_table, array($primary => $id)); + + $data = array( + 'title' => ( ! isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'], + 'fields' => $query->field_data(), + 'query' => $query->row(), + 'action' => $this->base_uri.'/update/'.$this->CI->uri->segment(4) + ); + + $this->CI->load->view('edit', $data); + } + + // -------------------------------------------------------------------- + + /** + * Update + * + * @access public + * @return void redirects to the view page + */ + function update() + { + // Fetch the primary key + $primary = $this->CI->db->primary($this->current_table); + + // Now do the query + $this->CI->db->update($this->current_table, $_POST, array($primary => $this->CI->uri->segment(4))); + + redirect($this->base_uri.'/view/'); + } + + // -------------------------------------------------------------------- + + /** + * Delete Confirmation + * + * @access public + * @return string the HTML "delete confirm" page + */ + function delete() + { + if ( ! isset($this->lang['scaff_del_confirm'])) + { + $message = 'Are you sure you want to delete the following row: '.$this->CI->uri->segment(4); + } + else + { + $message = $this->lang['scaff_del_confirm'].' '.$this->CI->uri->segment(4); + } + + $data = array( + 'title' => ( ! isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'], + 'message' => $message, + 'no' => anchor(array($this->base_uri, 'view'), ( ! isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']), + 'yes' => anchor(array($this->base_uri, 'do_delete', $this->CI->uri->segment(4)), ( ! isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes']) + ); + + $this->CI->load->view('delete', $data); + } + + // -------------------------------------------------------------------- + + /** + * Delete + * + * @access public + * @return void redirects to the view page + */ + function do_delete() + { + // Fetch the primary key + $primary = $this->CI->db->primary($this->current_table); + + // Now do the query + $this->CI->db->where($primary, $this->CI->uri->segment(4)); + $this->CI->db->delete($this->current_table); + + header("Refresh:0;url=".site_url(array($this->base_uri, 'view'))); + exit; + } + +} +?> \ No newline at end of file diff --git a/system/scaffolding/images/.svn/all-wcprops b/system/scaffolding/images/.svn/all-wcprops new file mode 100644 index 0000000..4423152 --- /dev/null +++ b/system/scaffolding/images/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/!svn/ver/18/trunk/system/scaffolding/images +END +logo.jpg +K 25 +svn:wc:ra_dav:version-url +V 57 +/svn/!svn/ver/18/trunk/system/scaffolding/images/logo.jpg +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/scaffolding/images/index.html +END +background.jpg +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/18/trunk/system/scaffolding/images/background.jpg +END diff --git a/system/scaffolding/images/.svn/entries b/system/scaffolding/images/.svn/entries new file mode 100644 index 0000000..495eec3 --- /dev/null +++ b/system/scaffolding/images/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/scaffolding/images +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +logo.jpg +file + + + + +2009-09-15T00:17:41.000000Z +52057b743d9a2b3d15a84275dc5bb228 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +4518 + +index.html +file + + + + +2009-09-15T00:17:41.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +background.jpg +file + + + + +2009-09-15T00:17:41.000000Z +f9a765e261c825030aa386f03d3dd952 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +410 + diff --git a/system/scaffolding/images/.svn/prop-base/background.jpg.svn-base b/system/scaffolding/images/.svn/prop-base/background.jpg.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/system/scaffolding/images/.svn/prop-base/background.jpg.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/scaffolding/images/.svn/prop-base/index.html.svn-base b/system/scaffolding/images/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/images/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/images/.svn/prop-base/logo.jpg.svn-base b/system/scaffolding/images/.svn/prop-base/logo.jpg.svn-base new file mode 100644 index 0000000..dbc918b --- /dev/null +++ b/system/scaffolding/images/.svn/prop-base/logo.jpg.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/system/scaffolding/images/.svn/text-base/background.jpg.svn-base b/system/scaffolding/images/.svn/text-base/background.jpg.svn-base new file mode 100644 index 0000000..9d5bdce Binary files /dev/null and b/system/scaffolding/images/.svn/text-base/background.jpg.svn-base differ diff --git a/system/scaffolding/images/.svn/text-base/index.html.svn-base b/system/scaffolding/images/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/images/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/images/.svn/text-base/logo.jpg.svn-base b/system/scaffolding/images/.svn/text-base/logo.jpg.svn-base new file mode 100644 index 0000000..d6cc9a7 Binary files /dev/null and b/system/scaffolding/images/.svn/text-base/logo.jpg.svn-base differ diff --git a/system/scaffolding/images/background.jpg b/system/scaffolding/images/background.jpg new file mode 100755 index 0000000..9d5bdce Binary files /dev/null and b/system/scaffolding/images/background.jpg differ diff --git a/system/scaffolding/images/index.html b/system/scaffolding/images/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/images/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/images/logo.jpg b/system/scaffolding/images/logo.jpg new file mode 100755 index 0000000..d6cc9a7 Binary files /dev/null and b/system/scaffolding/images/logo.jpg differ diff --git a/system/scaffolding/index.html b/system/scaffolding/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/views/.svn/all-wcprops b/system/scaffolding/views/.svn/all-wcprops new file mode 100644 index 0000000..ce940d2 --- /dev/null +++ b/system/scaffolding/views/.svn/all-wcprops @@ -0,0 +1,59 @@ +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/18/trunk/system/scaffolding/views +END +stylesheet.css +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/18/trunk/system/scaffolding/views/stylesheet.css +END +view.php +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/!svn/ver/18/trunk/system/scaffolding/views/view.php +END +footer.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/scaffolding/views/footer.php +END +delete.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/scaffolding/views/delete.php +END +index.html +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/scaffolding/views/index.html +END +no_data.php +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/18/trunk/system/scaffolding/views/no_data.php +END +edit.php +K 25 +svn:wc:ra_dav:version-url +V 56 +/svn/!svn/ver/18/trunk/system/scaffolding/views/edit.php +END +add.php +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/18/trunk/system/scaffolding/views/add.php +END +header.php +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/18/trunk/system/scaffolding/views/header.php +END diff --git a/system/scaffolding/views/.svn/entries b/system/scaffolding/views/.svn/entries new file mode 100644 index 0000000..181a9a2 --- /dev/null +++ b/system/scaffolding/views/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/scaffolding/views +http://sweetcron.googlecode.com/svn + + + +2008-08-28T06:03:25.654136Z +18 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +stylesheet.css +file + + + + +2009-09-15T00:17:42.000000Z +c9f9b1dc2f608fb24ca933c6e27df54e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +1933 + +view.php +file + + + + +2009-09-15T00:17:42.000000Z +31e5931f9cb9624d6790f262a8dc3416 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +700 + +footer.php +file + + + + +2009-09-15T00:17:42.000000Z +4a02ed7bc2c32b4a2fbf47cb8ba1880e +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +242 + +delete.php +file + + + + +2009-09-15T00:17:42.000000Z +2178c8cee67ca09bb366363d884000f1 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +178 + +index.html +file + + + + +2009-09-15T00:17:42.000000Z +362a648cc43551584abe596372cb8da8 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +149 + +no_data.php +file + + + + +2009-09-15T00:17:42.000000Z +d028ab66b8a7bb2f3829b98c53b2d756 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +192 + +edit.php +file + + + + +2009-09-15T00:17:42.000000Z +2aeba6c188e90271523ff6cf6143297a +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +857 + +add.php +file + + + + +2009-09-15T00:17:42.000000Z +a4d6c1452ccd9784e63fcbabdac96e27 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +857 + +header.php +file + + + + +2009-09-15T00:17:42.000000Z +e16c25dde241d428476f3ffa85e713d7 +2008-08-28T06:03:25.654136Z +18 +yongfook +has-props + + + + + + + + + + + + + + + + + + + + +790 + diff --git a/system/scaffolding/views/.svn/prop-base/add.php.svn-base b/system/scaffolding/views/.svn/prop-base/add.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/add.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/delete.php.svn-base b/system/scaffolding/views/.svn/prop-base/delete.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/delete.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/edit.php.svn-base b/system/scaffolding/views/.svn/prop-base/edit.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/edit.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/footer.php.svn-base b/system/scaffolding/views/.svn/prop-base/footer.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/footer.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/header.php.svn-base b/system/scaffolding/views/.svn/prop-base/header.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/header.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/index.html.svn-base b/system/scaffolding/views/.svn/prop-base/index.html.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/index.html.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/no_data.php.svn-base b/system/scaffolding/views/.svn/prop-base/no_data.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/no_data.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/stylesheet.css.svn-base b/system/scaffolding/views/.svn/prop-base/stylesheet.css.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/stylesheet.css.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/prop-base/view.php.svn-base b/system/scaffolding/views/.svn/prop-base/view.php.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/system/scaffolding/views/.svn/prop-base/view.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/system/scaffolding/views/.svn/text-base/add.php.svn-base b/system/scaffolding/views/.svn/text-base/add.php.svn-base new file mode 100644 index 0000000..a65e3d7 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/add.php.svn-base @@ -0,0 +1,30 @@ +load->view('header'); ?> + +

    + + + + + + + +primary_key == 1) continue; ?> + + + + + type == 'blob'): ?> + + + + + + + +
    name; echo ' '.$field->default; ?>
    + + + + + +load->view('footer'); ?> diff --git a/system/scaffolding/views/.svn/text-base/delete.php.svn-base b/system/scaffolding/views/.svn/text-base/delete.php.svn-base new file mode 100644 index 0000000..75a5c21 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/delete.php.svn-base @@ -0,0 +1,7 @@ +load->view('header'); ?> + +

    + +

      |   + +load->view('footer'); ?> diff --git a/system/scaffolding/views/.svn/text-base/edit.php.svn-base b/system/scaffolding/views/.svn/text-base/edit.php.svn-base new file mode 100644 index 0000000..a7d65c6 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/edit.php.svn-base @@ -0,0 +1,31 @@ +load->view('header'); ?> + + +

    + + + + + + + +primary_key == 1) continue; ?> + + + + + type == 'blob'): ?> + + + + + + + +
    name; ?>
    + + + + + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/scaffolding/views/.svn/text-base/footer.php.svn-base b/system/scaffolding/views/.svn/text-base/footer.php.svn-base new file mode 100644 index 0000000..a287664 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/footer.php.svn-base @@ -0,0 +1,10 @@ + +
    + + + + + \ No newline at end of file diff --git a/system/scaffolding/views/.svn/text-base/header.php.svn-base b/system/scaffolding/views/.svn/text-base/header.php.svn-base new file mode 100644 index 0000000..50f234a --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/header.php.svn-base @@ -0,0 +1,29 @@ + + + + +<?php echo $title; ?> + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/system/scaffolding/views/.svn/text-base/index.html.svn-base b/system/scaffolding/views/.svn/text-base/index.html.svn-base new file mode 100644 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/index.html.svn-base @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/views/.svn/text-base/no_data.php.svn-base b/system/scaffolding/views/.svn/text-base/no_data.php.svn-base new file mode 100644 index 0000000..dca477e --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/no_data.php.svn-base @@ -0,0 +1,6 @@ +load->view('header'); ?> + +

    +

    + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/scaffolding/views/.svn/text-base/stylesheet.css.svn-base b/system/scaffolding/views/.svn/text-base/stylesheet.css.svn-base new file mode 100644 index 0000000..e2e3aa5 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/stylesheet.css.svn-base @@ -0,0 +1,143 @@ +body { + margin: 0; + padding: 0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + color: #4F5155; + background: #fff url(background.jpg) repeat-x left top; +} + +a { + color: #8B0D00; + background-color: transparent; + text-decoration: none; + font-weight: bold; +} + +a:visited { + color: #8B0D00; + background-color: transparent; + text-decoration: none; +} + +a:hover { + color: #000; + text-decoration: none; + background-color: transparent; +} + + +#header { + margin: 0; + padding: 0; +} + +#header_left { + background-color: transparent; + float: left; + padding: 21px 0 0 32px; + margin: 0 +} + +#header_right { + background-color: transparent; + float: right; + text-align: right; + padding: 35px 50px 20px 0; + margin: 0 +} + +#footer { + margin: 20px 0 15px 0; + padding: 0; +} + +#footer p { + font-size: 10px; + color: #999; + text-align: center; +} + +#outer { + margin: 30px 40px 0 40px; +} + +img { + padding:0; + border: 0; + margin: 0; +} + +.nopad { + padding:0; + border: 0; + margin: 0; +} + +table { + background-color: #efefef; +} + +th { + background-color: #eee; + font-weight: bold; + padding: 6px; + text-align: left; +} + +td { + background-color: #fff; + padding: 6px; +} + + +form { + margin: 0; + padding: 0; +} + +.input { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + font-size: 11px; + height: 2em; + padding: 0; + margin: 0; +} + +.textarea { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 12px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + padding: 0; + margin: 0; +} + +.select { + background-color: #fff; + font-size: 11px; + font-weight: normal; + color: #333; + padding: 0; + margin: 0 0 3px 0; +} + +.checkbox { + background-color: transparent; + padding: 0; + border: 0; +} + +.submit { + background-color: #8B0D00; + color: transparent; + font-weight: normal; + border: 1px solid #000; + margin: 6px 0 0 0; + padding: 1px 5px 1px 5px; +} diff --git a/system/scaffolding/views/.svn/text-base/view.php.svn-base b/system/scaffolding/views/.svn/text-base/view.php.svn-base new file mode 100644 index 0000000..e7abda6 --- /dev/null +++ b/system/scaffolding/views/.svn/text-base/view.php.svn-base @@ -0,0 +1,25 @@ +load->view('header'); ?> + + + + + + + + + + +result() as $row): ?> + + + + + + + + +
    EditDelete
     $primary), $scaff_edit); ?> $primary), $scaff_delete); ?>$field);?>
    + + + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/scaffolding/views/add.php b/system/scaffolding/views/add.php new file mode 100755 index 0000000..a65e3d7 --- /dev/null +++ b/system/scaffolding/views/add.php @@ -0,0 +1,30 @@ +load->view('header'); ?> + +

    + + + + + + + +primary_key == 1) continue; ?> + + + + + type == 'blob'): ?> + + + + + + + +
    name; echo ' '.$field->default; ?>
    + + + + + +load->view('footer'); ?> diff --git a/system/scaffolding/views/delete.php b/system/scaffolding/views/delete.php new file mode 100755 index 0000000..75a5c21 --- /dev/null +++ b/system/scaffolding/views/delete.php @@ -0,0 +1,7 @@ +load->view('header'); ?> + +

    + +

      |   + +load->view('footer'); ?> diff --git a/system/scaffolding/views/edit.php b/system/scaffolding/views/edit.php new file mode 100755 index 0000000..a7d65c6 --- /dev/null +++ b/system/scaffolding/views/edit.php @@ -0,0 +1,31 @@ +load->view('header'); ?> + + +

    + + + + + + + +primary_key == 1) continue; ?> + + + + + type == 'blob'): ?> + + + + + + + +
    name; ?>
    + + + + + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/scaffolding/views/footer.php b/system/scaffolding/views/footer.php new file mode 100755 index 0000000..a287664 --- /dev/null +++ b/system/scaffolding/views/footer.php @@ -0,0 +1,10 @@ + +
    + + + + + \ No newline at end of file diff --git a/system/scaffolding/views/header.php b/system/scaffolding/views/header.php new file mode 100755 index 0000000..50f234a --- /dev/null +++ b/system/scaffolding/views/header.php @@ -0,0 +1,29 @@ + + + + +<?php echo $title; ?> + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/system/scaffolding/views/index.html b/system/scaffolding/views/index.html new file mode 100755 index 0000000..5a1f5d6 --- /dev/null +++ b/system/scaffolding/views/index.html @@ -0,0 +1,15 @@ + + + + +403 Forbidden + + + + + +

    Directory access is forbidden.

    + + + + \ No newline at end of file diff --git a/system/scaffolding/views/no_data.php b/system/scaffolding/views/no_data.php new file mode 100755 index 0000000..dca477e --- /dev/null +++ b/system/scaffolding/views/no_data.php @@ -0,0 +1,6 @@ +load->view('header'); ?> + +

    +

    + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/scaffolding/views/stylesheet.css b/system/scaffolding/views/stylesheet.css new file mode 100755 index 0000000..e2e3aa5 --- /dev/null +++ b/system/scaffolding/views/stylesheet.css @@ -0,0 +1,143 @@ +body { + margin: 0; + padding: 0; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + color: #4F5155; + background: #fff url(background.jpg) repeat-x left top; +} + +a { + color: #8B0D00; + background-color: transparent; + text-decoration: none; + font-weight: bold; +} + +a:visited { + color: #8B0D00; + background-color: transparent; + text-decoration: none; +} + +a:hover { + color: #000; + text-decoration: none; + background-color: transparent; +} + + +#header { + margin: 0; + padding: 0; +} + +#header_left { + background-color: transparent; + float: left; + padding: 21px 0 0 32px; + margin: 0 +} + +#header_right { + background-color: transparent; + float: right; + text-align: right; + padding: 35px 50px 20px 0; + margin: 0 +} + +#footer { + margin: 20px 0 15px 0; + padding: 0; +} + +#footer p { + font-size: 10px; + color: #999; + text-align: center; +} + +#outer { + margin: 30px 40px 0 40px; +} + +img { + padding:0; + border: 0; + margin: 0; +} + +.nopad { + padding:0; + border: 0; + margin: 0; +} + +table { + background-color: #efefef; +} + +th { + background-color: #eee; + font-weight: bold; + padding: 6px; + text-align: left; +} + +td { + background-color: #fff; + padding: 6px; +} + + +form { + margin: 0; + padding: 0; +} + +.input { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + font-size: 11px; + height: 2em; + padding: 0; + margin: 0; +} + +.textarea { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 12px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + padding: 0; + margin: 0; +} + +.select { + background-color: #fff; + font-size: 11px; + font-weight: normal; + color: #333; + padding: 0; + margin: 0 0 3px 0; +} + +.checkbox { + background-color: transparent; + padding: 0; + border: 0; +} + +.submit { + background-color: #8B0D00; + color: transparent; + font-weight: normal; + border: 1px solid #000; + margin: 6px 0 0 0; + padding: 1px 5px 1px 5px; +} diff --git a/system/scaffolding/views/view.php b/system/scaffolding/views/view.php new file mode 100755 index 0000000..e7abda6 --- /dev/null +++ b/system/scaffolding/views/view.php @@ -0,0 +1,25 @@ +load->view('header'); ?> + + + + + + + + + + +result() as $row): ?> + + + + + + + + +
    EditDelete
     $primary), $scaff_edit); ?> $primary), $scaff_delete); ?>$field);?>
    + + + +load->view('footer'); ?> \ No newline at end of file diff --git a/system/utilities/.svn/all-wcprops b/system/utilities/.svn/all-wcprops new file mode 100644 index 0000000..ddbe302 --- /dev/null +++ b/system/utilities/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 39 +/svn/!svn/ver/74/trunk/system/utilities +END +install.sql +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/74/trunk/system/utilities/install.sql +END diff --git a/system/utilities/.svn/entries b/system/utilities/.svn/entries new file mode 100644 index 0000000..37f3d62 --- /dev/null +++ b/system/utilities/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +124 +http://sweetcron.googlecode.com/svn/trunk/system/utilities +http://sweetcron.googlecode.com/svn + + + +2008-09-03T13:40:42.593902Z +74 +yongfook + + + + + + + + + + + + + + +51b50d7d-0b4b-0410-974b-f188aa86c7d9 + +install.sql +file + + + + +2009-09-15T00:18:18.000000Z +1372cf1d75d67f64e0dfe17f7b535a78 +2008-09-03T13:40:42.593902Z +74 +yongfook + + + + + + + + + + + + + + + + + + + + + +2477 + diff --git a/system/utilities/.svn/text-base/install.sql.svn-base b/system/utilities/.svn/text-base/install.sql.svn-base new file mode 100644 index 0000000..13d6f79 --- /dev/null +++ b/system/utilities/.svn/text-base/install.sql.svn-base @@ -0,0 +1,62 @@ +CREATE TABLE `%DB_PREFIX%feeds` ( + `feed_id` int(11) NOT NULL auto_increment, + `feed_title` text collate utf8_unicode_ci NOT NULL, + `feed_icon` varchar(255) collate utf8_unicode_ci NOT NULL, + `feed_url` text collate utf8_unicode_ci NOT NULL, + `feed_data` longtext collate utf8_unicode_ci NOT NULL, + `feed_status` varchar(20) collate utf8_unicode_ci NOT NULL default 'active', + `feed_domain` varchar(255) collate utf8_unicode_ci NOT NULL, + PRIMARY KEY (`feed_id`), + KEY `feed_status` (`feed_status`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE `%DB_PREFIX%items` ( + `ID` bigint(20) unsigned NOT NULL auto_increment, + `item_date` bigint(20) NOT NULL, + `item_content` longtext NOT NULL, + `item_title` text NOT NULL, + `item_permalink` varchar(255) NOT NULL, + `item_status` varchar(20) NOT NULL default 'publish', + `item_name` varchar(200) NOT NULL default '', + `item_parent` bigint(20) NOT NULL default '0', + `item_data` longtext NOT NULL, + `item_feed_id` int(11) NOT NULL, + PRIMARY KEY (`ID`), + KEY `item_name` (`item_name`), + KEY `type_status_date` (`item_status`,`item_date`,`ID`), + FULLTEXT KEY `item_title` (`item_title`,`item_content`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%options` ( + `option_id` bigint(20) NOT NULL auto_increment, + `option_name` varchar(64) NOT NULL default '', + `option_value` longtext NOT NULL, + `autoload` varchar(20) NOT NULL default 'yes', + PRIMARY KEY (`option_id`,`option_name`), + KEY `option_name` (`option_name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%tags` ( + `tag_id` bigint(20) NOT NULL auto_increment, + `name` varchar(55) NOT NULL default '', + `slug` varchar(200) NOT NULL default '', + `count` bigint(20) NOT NULL default '0', + PRIMARY KEY (`tag_id`), + UNIQUE KEY `slug` (`slug`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%tag_relationships` ( + `item_id` bigint(20) NOT NULL default '0', + `tag_id` bigint(20) NOT NULL default '0', + PRIMARY KEY (`item_id`,`tag_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%users` ( + `ID` bigint(20) unsigned NOT NULL auto_increment, + `user_login` varchar(60) NOT NULL default '', + `user_pass` varchar(64) NOT NULL default '', + `user_email` varchar(100) NOT NULL default '', + `user_activation_key` varchar(60) NOT NULL default '', + PRIMARY KEY (`ID`), + KEY `user_login_key` (`user_login`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/system/utilities/install.sql b/system/utilities/install.sql new file mode 100644 index 0000000..13d6f79 --- /dev/null +++ b/system/utilities/install.sql @@ -0,0 +1,62 @@ +CREATE TABLE `%DB_PREFIX%feeds` ( + `feed_id` int(11) NOT NULL auto_increment, + `feed_title` text collate utf8_unicode_ci NOT NULL, + `feed_icon` varchar(255) collate utf8_unicode_ci NOT NULL, + `feed_url` text collate utf8_unicode_ci NOT NULL, + `feed_data` longtext collate utf8_unicode_ci NOT NULL, + `feed_status` varchar(20) collate utf8_unicode_ci NOT NULL default 'active', + `feed_domain` varchar(255) collate utf8_unicode_ci NOT NULL, + PRIMARY KEY (`feed_id`), + KEY `feed_status` (`feed_status`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE `%DB_PREFIX%items` ( + `ID` bigint(20) unsigned NOT NULL auto_increment, + `item_date` bigint(20) NOT NULL, + `item_content` longtext NOT NULL, + `item_title` text NOT NULL, + `item_permalink` varchar(255) NOT NULL, + `item_status` varchar(20) NOT NULL default 'publish', + `item_name` varchar(200) NOT NULL default '', + `item_parent` bigint(20) NOT NULL default '0', + `item_data` longtext NOT NULL, + `item_feed_id` int(11) NOT NULL, + PRIMARY KEY (`ID`), + KEY `item_name` (`item_name`), + KEY `type_status_date` (`item_status`,`item_date`,`ID`), + FULLTEXT KEY `item_title` (`item_title`,`item_content`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%options` ( + `option_id` bigint(20) NOT NULL auto_increment, + `option_name` varchar(64) NOT NULL default '', + `option_value` longtext NOT NULL, + `autoload` varchar(20) NOT NULL default 'yes', + PRIMARY KEY (`option_id`,`option_name`), + KEY `option_name` (`option_name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%tags` ( + `tag_id` bigint(20) NOT NULL auto_increment, + `name` varchar(55) NOT NULL default '', + `slug` varchar(200) NOT NULL default '', + `count` bigint(20) NOT NULL default '0', + PRIMARY KEY (`tag_id`), + UNIQUE KEY `slug` (`slug`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%tag_relationships` ( + `item_id` bigint(20) NOT NULL default '0', + `tag_id` bigint(20) NOT NULL default '0', + PRIMARY KEY (`item_id`,`tag_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `%DB_PREFIX%users` ( + `ID` bigint(20) unsigned NOT NULL auto_increment, + `user_login` varchar(60) NOT NULL default '', + `user_pass` varchar(64) NOT NULL default '', + `user_email` varchar(100) NOT NULL default '', + `user_activation_key` varchar(60) NOT NULL default '', + PRIMARY KEY (`ID`), + KEY `user_login_key` (`user_login`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8;