Take two:
authorStephen Soltesz <soltesz@cs.princeton.edu>
Fri, 27 Feb 2009 21:05:30 +0000 (21:05 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Fri, 27 Feb 2009 21:05:30 +0000 (21:05 +0000)
Initial import of www-register-wizard module.  Pulled out of plcwww

193 files changed:
application/config/autoload.php [new file with mode: 0644]
application/config/config.php [new file with mode: 0644]
application/config/constants.php [new file with mode: 0644]
application/config/database.php [new file with mode: 0644]
application/config/hooks.php [new file with mode: 0644]
application/config/index.html [new file with mode: 0644]
application/config/mimes.php [new file with mode: 0644]
application/config/routes.php [new file with mode: 0644]
application/config/smileys.php [new file with mode: 0644]
application/config/user_agents.php [new file with mode: 0644]
application/controllers/conffile.php [new file with mode: 0644]
application/controllers/confirm.php [new file with mode: 0644]
application/controllers/download.php [new file with mode: 0644]
application/controllers/index.html [new file with mode: 0644]
application/controllers/register.php [new file with mode: 0644]
application/controllers/welcome.php [new file with mode: 0644]
application/errors/error_404.php [new file with mode: 0644]
application/errors/error_db.php [new file with mode: 0644]
application/errors/error_general.php [new file with mode: 0644]
application/errors/error_php.php [new file with mode: 0644]
application/errors/index.html [new file with mode: 0644]
application/helpers/index.html [new file with mode: 0644]
application/hooks/index.html [new file with mode: 0644]
application/index.html [new file with mode: 0644]
application/language/english/index.html [new file with mode: 0644]
application/libraries/index.html [new file with mode: 0644]
application/models/index.html [new file with mode: 0644]
application/views/AddConfFile.php [new file with mode: 0644]
application/views/ListConfFiles.php [new file with mode: 0644]
application/views/UpdateConfFile.php [new file with mode: 0644]
application/views/debug.php [new file with mode: 0644]
application/views/footer.php [new file with mode: 0644]
application/views/header.php [new file with mode: 0644]
application/views/index.html [new file with mode: 0644]
application/views/stage0.php [new file with mode: 0644]
application/views/stage1_pcu_choose.php [new file with mode: 0644]
application/views/stage2_pcu_confirm.php [new file with mode: 0644]
application/views/stage3_node_choose.php [new file with mode: 0644]
application/views/stage45_pcuport.php [new file with mode: 0644]
application/views/stage4_node_confirm.php [new file with mode: 0644]
application/views/stage5_bootimage.php [new file with mode: 0644]
application/views/stage6_download.php [new file with mode: 0644]
application/views/stage7_firstcontact.php [new file with mode: 0644]
application/views/stage8_rebootpcu.php [new file with mode: 0644]
application/views/stage9_complete.php [new file with mode: 0644]
application/views/welcome_message.php [new file with mode: 0644]
cache/index.html [new file with mode: 0644]
codeigniter/Base4.php [new file with mode: 0644]
codeigniter/Base5.php [new file with mode: 0644]
codeigniter/CodeIgniter.php [new file with mode: 0644]
codeigniter/Common.php [new file with mode: 0644]
codeigniter/Compat.php [new file with mode: 0644]
codeigniter/index.html [new file with mode: 0644]
database/DB.php [new file with mode: 0644]
database/DB_active_rec.php [new file with mode: 0644]
database/DB_cache.php [new file with mode: 0644]
database/DB_driver.php [new file with mode: 0644]
database/DB_forge.php [new file with mode: 0644]
database/DB_result.php [new file with mode: 0644]
database/DB_utility.php [new file with mode: 0644]
database/drivers/index.html [new file with mode: 0644]
database/drivers/mssql/index.html [new file with mode: 0644]
database/drivers/mssql/mssql_driver.php [new file with mode: 0644]
database/drivers/mssql/mssql_forge.php [new file with mode: 0644]
database/drivers/mssql/mssql_result.php [new file with mode: 0644]
database/drivers/mssql/mssql_utility.php [new file with mode: 0644]
database/drivers/mysql/index.html [new file with mode: 0644]
database/drivers/mysql/mysql_driver.php [new file with mode: 0644]
database/drivers/mysql/mysql_forge.php [new file with mode: 0644]
database/drivers/mysql/mysql_result.php [new file with mode: 0644]
database/drivers/mysql/mysql_utility.php [new file with mode: 0644]
database/drivers/mysqli/index.html [new file with mode: 0644]
database/drivers/mysqli/mysqli_driver.php [new file with mode: 0644]
database/drivers/mysqli/mysqli_forge.php [new file with mode: 0644]
database/drivers/mysqli/mysqli_result.php [new file with mode: 0644]
database/drivers/mysqli/mysqli_utility.php [new file with mode: 0644]
database/drivers/oci8/index.html [new file with mode: 0644]
database/drivers/oci8/oci8_driver.php [new file with mode: 0644]
database/drivers/oci8/oci8_forge.php [new file with mode: 0644]
database/drivers/oci8/oci8_result.php [new file with mode: 0644]
database/drivers/oci8/oci8_utility.php [new file with mode: 0644]
database/drivers/odbc/index.html [new file with mode: 0644]
database/drivers/odbc/odbc_driver.php [new file with mode: 0644]
database/drivers/odbc/odbc_forge.php [new file with mode: 0644]
database/drivers/odbc/odbc_result.php [new file with mode: 0644]
database/drivers/odbc/odbc_utility.php [new file with mode: 0644]
database/drivers/postgre/index.html [new file with mode: 0644]
database/drivers/postgre/postgre_driver.php [new file with mode: 0644]
database/drivers/postgre/postgre_forge.php [new file with mode: 0644]
database/drivers/postgre/postgre_result.php [new file with mode: 0644]
database/drivers/postgre/postgre_utility.php [new file with mode: 0644]
database/drivers/sqlite/index.html [new file with mode: 0644]
database/drivers/sqlite/sqlite_driver.php [new file with mode: 0644]
database/drivers/sqlite/sqlite_forge.php [new file with mode: 0644]
database/drivers/sqlite/sqlite_result.php [new file with mode: 0644]
database/drivers/sqlite/sqlite_utility.php [new file with mode: 0644]
database/index.html [new file with mode: 0644]
fonts/index.html [new file with mode: 0644]
fonts/texb.ttf [new file with mode: 0644]
helpers/array_helper.php [new file with mode: 0644]
helpers/compatibility_helper.php [new file with mode: 0644]
helpers/cookie_helper.php [new file with mode: 0644]
helpers/date_helper.php [new file with mode: 0644]
helpers/directory_helper.php [new file with mode: 0644]
helpers/download_helper.php [new file with mode: 0644]
helpers/email_helper.php [new file with mode: 0644]
helpers/file_helper.php [new file with mode: 0644]
helpers/form_helper.php [new file with mode: 0644]
helpers/html_helper.php [new file with mode: 0644]
helpers/index.html [new file with mode: 0644]
helpers/inflector_helper.php [new file with mode: 0644]
helpers/language_helper.php [new file with mode: 0644]
helpers/number_helper.php [new file with mode: 0644]
helpers/path_helper.php [new file with mode: 0644]
helpers/security_helper.php [new file with mode: 0644]
helpers/smiley_helper.php [new file with mode: 0644]
helpers/string_helper.php [new file with mode: 0644]
helpers/text_helper.php [new file with mode: 0644]
helpers/typography_helper.php [new file with mode: 0644]
helpers/url_helper.php [new file with mode: 0644]
helpers/xml_helper.php [new file with mode: 0644]
index.php [new file with mode: 0644]
language/english/calendar_lang.php [new file with mode: 0644]
language/english/date_lang.php [new file with mode: 0644]
language/english/db_lang.php [new file with mode: 0644]
language/english/email_lang.php [new file with mode: 0644]
language/english/form_validation_lang.php [new file with mode: 0644]
language/english/ftp_lang.php [new file with mode: 0644]
language/english/imglib_lang.php [new file with mode: 0644]
language/english/index.html [new file with mode: 0644]
language/english/number_lang.php [new file with mode: 0644]
language/english/profiler_lang.php [new file with mode: 0644]
language/english/scaffolding_lang.php [new file with mode: 0644]
language/english/unit_test_lang.php [new file with mode: 0644]
language/english/upload_lang.php [new file with mode: 0644]
language/english/validation_lang.php [new file with mode: 0644]
language/index.html [new file with mode: 0644]
libraries/Benchmark.php [new file with mode: 0644]
libraries/Calendar.php [new file with mode: 0644]
libraries/Config.php [new file with mode: 0644]
libraries/Controller.php [new file with mode: 0644]
libraries/Email.php [new file with mode: 0644]
libraries/Encrypt.php [new file with mode: 0644]
libraries/Exceptions.php [new file with mode: 0644]
libraries/Form_validation.php [new file with mode: 0644]
libraries/Ftp.php [new file with mode: 0644]
libraries/Hooks.php [new file with mode: 0644]
libraries/Image_lib.php [new file with mode: 0644]
libraries/Input.php [new file with mode: 0644]
libraries/Language.php [new file with mode: 0644]
libraries/Loader.php [new file with mode: 0644]
libraries/Log.php [new file with mode: 0644]
libraries/Model.php [new file with mode: 0644]
libraries/Output.php [new file with mode: 0644]
libraries/Pagination.php [new file with mode: 0644]
libraries/Parser.php [new file with mode: 0644]
libraries/Profiler.php [new file with mode: 0644]
libraries/Router.php [new file with mode: 0644]
libraries/Session.php [new file with mode: 0644]
libraries/Sha1.php [new file with mode: 0644]
libraries/Table.php [new file with mode: 0644]
libraries/Trackback.php [new file with mode: 0644]
libraries/Typography.php [new file with mode: 0644]
libraries/URI.php [new file with mode: 0644]
libraries/Unit_test.php [new file with mode: 0644]
libraries/Upload.php [new file with mode: 0644]
libraries/User_agent.php [new file with mode: 0644]
libraries/Validation.php [new file with mode: 0644]
libraries/Xmlrpc.php [new file with mode: 0644]
libraries/Xmlrpcs.php [new file with mode: 0644]
libraries/Zip.php [new file with mode: 0644]
libraries/index.html [new file with mode: 0644]
logs/index.html [new file with mode: 0644]
plugins/captcha_pi.php [new file with mode: 0644]
plugins/index.html [new file with mode: 0644]
plugins/js_calendar_pi.php [new file with mode: 0644]
rounded.css [new file with mode: 0644]
rounded.js [new file with mode: 0644]
scaffolding/Scaffolding.php [new file with mode: 0644]
scaffolding/images/background.jpg [new file with mode: 0644]
scaffolding/images/index.html [new file with mode: 0644]
scaffolding/images/logo.jpg [new file with mode: 0644]
scaffolding/index.html [new file with mode: 0644]
scaffolding/views/add.php [new file with mode: 0644]
scaffolding/views/delete.php [new file with mode: 0644]
scaffolding/views/edit.php [new file with mode: 0644]
scaffolding/views/footer.php [new file with mode: 0644]
scaffolding/views/header.php [new file with mode: 0644]
scaffolding/views/index.html [new file with mode: 0644]
scaffolding/views/no_data.php [new file with mode: 0644]
scaffolding/views/stylesheet.css [new file with mode: 0644]
scaffolding/views/view.php [new file with mode: 0644]
www-register-wizard.spec [new file with mode: 0755]

diff --git a/application/config/autoload.php b/application/config/autoload.php
new file mode 100644 (file)
index 0000000..b99ffe4
--- /dev/null
@@ -0,0 +1,127 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/*\r
+| -------------------------------------------------------------------\r
+| AUTO-LOADER\r
+| -------------------------------------------------------------------\r
+| This file specifies which systems should be loaded by default.\r
+|\r
+| In order to keep the framework as light-weight as possible only the\r
+| absolute minimal resources are loaded by default. For example,\r
+| the database is not connected to automatically since no assumption\r
+| is made regarding whether you intend to use it.  This file lets\r
+| you globally define which systems you would like loaded with every\r
+| request.\r
+|\r
+| -------------------------------------------------------------------\r
+| Instructions\r
+| -------------------------------------------------------------------\r
+|\r
+| These are the things you can load automatically:\r
+|\r
+| 1. Libraries\r
+| 2. Helper files\r
+| 3. Plugins\r
+| 4. Custom config files\r
+| 5. Language files\r
+| 6. Models\r
+|\r
+*/\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Libraries\r
+| -------------------------------------------------------------------\r
+| These are the classes located in the system/libraries folder\r
+| or in your system/application/libraries folder.\r
+|\r
+| Prototype:\r
+|\r
+|      $autoload['libraries'] = array('database', 'session', 'xmlrpc');\r
+*/\r
+\r
+$autoload['libraries'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Helper Files\r
+| -------------------------------------------------------------------\r
+| Prototype:\r
+|\r
+|      $autoload['helper'] = array('url', 'file');\r
+*/\r
+\r
+$autoload['helper'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Plugins\r
+| -------------------------------------------------------------------\r
+| Prototype:\r
+|\r
+|      $autoload['plugin'] = array('captcha', 'js_calendar');\r
+*/\r
+\r
+$autoload['plugin'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Config files\r
+| -------------------------------------------------------------------\r
+| Prototype:\r
+|\r
+|      $autoload['config'] = array('config1', 'config2');\r
+|\r
+| NOTE: This item is intended for use ONLY if you have created custom\r
+| config files.  Otherwise, leave it blank.\r
+|\r
+*/\r
+\r
+$autoload['config'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Language files\r
+| -------------------------------------------------------------------\r
+| Prototype:\r
+|\r
+|      $autoload['language'] = array('lang1', 'lang2');\r
+|\r
+| NOTE: Do not include the "_lang" part of your file.  For example \r
+| "codeigniter_lang.php" would be referenced as array('codeigniter');\r
+|\r
+*/\r
+\r
+$autoload['language'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Models\r
+| -------------------------------------------------------------------\r
+| Prototype:\r
+|\r
+|      $autoload['model'] = array('model1', 'model2');\r
+|\r
+*/\r
+\r
+$autoload['model'] = array();\r
+\r
+\r
+/*\r
+| -------------------------------------------------------------------\r
+|  Auto-load Core Libraries\r
+| -------------------------------------------------------------------\r
+|\r
+| DEPRECATED:  Use $autoload['libraries'] above instead.\r
+|\r
+*/\r
+// $autoload['core'] = array();\r
+\r
+\r
+\r
+/* End of file autoload.php */\r
+/* Location: ./system/application/config/autoload.php */
\ No newline at end of file
diff --git a/application/config/config.php b/application/config/config.php
new file mode 100644 (file)
index 0000000..6b8fcaf
--- /dev/null
@@ -0,0 +1,317 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+\r
+include_once 'plc_config.php';\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Base Site URL\r
+|--------------------------------------------------------------------------\r
+|\r
+| URL to your CodeIgniter root. Typically this will be your base URL,\r
+| WITH a trailing slash:\r
+|\r
+|      http://example.com/\r
+|\r
+*/\r
+$config['base_url']    = "https://". PLC_WWW_HOST . ":" . PLC_WWW_SSL_PORT ."/registerwizard/";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Index File\r
+|--------------------------------------------------------------------------\r
+|\r
+| Typically this will be your index.php file, unless you've renamed it to\r
+| something else. If you are using mod_rewrite to remove the page set this\r
+| variable so that it is blank.\r
+|\r
+*/\r
+$config['index_page'] = "index.php";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| URI PROTOCOL\r
+|--------------------------------------------------------------------------\r
+|\r
+| This item determines which server global should be used to retrieve the\r
+| URI string.  The default setting of "AUTO" works for most servers.\r
+| If your links do not seem to work, try one of the other delicious flavors:\r
+|\r
+| 'AUTO'                       Default - auto detects\r
+| 'PATH_INFO'          Uses the PATH_INFO\r
+| 'QUERY_STRING'       Uses the QUERY_STRING\r
+| 'REQUEST_URI'                Uses the REQUEST_URI\r
+| 'ORIG_PATH_INFO'     Uses the ORIG_PATH_INFO\r
+|\r
+*/\r
+$config['uri_protocol']        = "AUTO";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| URL suffix\r
+|--------------------------------------------------------------------------\r
+|\r
+| This option allows you to add a suffix to all URLs generated by CodeIgniter.\r
+| For more information please see the user guide:\r
+|\r
+| http://codeigniter.com/user_guide/general/urls.html\r
+*/\r
+\r
+$config['url_suffix'] = "";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Default Language\r
+|--------------------------------------------------------------------------\r
+|\r
+| This determines which set of language files should be used. Make sure\r
+| there is an available translation if you intend to use something other\r
+| than english.\r
+|\r
+*/\r
+$config['language']    = "english";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Default Character Set\r
+|--------------------------------------------------------------------------\r
+|\r
+| This determines which character set is used by default in various methods\r
+| that require a character set to be provided.\r
+|\r
+*/\r
+$config['charset'] = "UTF-8";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Enable/Disable System Hooks\r
+|--------------------------------------------------------------------------\r
+|\r
+| If you would like to use the "hooks" feature you must enable it by\r
+| setting this variable to TRUE (boolean).  See the user guide for details.\r
+|\r
+*/\r
+$config['enable_hooks'] = FALSE;\r
+\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Class Extension Prefix\r
+|--------------------------------------------------------------------------\r
+|\r
+| This item allows you to set the filename/classname prefix when extending\r
+| native libraries.  For more information please see the user guide:\r
+|\r
+| http://codeigniter.com/user_guide/general/core_classes.html\r
+| http://codeigniter.com/user_guide/general/creating_libraries.html\r
+|\r
+*/\r
+$config['subclass_prefix'] = 'MY_';\r
+\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Allowed URL Characters\r
+|--------------------------------------------------------------------------\r
+|\r
+| This lets you specify with a regular expression which characters are permitted\r
+| within your URLs.  When someone tries to submit a URL with disallowed\r
+| characters they will get a warning message.\r
+|\r
+| As a security measure you are STRONGLY encouraged to restrict URLs to\r
+| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-\r
+|\r
+| Leave blank to allow all characters -- but only if you are insane.\r
+|\r
+| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!\r
+|\r
+*/\r
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';\r
+\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Enable Query Strings\r
+|--------------------------------------------------------------------------\r
+|\r
+| By default CodeIgniter uses search-engine friendly segment based URLs:\r
+| example.com/who/what/where/\r
+|\r
+| You can optionally enable standard query string based URLs:\r
+| example.com?who=me&what=something&where=here\r
+|\r
+| Options are: TRUE or FALSE (boolean)\r
+|\r
+| The other items let you set the query string "words" that will\r
+| invoke your controllers and its functions:\r
+| example.com/index.php?c=controller&m=function\r
+|\r
+| Please note that some of the helpers won't work as expected when\r
+| this feature is enabled, since CodeIgniter is designed primarily to\r
+| use segment based URLs.\r
+|\r
+*/\r
+$config['enable_query_strings'] = FALSE;\r
+$config['controller_trigger']  = 'c';\r
+$config['function_trigger']    = 'm';\r
+$config['directory_trigger']   = 'd'; // experimental not currently in use\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Error Logging Threshold\r
+|--------------------------------------------------------------------------\r
+|\r
+| If you have enabled error logging, you can set an error threshold to \r
+| determine what gets logged. Threshold options are:\r
+| You can enable error logging by setting a threshold over zero. The\r
+| threshold determines what gets logged. Threshold options are:\r
+|\r
+|      0 = Disables logging, Error logging TURNED OFF\r
+|      1 = Error Messages (including PHP errors)\r
+|      2 = Debug Messages\r
+|      3 = Informational Messages\r
+|      4 = All Messages\r
+|\r
+| For a live site you'll usually only enable Errors (1) to be logged otherwise\r
+| your log files will fill up very fast.\r
+|\r
+*/\r
+$config['log_threshold'] = 0;\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Error Logging Directory Path\r
+|--------------------------------------------------------------------------\r
+|\r
+| Leave this BLANK unless you would like to set something other than the default\r
+| system/logs/ folder.  Use a full server path with trailing slash.\r
+|\r
+*/\r
+$config['log_path'] = '';\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Date Format for Logs\r
+|--------------------------------------------------------------------------\r
+|\r
+| Each item that is logged has an associated date. You can use PHP date\r
+| codes to set your own date formatting\r
+|\r
+*/\r
+$config['log_date_format'] = 'Y-m-d H:i:s';\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Cache Directory Path\r
+|--------------------------------------------------------------------------\r
+|\r
+| Leave this BLANK unless you would like to set something other than the default\r
+| system/cache/ folder.  Use a full server path with trailing slash.\r
+|\r
+*/\r
+$config['cache_path'] = '';\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Encryption Key\r
+|--------------------------------------------------------------------------\r
+|\r
+| If you use the Encryption class or the Sessions class with encryption\r
+| enabled you MUST set an encryption key.  See the user guide for info.\r
+|\r
+*/\r
+$config['encryption_key'] = "";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Session Variables\r
+|--------------------------------------------------------------------------\r
+|\r
+| 'session_cookie_name' = the name you want for the cookie\r
+| 'encrypt_sess_cookie' = TRUE/FALSE (boolean).  Whether to encrypt the cookie\r
+| 'session_expiration'  = the number of SECONDS you want the session to last.\r
+|  by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.\r
+| 'time_to_update'             = how many seconds between CI refreshing Session Information\r
+|\r
+*/\r
+$config['sess_cookie_name']            = 'ci_session';\r
+$config['sess_expiration']             = 7200;\r
+$config['sess_encrypt_cookie'] = FALSE;\r
+$config['sess_use_database']   = FALSE;\r
+$config['sess_table_name']             = 'ci_sessions';\r
+$config['sess_match_ip']               = FALSE;\r
+$config['sess_match_useragent']        = TRUE;\r
+$config['sess_time_to_update']         = 300;\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Cookie Related Variables\r
+|--------------------------------------------------------------------------\r
+|\r
+| 'cookie_prefix' = Set a prefix if you need to avoid collisions\r
+| 'cookie_domain' = Set to .your-domain.com for site-wide cookies\r
+| 'cookie_path'   =  Typically will be a forward slash\r
+|\r
+*/\r
+$config['cookie_prefix']       = "";\r
+$config['cookie_domain']       = "";\r
+$config['cookie_path']         = "/";\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Global XSS Filtering\r
+|--------------------------------------------------------------------------\r
+|\r
+| Determines whether the XSS filter is always active when GET, POST or\r
+| COOKIE data is encountered\r
+|\r
+*/\r
+$config['global_xss_filtering'] = FALSE;\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Output Compression\r
+|--------------------------------------------------------------------------\r
+|\r
+| Enables Gzip output compression for faster page loads.  When enabled,\r
+| the output class will test whether your server supports Gzip.\r
+| Even if it does, however, not all browsers support compression\r
+| so enable only if you are reasonably sure your visitors can handle it.\r
+|\r
+| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it\r
+| means you are prematurely outputting something to your browser. It could\r
+| even be a line of whitespace at the end of one of your scripts.  For\r
+| compression to work, nothing can be sent before the output buffer is called\r
+| by the output class.  Do not "echo" any values with compression enabled.\r
+|\r
+*/\r
+$config['compress_output'] = FALSE;\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Master Time Reference\r
+|--------------------------------------------------------------------------\r
+|\r
+| Options are "local" or "gmt".  This pref tells the system whether to use\r
+| your server's local time as the master "now" reference, or convert it to\r
+| GMT.  See the "date helper" page of the user guide for information\r
+| regarding date handling.\r
+|\r
+*/\r
+$config['time_reference'] = 'local';\r
+\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| Rewrite PHP Short Tags\r
+|--------------------------------------------------------------------------\r
+|\r
+| If your PHP installation does not have short tag support enabled CI\r
+| can rewrite the tags on-the-fly, enabling you to utilize that syntax\r
+| in your view files.  Options are TRUE or FALSE (boolean)\r
+|\r
+*/\r
+$config['rewrite_short_tags'] = FALSE;\r
+\r
+\r
+\r
+/* End of file config.php */\r
+/* Location: ./system/application/config/config.php */\r
diff --git a/application/config/constants.php b/application/config/constants.php
new file mode 100644 (file)
index 0000000..3d317f5
--- /dev/null
@@ -0,0 +1,41 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| File and Directory Modes\r
+|--------------------------------------------------------------------------\r
+|\r
+| These prefs are used when checking and setting modes when working\r
+| with the file system.  The defaults are fine on servers with proper\r
+| security, but you may wish (or even need) to change the values in\r
+| certain environments (Apache running a separate process for each\r
+| user, PHP under CGI with Apache suEXEC, etc.).  Octal values should\r
+| always be used to set the mode correctly.\r
+|\r
+*/\r
+define('FILE_READ_MODE', 0644);\r
+define('FILE_WRITE_MODE', 0666);\r
+define('DIR_READ_MODE', 0755);\r
+define('DIR_WRITE_MODE', 0777);\r
+\r
+/*\r
+|--------------------------------------------------------------------------\r
+| File Stream Modes\r
+|--------------------------------------------------------------------------\r
+|\r
+| These modes are used when working with fopen()/popen()\r
+|\r
+*/\r
+\r
+define('FOPEN_READ',                                                   'rb');\r
+define('FOPEN_READ_WRITE',                                             'r+b');\r
+define('FOPEN_WRITE_CREATE_DESTRUCTIVE',               'wb'); // truncates existing file data, use with care\r
+define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE',  'w+b'); // truncates existing file data, use with care\r
+define('FOPEN_WRITE_CREATE',                                   'ab');\r
+define('FOPEN_READ_WRITE_CREATE',                              'a+b');\r
+define('FOPEN_WRITE_CREATE_STRICT',                    'xb');\r
+define('FOPEN_READ_WRITE_CREATE_STRICT',               'x+b');\r
+\r
+\r
+/* End of file constants.php */\r
+/* Location: ./system/application/config/constants.php */
\ No newline at end of file
diff --git a/application/config/database.php b/application/config/database.php
new file mode 100644 (file)
index 0000000..24789f4
--- /dev/null
@@ -0,0 +1,55 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/*\r
+| -------------------------------------------------------------------\r
+| DATABASE CONNECTIVITY SETTINGS\r
+| -------------------------------------------------------------------\r
+| This file will contain the settings needed to access your database.\r
+|\r
+| For complete instructions please consult the "Database Connection"\r
+| page of the User Guide.\r
+|\r
+| -------------------------------------------------------------------\r
+| EXPLANATION OF VARIABLES\r
+| -------------------------------------------------------------------\r
+|\r
+|      ['hostname'] The hostname of your database server.\r
+|      ['username'] The username used to connect to the database\r
+|      ['password'] The password used to connect to the database\r
+|      ['database'] The name of the database you want to connect to\r
+|      ['dbdriver'] The database type. ie: mysql.  Currently supported:\r
+                                mysql, mysqli, postgre, odbc, mssql, sqlite, oci8\r
+|      ['dbprefix'] You can add an optional prefix, which will be added\r
+|                               to the table name when using the  Active Record class\r
+|      ['pconnect'] TRUE/FALSE - Whether to use a persistent connection\r
+|      ['db_debug'] TRUE/FALSE - Whether database errors should be displayed.\r
+|      ['cache_on'] TRUE/FALSE - Enables/disables query caching\r
+|      ['cachedir'] The path to the folder where cache files should be stored\r
+|      ['char_set'] The character set used in communicating with the database\r
+|      ['dbcollat'] The character collation used in communicating with the database\r
+|\r
+| The $active_group variable lets you choose which connection group to\r
+| make active.  By default there is only one group (the "default" group).\r
+|\r
+| The $active_record variables lets you determine whether or not to load\r
+| the active record class\r
+*/\r
+\r
+$active_group = "default";\r
+$active_record = TRUE;\r
+\r
+$db['default']['hostname'] = "localhost";\r
+$db['default']['username'] = "";\r
+$db['default']['password'] = "";\r
+$db['default']['database'] = "";\r
+$db['default']['dbdriver'] = "mysql";\r
+$db['default']['dbprefix'] = "";\r
+$db['default']['pconnect'] = TRUE;\r
+$db['default']['db_debug'] = TRUE;\r
+$db['default']['cache_on'] = FALSE;\r
+$db['default']['cachedir'] = "";\r
+$db['default']['char_set'] = "utf8";\r
+$db['default']['dbcollat'] = "utf8_general_ci";\r
+\r
+\r
+/* End of file database.php */\r
+/* Location: ./system/application/config/database.php */
\ No newline at end of file
diff --git a/application/config/hooks.php b/application/config/hooks.php
new file mode 100644 (file)
index 0000000..5e98a9b
--- /dev/null
@@ -0,0 +1,16 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------------
+| Hooks
+| -------------------------------------------------------------------------
+| This file lets you define "hooks" to extend CI without hacking the core
+| files.  Please see the user guide for info:
+|
+|      http://codeigniter.com/user_guide/general/hooks.html
+|
+*/
+
+
+
+/* End of file hooks.php */
+/* Location: ./system/application/config/hooks.php */
\ No newline at end of file
diff --git a/application/config/index.html b/application/config/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/config/mimes.php b/application/config/mimes.php
new file mode 100644 (file)
index 0000000..51e444e
--- /dev/null
@@ -0,0 +1,105 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/*\r
+| -------------------------------------------------------------------\r
+| MIME TYPES\r
+| -------------------------------------------------------------------\r
+| This file contains an array of mime types.  It is used by the\r
+| Upload class to help identify allowed file types.\r
+|\r
+*/\r
+\r
+$mimes = array(        'hqx'   =>      'application/mac-binhex40',\r
+                               'cpt'   =>      'application/mac-compactpro',\r
+                               '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'),\r
+                               'bin'   =>      'application/macbinary',\r
+                               'dms'   =>      'application/octet-stream',\r
+                               'lha'   =>      'application/octet-stream',\r
+                               'lzh'   =>      'application/octet-stream',\r
+                               'exe'   =>      'application/octet-stream',\r
+                               'class' =>      'application/octet-stream',\r
+                               'psd'   =>      'application/x-photoshop',\r
+                               'so'    =>      'application/octet-stream',\r
+                               'sea'   =>      'application/octet-stream',\r
+                               'dll'   =>      'application/octet-stream',\r
+                               'oda'   =>      'application/oda',\r
+                               'pdf'   =>      array('application/pdf', 'application/x-download'),\r
+                               'ai'    =>      'application/postscript',\r
+                               'eps'   =>      'application/postscript',\r
+                               'ps'    =>      'application/postscript',\r
+                               'smi'   =>      'application/smil',\r
+                               'smil'  =>      'application/smil',\r
+                               'mif'   =>      'application/vnd.mif',\r
+                               'xls'   =>      array('application/excel', 'application/vnd.ms-excel'),\r
+                               'ppt'   =>      array('application/powerpoint', 'application/vnd.ms-powerpoint'),\r
+                               'wbxml' =>      'application/wbxml',\r
+                               'wmlc'  =>      'application/wmlc',\r
+                               'dcr'   =>      'application/x-director',\r
+                               'dir'   =>      'application/x-director',\r
+                               'dxr'   =>      'application/x-director',\r
+                               'dvi'   =>      'application/x-dvi',\r
+                               'gtar'  =>      'application/x-gtar',\r
+                               'gz'    =>      'application/x-gzip',\r
+                               'php'   =>      'application/x-httpd-php',\r
+                               'php4'  =>      'application/x-httpd-php',\r
+                               'php3'  =>      'application/x-httpd-php',\r
+                               'phtml' =>      'application/x-httpd-php',\r
+                               'phps'  =>      'application/x-httpd-php-source',\r
+                               'js'    =>      'application/x-javascript',\r
+                               'swf'   =>      'application/x-shockwave-flash',\r
+                               'sit'   =>      'application/x-stuffit',\r
+                               'tar'   =>      'application/x-tar',\r
+                               'tgz'   =>      'application/x-tar',\r
+                               'xhtml' =>      'application/xhtml+xml',\r
+                               'xht'   =>      'application/xhtml+xml',\r
+                               'zip'   =>  array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),\r
+                               'mid'   =>      'audio/midi',\r
+                               'midi'  =>      'audio/midi',\r
+                               'mpga'  =>      'audio/mpeg',\r
+                               'mp2'   =>      'audio/mpeg',\r
+                               'mp3'   =>      array('audio/mpeg', 'audio/mpg'),\r
+                               'aif'   =>      'audio/x-aiff',\r
+                               'aiff'  =>      'audio/x-aiff',\r
+                               'aifc'  =>      'audio/x-aiff',\r
+                               'ram'   =>      'audio/x-pn-realaudio',\r
+                               'rm'    =>      'audio/x-pn-realaudio',\r
+                               'rpm'   =>      'audio/x-pn-realaudio-plugin',\r
+                               'ra'    =>      'audio/x-realaudio',\r
+                               'rv'    =>      'video/vnd.rn-realvideo',\r
+                               'wav'   =>      'audio/x-wav',\r
+                               'bmp'   =>      'image/bmp',\r
+                               'gif'   =>      'image/gif',\r
+                               'jpeg'  =>      array('image/jpeg', 'image/pjpeg'),\r
+                               'jpg'   =>      array('image/jpeg', 'image/pjpeg'),\r
+                               'jpe'   =>      array('image/jpeg', 'image/pjpeg'),\r
+                               'png'   =>      array('image/png',  'image/x-png'),\r
+                               'tiff'  =>      'image/tiff',\r
+                               'tif'   =>      'image/tiff',\r
+                               'css'   =>      'text/css',\r
+                               'html'  =>      'text/html',\r
+                               'htm'   =>      'text/html',\r
+                               'shtml' =>      'text/html',\r
+                               'txt'   =>      'text/plain',\r
+                               'text'  =>      'text/plain',\r
+                               'log'   =>      array('text/plain', 'text/x-log'),\r
+                               'rtx'   =>      'text/richtext',\r
+                               'rtf'   =>      'text/rtf',\r
+                               'xml'   =>      'text/xml',\r
+                               'xsl'   =>      'text/xml',\r
+                               'mpeg'  =>      'video/mpeg',\r
+                               'mpg'   =>      'video/mpeg',\r
+                               'mpe'   =>      'video/mpeg',\r
+                               'qt'    =>      'video/quicktime',\r
+                               'mov'   =>      'video/quicktime',\r
+                               'avi'   =>      'video/x-msvideo',\r
+                               'movie' =>      'video/x-sgi-movie',\r
+                               'doc'   =>      'application/msword',\r
+                               'docx'  =>      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\r
+                               'xlsx'  =>      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r
+                               'word'  =>      array('application/msword', 'application/octet-stream'),\r
+                               'xl'    =>      'application/excel',\r
+                               'eml'   =>      'message/rfc822'\r
+                       );\r
+\r
+\r
+/* End of file mimes.php */\r
+/* Location: ./system/application/config/mimes.php */
\ No newline at end of file
diff --git a/application/config/routes.php b/application/config/routes.php
new file mode 100644 (file)
index 0000000..beeff25
--- /dev/null
@@ -0,0 +1,48 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/*\r
+| -------------------------------------------------------------------------\r
+| URI ROUTING\r
+| -------------------------------------------------------------------------\r
+| This file lets you re-map URI requests to specific controller functions.\r
+|\r
+| Typically there is a one-to-one relationship between a URL string\r
+| and its corresponding controller class/method. The segments in a\r
+| URL normally follow this pattern:\r
+|\r
+|      example.com/class/method/id/\r
+|\r
+| In some instances, however, you may want to remap this relationship\r
+| so that a different class/function is called than the one\r
+| corresponding to the URL.\r
+|\r
+| Please see the user guide for complete details:\r
+|\r
+|      http://codeigniter.com/user_guide/general/routing.html\r
+|\r
+| -------------------------------------------------------------------------\r
+| RESERVED ROUTES\r
+| -------------------------------------------------------------------------\r
+|\r
+| There are two reserved routes:\r
+|\r
+|      $route['default_controller'] = 'welcome';\r
+|\r
+| This route indicates which controller class should be loaded if the\r
+| URI contains no data. In the above example, the "welcome" class\r
+| would be loaded.\r
+|\r
+|      $route['scaffolding_trigger'] = 'scaffolding';\r
+|\r
+| This route lets you set a "secret" word that will trigger the\r
+| scaffolding feature for added security. Note: Scaffolding must be\r
+| enabled in the controller in which you intend to use it.   The reserved \r
+| routes must come before any wildcard or regular expression routes.\r
+|\r
+*/\r
+\r
+$route['default_controller'] = "register";\r
+$route['scaffolding_trigger'] = "";\r
+\r
+\r
+/* End of file routes.php */\r
+/* Location: ./system/application/config/routes.php */\r
diff --git a/application/config/smileys.php b/application/config/smileys.php
new file mode 100644 (file)
index 0000000..b1988cd
--- /dev/null
@@ -0,0 +1,66 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| SMILEYS
+| -------------------------------------------------------------------
+| This file contains an array of smileys for use with the emoticon helper.
+| Individual images can be used to replace multiple simileys.  For example:
+| :-) and :) use the same image replacement.
+|
+| Please see user guide for more info: 
+| http://codeigniter.com/user_guide/helpers/smiley_helper.html
+|
+*/
+
+$smileys = array(
+
+//     smiley                  image name                                              width   height  alt
+
+       ':-)'                   =>      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('raspberry.gif',          '19',   '19',   'raspberry'),
+       ':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
+       
+               );
+
+/* End of file smileys.php */
+/* Location: ./system/application/config/smileys.php */
\ No newline at end of file
diff --git a/application/config/user_agents.php b/application/config/user_agents.php
new file mode 100644 (file)
index 0000000..38bfc1f
--- /dev/null
@@ -0,0 +1,175 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/*\r
+| -------------------------------------------------------------------\r
+| USER AGENT TYPES\r
+| -------------------------------------------------------------------\r
+| This file contains four arrays of user agent data.  It is used by the\r
+| User Agent Class to help identify browser, platform, robot, and\r
+| mobile device data.  The array keys are used to identify the device\r
+| and the array values are used to set the actual name of the item.\r
+|\r
+*/\r
+\r
+$platforms = array (\r
+                                       'windows nt 6.0'        => 'Windows Longhorn',\r
+                                       'windows nt 5.2'        => 'Windows 2003',\r
+                                       'windows nt 5.0'        => 'Windows 2000',\r
+                                       'windows nt 5.1'        => 'Windows XP',\r
+                                       'windows nt 4.0'        => 'Windows NT 4.0',\r
+                                       'winnt4.0'                      => 'Windows NT 4.0',\r
+                                       'winnt 4.0'                     => 'Windows NT',\r
+                                       'winnt'                         => 'Windows NT',\r
+                                       'windows 98'            => 'Windows 98',\r
+                                       'win98'                         => 'Windows 98',\r
+                                       'windows 95'            => 'Windows 95',\r
+                                       'win95'                         => 'Windows 95',\r
+                                       'windows'                       => 'Unknown Windows OS',\r
+                                       'os x'                          => 'Mac OS X',\r
+                                       'ppc mac'                       => 'Power PC Mac',\r
+                                       'freebsd'                       => 'FreeBSD',\r
+                                       'ppc'                           => 'Macintosh',\r
+                                       'linux'                         => 'Linux',\r
+                                       'debian'                        => 'Debian',\r
+                                       'sunos'                         => 'Sun Solaris',\r
+                                       'beos'                          => 'BeOS',\r
+                                       'apachebench'           => 'ApacheBench',\r
+                                       'aix'                           => 'AIX',\r
+                                       'irix'                          => 'Irix',\r
+                                       'osf'                           => 'DEC OSF',\r
+                                       'hp-ux'                         => 'HP-UX',\r
+                                       'netbsd'                        => 'NetBSD',\r
+                                       'bsdi'                          => 'BSDi',\r
+                                       'openbsd'                       => 'OpenBSD',\r
+                                       'gnu'                           => 'GNU/Linux',\r
+                                       'unix'                          => 'Unknown Unix OS'\r
+                               );\r
+\r
+\r
+// The order of this array should NOT be changed. Many browsers return\r
+// multiple browser types so we want to identify the sub-type first.\r
+$browsers = array(\r
+                                       'Opera'                         => 'Opera',\r
+                                       'MSIE'                          => 'Internet Explorer',\r
+                                       'Internet Explorer'     => 'Internet Explorer',\r
+                                       'Shiira'                        => 'Shiira',\r
+                                       'Firefox'                       => 'Firefox',\r
+                                       'Chimera'                       => 'Chimera',\r
+                                       'Phoenix'                       => 'Phoenix',\r
+                                       'Firebird'                      => 'Firebird',\r
+                                       'Camino'                        => 'Camino',\r
+                                       'Netscape'                      => 'Netscape',\r
+                                       'OmniWeb'                       => 'OmniWeb',\r
+                                       'Mozilla'                       => 'Mozilla',\r
+                                       'Safari'                        => 'Safari',\r
+                                       'Konqueror'                     => 'Konqueror',\r
+                                       'icab'                          => 'iCab',\r
+                                       'Lynx'                          => 'Lynx',\r
+                                       'Links'                         => 'Links',\r
+                                       'hotjava'                       => 'HotJava',\r
+                                       'amaya'                         => 'Amaya',\r
+                                       'IBrowse'                       => 'IBrowse'\r
+                               );\r
+\r
+$mobiles = array(\r
+                                       // legacy array, old values commented out\r
+                                       'mobileexplorer'        => 'Mobile Explorer',\r
+//                                     'openwave'                      => 'Open Wave',\r
+//                                     'opera mini'            => 'Opera Mini',\r
+//                                     'operamini'                     => 'Opera Mini',\r
+//                                     'elaine'                        => 'Palm',\r
+                                       'palmsource'            => 'Palm',\r
+//                                     'digital paths'         => 'Palm',\r
+//                                     'avantgo'                       => 'Avantgo',\r
+//                                     'xiino'                         => 'Xiino',\r
+                                       'palmscape'                     => 'Palmscape',\r
+//                                     'nokia'                         => 'Nokia',\r
+//                                     'ericsson'                      => 'Ericsson',\r
+//                                     'blackberry'            => 'BlackBerry',\r
+//                                     'motorola'                      => 'Motorola'\r
+                                       \r
+                                       // Phones and Manufacturers\r
+                                       'motorola'                      => "Motorola",\r
+                                       'nokia'                         => "Nokia",\r
+                                       'palm'                          => "Palm",\r
+                                       'iphone'                        => "Apple iPhone",\r
+                                       'ipod'                          => "Apple iPod Touch",\r
+                                       'sony'                          => "Sony Ericsson",\r
+                                       'ericsson'                      => "Sony Ericsson",\r
+                                       'blackberry'            => "BlackBerry",\r
+                                       'cocoon'                        => "O2 Cocoon",\r
+                                       'blazer'                        => "Treo",\r
+                                       'lg'                            => "LG",\r
+                                       'amoi'                          => "Amoi",\r
+                                       'xda'                           => "XDA",\r
+                                       'mda'                           => "MDA",\r
+                                       'vario'                         => "Vario",\r
+                                       'htc'                           => "HTC",\r
+                                       'samsung'                       => "Samsung",\r
+                                       'sharp'                         => "Sharp",\r
+                                       'sie-'                          => "Siemens",\r
+                                       'alcatel'                       => "Alcatel",\r
+                                       'benq'                          => "BenQ",\r
+                                       'ipaq'                          => "HP iPaq",\r
+                                       'mot-'                          => "Motorola",\r
+                                       'playstation portable'  => "PlayStation Portable",\r
+                                       'hiptop'                        => "Danger Hiptop",\r
+                                       'nec-'                          => "NEC",\r
+                                       'panasonic'                     => "Panasonic",\r
+                                       'philips'                       => "Philips",\r
+                                       'sagem'                         => "Sagem",\r
+                                       'sanyo'                         => "Sanyo",\r
+                                       'spv'                           => "SPV",\r
+                                       'zte'                           => "ZTE",\r
+                                       'sendo'                         => "Sendo",\r
+                                       \r
+                                       // Operating Systems\r
+                                       'symbian'                               => "Symbian",\r
+                                       'SymbianOS'                             => "SymbianOS", \r
+                                       'elaine'                                => "Palm",\r
+                                       'palm'                                  => "Palm",\r
+                                       'series60'                              => "Symbian S60",\r
+                                       'windows ce'                    => "Windows CE",\r
+                               \r
+                                       // Browsers     \r
+                                       'obigo'                                 => "Obigo",\r
+                                       'netfront'                              => "Netfront Browser",\r
+                                       'openwave'                              => "Openwave Browser",\r
+                                       'mobilexplorer'                 => "Mobile Explorer",\r
+                                       'operamini'                             => "Opera Mini",\r
+                                       'opera mini'                    => "Opera Mini",\r
+                               \r
+                                       // Other\r
+                                       'digital paths'                 => "Digital Paths",\r
+                                       'avantgo'                               => "AvantGo",\r
+                                       'xiino'                                 => "Xiino",\r
+                                       'novarra'                               => "Novarra Transcoder",\r
+                                       'vodafone'                              => "Vodafone",\r
+                                       'docomo'                                => "NTT DoCoMo",\r
+                                       'o2'                                    => "O2",\r
+                               \r
+                                       // Fallback\r
+                                       'mobile'                                => "Generic Mobile",\r
+                                       'wireless'                              => "Generic Mobile",\r
+                                       'j2me'                                  => "Generic Mobile",\r
+                                       'midp'                                  => "Generic Mobile",\r
+                                       'cldc'                                  => "Generic Mobile",\r
+                                       'up.link'                               => "Generic Mobile",\r
+                                       'up.browser'                    => "Generic Mobile",\r
+                                       'smartphone'                    => "Generic Mobile",\r
+                                       'cellphone'                             => "Generic Mobile"\r
+                               );\r
+\r
+// There are hundreds of bots but these are the most common.\r
+$robots = array(\r
+                                       'googlebot'                     => 'Googlebot',\r
+                                       'msnbot'                        => 'MSNBot',\r
+                                       'slurp'                         => 'Inktomi Slurp',\r
+                                       'yahoo'                         => 'Yahoo',\r
+                                       'askjeeves'                     => 'AskJeeves',\r
+                                       'fastcrawler'           => 'FastCrawler',\r
+                                       'infoseek'                      => 'InfoSeek Robot 1.0',\r
+                                       'lycos'                         => 'Lycos'\r
+                               );\r
+\r
+/* End of file user_agents.php */\r
+/* Location: ./system/application/config/user_agents.php */
\ No newline at end of file
diff --git a/application/controllers/conffile.php b/application/controllers/conffile.php
new file mode 100644 (file)
index 0000000..9f59fc6
--- /dev/null
@@ -0,0 +1,311 @@
+<?php
+
+require_once 'plc_login.php'; // Require login
+require_once 'plc_session.php'; // Get session and API handles
+global $plc, $api, $adm;
+
+// Print header
+require_once 'plc_drupal.php';
+
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+include 'plc_objects.php';
+
+
+class Conffile extends Controller {
+       
+       function index()
+       {
+               global $api, $plc;
+               $all_conf_files= $api->GetConfFiles();
+               print $api->error();
+               $data = array();
+               $data['all_conf_files'] = $all_conf_files;
+               $data['api'] = $api;
+               $data['stage'] = 1;
+
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('ListConfFile', $data);
+               $this->load->view('footer', $data);
+
+       }
+       function get_stage_data(&$data)
+       {
+               global $api, $plc;
+               $data['nodegroups'] = $api->GetNodeGroups();
+               $data['nodes'] = $api->GetNodes(NULL, array('hostname', 'node_id'));
+               return $data;
+       }
+       function convert_checked($val)
+       {
+               if ( $val == "on" || $val == True )
+               {
+                       print "CALLED CHECKED '$val' .<BR>";
+                       return True;
+               } else {
+                       return False;
+               }
+       }
+       function update($conf_file_id=-1)
+       {
+               global $api, $plc;
+               $conf_file_id = intval($conf_file_id);
+
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $data = array();
+
+               $data['submit_caption'] = "Update";
+               $data['title'] = "Update existing node configuration file";
+               $data['conf_file_id'] = $conf_file_id;
+
+               $fields['enabled']  = "Enabled";
+               $fields['source']               = "Source";
+               $fields['dest']  = "Destination";
+               $fields['file_permissions']  = "File Permissions";
+               $fields['file_owner']  = "File Owner";
+               $fields['file_group']  = "File Group";
+               $fields['preinstall_cmd']  = "Preinstall Command";
+               $fields['postinstall_cmd']  = "Postinstall Command";
+               $fields['error_cmd']  = "Error Command";
+               $fields['ignore_cmd_errors']  = "Ignore Command Errors";
+               $fields['always_update']  = "Always Update";
+               $fields['scope']  = "ConfFile Scope";
+               $fields['node_ids']  = "";
+               $fields['nodegroup_ids']  = "";
+               $this->validation->set_fields($fields);
+
+               if( isset($_REQUEST['submitted']) )
+               {
+                       print "SUBMITTED REQUEST";
+                       $rules['enabled']  = "trim";
+                       $rules['source']                = "trim|required";
+                       $rules['dest']  = "trim|required";
+                       $rules['file_permissions']  = "trim";
+                       $rules['file_owner']  = "trim";
+                       $rules['file_group']  = "trim";
+                       $rules['preinstall_cmd']  = "trim";
+                       $rules['postinstall_cmd']  = "trim";
+                       $rules['error_cmd']  = "trim";
+                       $rules['ignore_cmd_errors']  = "trim";
+                       $rules['always_update']  = "trim";
+                       $rules['scope']  = "trim";
+                       $rules['node_ids']  = "trim";
+                       $rules['nodegroup_ids']  = "trim";
+                       $this->validation->set_rules($rules);
+
+                       $error_occurred= 0;
+                       if ($this->validation->run() == TRUE)
+                       {
+                               $data['enabled']                        =       $this->validation->enabled;
+                               $data['source']                         =       $this->validation->source;
+                               $data['dest']                           =       $this->validation->dest;
+                               $data['file_permissions']       =       $this->validation->file_permissions;
+                               $data['file_owner']                     =       $this->validation->file_owner;
+                               $data['file_group']                     =       $this->validation->file_group;
+                               $data['preinstall_cmd']         =       $this->validation->preinstall_cmd;
+                               $data['postinstall_cmd']        =       $this->validation->postinstall_cmd;
+                               $data['error_cmd']                      =       $this->validation->error_cmd;
+                               $data['ignore_cmd_errors']      =       $this->validation->ignore_cmd_errors;
+                               $data['always_update']          =       $this->validation->always_update;
+                               $data['scope']                          =       $this->validation->scope;
+                               $data['node_ids']                       =       array($this->validation->node_ids);
+                               $data['nodegroup_ids']          =       array($this->validation->nodegroup_ids);
+
+                               print "<br>";
+                               print "ena: " . $data['enabled'] . "<br>";
+                               print "ice: " . $data['ignore_cmd_errors'] . "<br>";
+                               print "alu: " . $data['always_update'] . "<br>";
+                               $conf_fields = array();
+
+                               $data['enabled'] = $this->convert_checked($data['enabled']);
+                               $data['ignore_cmd_errors'] = $this->convert_checked($data['ignore_cmd_errors']);
+                               $data['always_update'] = $this->convert_checked($data['always_update']);
+
+                               # TODO: UpdateConfFile does not honor the values of 'node_ids'
+                               # and 'nodegroup_ids'.  These are read-only values.  Instead
+                               # there needs to be a check to GetConfFile() followed by:
+                               #   AddConfFileToNode(or Group) or,
+                               #   DeleteConfFileFromNode(or Group) as appropriate.
+                               # This would be easier to update in the API, but it's not
+                               # clear if there are other semantics that are being honored by
+                               # doing it the way that it currently is.
+
+                               $return =       $api->UpdateConfFile($conf_file_id, $data);
+                               if ($return != 1 ) {
+                                       print $api->error();
+                               $error_occurred= 1;
+                               }
+                               $return =       $api->GetConfFiles(array($conf_file_id));
+                               print "<pre>";
+                               print_r($return );
+                               print "</pre>";
+                                
+                       } else {
+                               print "VALIDATION FAILED<br>";
+                               print $this->validation->error_string ;
+                               print "VALIDATION FAILED<br>";
+                           $error_occurred= 1;
+                       }
+
+                       if( !$error_occurred )
+                       {
+                           $edit_finalized= 1;
+                           $finalized_message= "Successfully updated.";
+                       } 
+               } else {
+
+                       $conf_file = $api->GetConfFiles(array(intval($conf_file_id)));
+                       if (empty($conf_file)) {
+                               print $api->error();
+                       }
+                       $conf_file = $conf_file[0];
+
+                       $data['enabled']                        =       $conf_file['enabled'];
+                       $data['source']                         =       $conf_file['source'];
+                       $data['dest']                           =       $conf_file['dest'];
+                       $data['file_permissions']       =       $conf_file['file_permissions'];
+                       $data['file_owner']                     =       $conf_file['file_owner'];
+                       $data['file_group']                     =       $conf_file['file_group'];
+                       $data['preinstall_cmd']         =       $conf_file['preinstall_cmd'];
+                       $data['postinstall_cmd']        =       $conf_file['postinstall_cmd'];
+                       $data['error_cmd']                      =       $conf_file['error_cmd'];
+                       $data['ignore_cmd_errors']      =       $conf_file['ignore_cmd_errors'];
+                       $data['always_update']          =       $conf_file['always_update'];
+                       $data['node_ids']                       =       $conf_file['node_ids'];
+                       $data['nodegroup_ids']          =       $conf_file['nodegroup_ids'];
+
+                       if( count($data['nodegroup_ids']) == 0 && count($data['node_ids']) == 0 )
+                       {
+                                $data['scope'] = "global";
+                       } else {                 
+                               if( count($data['nodegroup_ids']) == 0 && is_numeric($data['node_ids'][0]) )
+                               {
+                                       $data['scope'] = "node";
+                               } elseif( count($data['node_ids']) == 0 && is_numeric($data['nodegroup_ids'][0]) )
+                               {
+                                       $data['scope'] = "group";
+                               }
+                       }
+               }
+
+               $data = $this->get_stage_data($data);
+
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('UpdateConfFile', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function add()
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $data = array();
+
+               $fields['enabled']  = "Enabled";
+               $fields['source']               = "Source";
+               $fields['dest']  = "Destination";
+               $fields['file_permissions']  = "File Permissions";
+               $fields['file_owner']  = "File Owner";
+               $fields['file_group']  = "File Group";
+               $fields['preinstall_cmd']  = "Preinstall Command";
+               $fields['postinstall_cmd']  = "Postinstall Command";
+               $fields['error_cmd']  = "Error Command";
+               $fields['ignore_cmd_errors']  = "Ignore Command Errors";
+               $fields['always_update']  = "Always Update";
+               $fields['scope']  = "ConfFile Scope";
+               $fields['node_ids']  = "";
+               $fields['nodegroup_ids']  = "";
+               $this->validation->set_fields($fields);
+
+               if ( isset($_REQUEST['submitted']) )
+               {
+                       $action= $_REQUEST["action"];
+                       $submitted= $_REQUEST["submitted"];
+               } else {
+                       $action= 'default';
+                       $submitted= False;
+               }
+
+               $data['submit_caption']= "Create";
+               $data['title'] = "Create new node configuration file";
+
+               if(     $submitted      )
+               {
+                       $rules['enabled']  = "trim|required|integer|intval";
+                       $rules['source']                = "trim|required";
+                       $rules['dest']  = "trim|required";
+                       $rules['file_permissions']  = "trim";
+                       $rules['file_owner']  = "trim";
+                       $rules['file_group']  = "trim";
+                       $rules['preinstall_cmd']  = "trim";
+                       $rules['postinstall_cmd']  = "trim";
+                       $rules['error_cmd']  = "trim";
+                       $rules['ignore_cmd_errors']  = "trim|integer|intval";
+                       $rules['always_update']  = "trim|integer|intval";
+                       $rules['scope']  = "trim";
+                       $rules['node_ids']  = "trim";
+                       $rules['nodegroup_ids']  = "trim";
+                       $this->validation->set_rules($rules);
+
+                       $data['enabled']                        =       $this->validation->enabled;
+                       $data['source']                         =       $this->validation->source;
+                       $data['dest']                           =       $this->validation->dest;
+                       $data['file_permissions']       =       $this->validation->file_permissions;
+                       $data['file_owner']                     =       $this->validation->file_owner;
+                       $data['file_group']                     =       $this->validation->file_group;
+                       $data['preinstall_cmd']         =       $this->validation->preinstall_cmd;
+                       $data['postinstall_cmd']        =       $this->validation->postinstall_cmd;
+                       $data['error_cmd']                      =       $this->validation->error_cmd;
+                       $data['ignore_cmd_errors']      =       $this->validation->ignore_cmd_errors;
+                       $data['always_update']          =       $this->validation->always_update;
+                       $data['scope']                          =       $this->validation->scope;
+                       $data['node_ids']                       =       array($this->validation->node_ids);
+                       $data['nodegroup_ids']          =       array($this->validation->nodegroup_ids);
+
+                       if ($this->validation->run() == TRUE)
+                       {
+                               $conf_file_id = $api->AddConfFile($data);
+                               if ($conf_file_id == -1 ) {
+                                       print $api->error();
+                               }
+                       }
+
+                       if(     !$error_occurred        )
+                       {
+                               $edit_finalized=        1;
+                               $finalized_message=     "Successfully   created.";
+                       }
+               } else {
+                       //      set     up      default values  for     a       new     one
+                       $data['enabled']                        =       0;
+                       $data['source']                         =       "";
+                       $data['dest']                           =       "";
+                       $data['file_permissions']       =       "644";
+                       $data['file_owner']                     =       "root";
+                       $data['file_group']                     =       "root";
+                       $data['preinstall_cmd']         =       "";
+                       $data['postinstall_cmd']        =       "";
+                       $data['error_cmd']                      =       "";
+                       $data['ignore_cmd_errors']      =       0;
+                       $data['always_update']          =       0;
+                       $data['scope']                          =       "global";
+               }
+
+               $data = $this->get_stage_data($data);
+
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('AddConfFile', $data);
+               $this->load->view('footer', $data);
+
+       }
+}
diff --git a/application/controllers/confirm.php b/application/controllers/confirm.php
new file mode 100644 (file)
index 0000000..2f399f5
--- /dev/null
@@ -0,0 +1,175 @@
+<?php
+
+require_once 'plc_login.php'; // Require login
+require_once 'plc_session.php'; // Get session and API handles
+global $plc, $api, $adm;
+
+// Print header
+require_once 'plc_drupal.php';
+
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+include 'plc_objects.php';
+
+
+class Confirm extends Controller {
+       
+       var $pcu_id = 0;
+       function stage7_firstcontact($pcu_id, $site_id, $node_id)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->helper('download');
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['node_id'] = intval($node_id);
+               $data['site_id'] = intval($site_id);
+               $data['stage'] = 7;
+               $data = $this->get_stage7_data($person, $data);
+               /*print "RESULT: ".$result . "<br>";*/
+               /*print $this->validation->error_string . "<br>";*/
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage7_firstcontact', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function getnode($node_id)
+       {
+               global $api, $plc;
+               $plc_node_list = $api->GetNodes(array('node_id' => intval($node_id) ));
+               return $plc_node_list[0];
+       }
+       function getsite($site_id)
+       {
+               global $api, $plc;
+               $site_info = $api->GetSites($site_id, array( "name", "site_id", "login_base" ) );
+               return $site_info[0];
+       }
+
+       function get_stage7_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['node']  = $this->getnode($data['node_id']);
+               $data['site']  = $this->getsite($data['node']['site_id']);
+               if( $data['node']['last_contact'] != NULL && $data['node']['last_contact'] != '' ) {
+                       $last_contact = $data['node']['last_contact'];
+               } else {
+                       $last_contact = NULL;
+               }
+               if( $last_contact != NULL ) {
+                       $last_contact_str = timeDiff($last_contact);
+               } else {
+                       $last_contact_str = "Never";
+               }
+               $data['last_contact_str'] = $last_contact_str;
+               return $data;
+       }
+
+       function stage8_rebootpcu($pcu_id, $site_id, $node_id)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->helper('download');
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['node_id'] = intval($node_id);
+               $data['site_id'] = intval($site_id);
+               $data['stage'] = 8;
+               $data = $this->get_stage8_data($person, $data);
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage8_rebootpcu', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function reboot($site_id, $pcu_id, $node_id)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->helper('download');
+               $this->load->library('validation');
+               $person = new Person($plc->person);
+
+               $data = array();
+               $data['site_id'] = intval($site_id);
+               $data['node_id'] = intval($node_id);
+               $data['pcu_id'] = intval($pcu_id);
+               $data['stage'] = 8;
+               $this->reboot_node($data);
+               $data = $this->get_stage8_data($person, $data);
+
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage8_rebootpcu', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function complete($site_id, $pcu_id, $node_id)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->helper('download');
+               $this->load->library('validation');
+
+               $data = array();
+               $data['site_id'] = $site_id;
+               $data['stage'] = 9;
+
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage9_complete', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function get_stage8_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['node']  = $this->getnode($data['node_id']);
+               $data['site']  = $this->getsite($data['node']['site_id']);
+               if( $data['node']['last_contact'] != NULL && $data['node']['last_contact'] != '' ) {
+                       $last_contact = $data['node']['last_contact'];
+               } else {
+                       $last_contact = NULL;
+               }
+               if( $last_contact != NULL ) {
+                       $last_contact_str = timeDiff($last_contact);
+               } else {
+                       $last_contact_str = "Never";
+               }
+               $data['last_contact_str'] = $last_contact_str;
+               return $data;
+       }
+
+       function reboot_node(&$data)
+       {
+               global $api, $plc;
+               $hostname = $data['node_id'];
+               $api->UpdateNode( $hostname, array( "boot_state" => 'rins') );
+               $ret = $api->RebootNodeWithPCU( $hostname );
+               if ( $ret != 0 ) {
+                       $data['error'] = $api->error();
+               }
+               $data['error'] = $api->error();
+       }
+}
+?>
diff --git a/application/controllers/download.php b/application/controllers/download.php
new file mode 100644 (file)
index 0000000..06e1737
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+
+require_once 'plc_login.php'; // Require login
+require_once 'plc_session.php'; // Get session and API handles
+global $plc, $api, $adm;
+
+// Print header
+require_once 'plc_drupal.php';
+
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+include 'plc_objects.php';
+
+
+class Download extends Controller {
+       
+       var $pcu_id = 0;
+       function stage5_bootimage($pcu_id=0, $site_id=0, $node_id=0)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+
+               # TODO: if result is false, redirect to beginning.
+               /*$result = $this->validation->run();*/
+               /*print "RESULT: ".$result . "<br>";*/
+               /*print $this->validation->error_string . "<br>";*/
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['node_id'] = intval($node_id);
+               $data['site_id'] = intval($site_id);
+               $data['stage'] = 5;
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage5_bootimage', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function stage6_download($pcu_id=0, $site_id=0, $node_id=0)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->helper('download');
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+
+               $fields['action']  = "Download Action";
+               $this->validation->set_fields($fields);
+
+               $rules['action']        = "required";
+               $this->validation->set_rules($rules);
+
+               # TODO: if result is false, redirect to beginning.
+               $result = $this->validation->run();
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['node_id'] = intval($node_id);
+               $data['site_id'] = intval($site_id);
+               $data['action'] = $this->validation->action;
+               $data['stage'] = 6;
+               $data['generic_iso_name'] = $this->get_bootcd_version();
+               $data = $this->get_stage6_data($person, $data);
+               print $this->validation->error_string . "<br>";
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage6_download', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function getnode($node_id)
+       {
+               global $api, $plc;
+               $plc_node_list = $api->GetNodes(array('node_id' => intval($node_id) ));
+               return $plc_node_list[0];
+       }
+
+       function get_stage6_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['api'] = $api;
+               $data['has_primary'] = 1;
+               $node_detail = $this->getnode($data['node_id']);
+               $data['node_detail'] = $node_detail;
+               $node_id = $data['node_id'];
+               $action = $_REQUEST['action'];
+               switch ($action) {
+
+                       case "download-generic-iso":
+                       case "download-generic-usb":
+                  
+                               if ($action=="download-generic-iso") {
+                                       $boot_action="generic-iso";
+                                       $basename=PLC_NAME."-BootCD.iso";
+                               } else {
+                                       $boot_action="generic-usb";
+                                       $basename=PLC_NAME."-BootCD.usb";
+                               }
+
+                               $api->UpdateNode( $hostname, array( "boot_state" => 'disable',
+                                                                                                       "version" => $this->get_bootcd_version() ) );
+                               /* exits on success */
+                               $success = $this->deliver_bootmedium($node_id, $boot_action, $basename);
+                               if (! $success ) {
+                                       $error="Unexpected error from deliver_bootmedium - probably wrong directory modes";
+                                       print ("<div class='plc-error'> $error </div>\n");
+                                       print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
+                                       return ;
+                               }
+                               break;
+
+                       case "download-node-floppy-with-iso":
+                       case "download-node-floppy-with-usb":
+                       case "download-node-floppy":
+                       case "download-node-iso":
+                       case "download-node-usb":
+                       case "download-node-usb-partition":
+                  
+                               $return= $api->GetNodes( array( $node_id ) );
+                               $node_detail= $return[0];
+
+                               // non-admin people need to be affiliated with the right site
+                               if( !in_array( 10, $person->data['role_ids'] ) ) {
+                                       $node_site_id = $node_detail['site_id'];
+                                       $in_site = in_array ($node_site_id,$person->data['site_ids']);
+                                       if( ! $in_site) {
+                                               $error= "Insufficient permission. You cannot create configuration files for this node.";
+                                       }
+                               }
+
+                               $hostname= $node_detail['hostname'];
+                               $return= $api->GetNodeNetworks( array( "node_id" => $node_id ), NULL );
+                  
+                               $can_gen_config= 1;
+                               $data['has_primary']= 0;
+                  
+                               if( count($return) > 0 ) {
+                                       foreach( $return as $node_network_detail ) {
+                                               if( $node_network_detail['is_primary'] == true ) {
+                                                       $data['has_primary']= 1;
+                                                       break;
+                                               }
+                                       }
+                                       $data['node_network_detail'] = $node_network_detail;
+                               }
+
+                               if( !$data['has_primary'] ) {
+                                       $can_gen_config= 0;
+                               } else {
+                                       if( $node_detail['hostname'] == "" ) {
+                                               $can_gen_config= 0;
+                                               $node_detail['hostname']= "<i>Missing</i>";
+                                       }
+                        
+                                       $fields= array("method","ip");
+                                       foreach( $fields as $field ) {
+                                               if( $node_network_detail[$field] == "" ) {
+                                                       $can_gen_config= 0;
+                                                       $node_network_detail[$field]= "<i>Missing</i>";
+                                               }
+                                       }
+
+                                       if( $node_network_detail['method'] == "static" ) {
+                                               $fields= array("gateway","netmask","network","broadcast","dns1");
+                                               foreach( $fields as $field ) {
+                                                       if( $node_network_detail[$field] == "" ) {
+                                                               $can_gen_config= 0;
+                                                               $node_network_detail[$field]= "<i>Missing</i>";
+                                                       }
+                                               }
+                                       }
+
+                                       if( $node_network_detail['method'] != "static" && $node_network_detail['method'] != "dhcp" ) {
+                                               $can_gen_config= 0;
+                                               $node_network_detail['method']= "<i>Unknown method</i>";
+                                       }
+                               }
+
+                               if( $can_gen_config && isset($_REQUEST['download']) ) {
+                                       $download = $_REQUEST['download'];
+                                       if (method_exists($api, "GetBootMedium"))
+                                               $file_contents= $api->GetBootMedium($node_id, "node-floppy", "");
+                                       else
+                                               $file_contents= $api->GenerateNodeConfFile($node_id, true);
+               
+                                       switch ($action) {
+                                               case 'download-node-floppy-with-iso':
+                                               case 'download-node-floppy-with-usb':
+                                               case 'download-node-floppy':
+                                                       $boot_action='node-floppy';
+                                                       $basename = "plnode.txt";
+                                                       break;
+                                               case 'download-node-iso':
+                                                       $boot_action='node-iso';
+                                                       $basename = "$hostname.iso";
+                                                       break;
+                                               case 'download-node-usb':
+                                                       $boot_action='node-usb';
+                                                       $basename = "$hostname.usb";
+                                                       break;
+                                               case "download-node-usb-partition":
+                                                       $boot_action='node-usb-partition';
+                                                       $basename = "$hostname-partition.usb";
+                                                       break;
+                                       }        
+                                       if ($action != 'download-node-floppy')
+                                       {
+                                               $api->UpdateNode( $hostname, array( "boot_state" => 'disable',
+                                                                                 "version" => $this->get_bootcd_version() ) );
+                                       }
+                                       /* exits on success */
+                                       $success = $this->deliver_bootmedium($node_id, $boot_action, $basename);
+                                       if (! $success ) {
+                                               $error="Unexpected error from deliver_bootmedium - probably wrong directory modes";
+                                               print ("<div class='plc-error'> $error </div>\n");
+                                               print ("<p><a href='/db/nodes/index.php?id=$node_id'>Back to node </a>\n");
+                                               return ;
+                                       }
+                               }
+                               $action_labels = array (
+                                   'download-node-floppy' => 'textual node config (for floppy)' ,
+                                   'download-node-floppy-with-iso' => 'textual node config (for floppy)' ,
+                                   'download-node-floppy-with-usb' => 'textual node config (for floppy)' ,
+                                       'download-node-iso' => 'ISO image',
+                                       'download-node-usb-partition' => 'USB image',
+                                       'download-node-usb' => 'USB image' );
+
+                               $format = $action_labels [ $action ] ;
+                               /*drupal_set_title("Download boot material for $hostname");*/
+                       break;
+                
+                       default:
+                               echo "Unknown action $action.";
+                               exit();
+                       break;
+               }
+               $data['format'] = $format;
+               $data['can_gen_config'] = $can_gen_config;
+               return $data;
+       }
+       function get_bootcd_version()
+       {
+               $BOOTCD="/usr/share/bootcd";
+               $BOOTCDVERSION="$BOOTCD/build/version.txt";
+               $version = trim(file_get_contents($BOOTCDVERSION));
+               $bootcd_version = PLC_NAME . "-BootCD-".$version;
+               return $bootcd_version;
+       }
+
+       function deliver_bootmedium($node_id, $action, $filename)
+       {
+               global $api;
+               ini_set("memory_limit","300M");
+               $options = array();
+               switch ($action) {
+                       case "node-usb-partition":
+                               $action = "node-usb";
+                               $options[] = "partition";
+                               break;
+               }        
+               $b64_data = $api->GetBootMedium($node_id,$action,"", $options);
+               $error= $api->error();
+               if ( empty($error) )
+               {
+                       if ( $action == "node-floppy" )
+                       {
+                               # data comes back in plain text for node-floppy.
+                               $data = $b64_data;
+                       } else {
+                               $data = base64_decode($b64_data);
+                       }
+                       $size = strlen($data);
+                       /* exits on success */
+                       force_download($filename, $data);
+               }
+               return False;
+       }
+
+}
+?>
diff --git a/application/controllers/index.html b/application/controllers/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/controllers/register.php b/application/controllers/register.php
new file mode 100644 (file)
index 0000000..f7f330d
--- /dev/null
@@ -0,0 +1,716 @@
+<?php
+
+require_once 'plc_login.php'; // Require login
+require_once 'plc_session.php'; // Get session and API handles
+global $plc, $api, $adm;
+
+// Print header
+require_once 'plc_drupal.php';
+
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+include 'plc_objects.php';
+
+
+class Register extends Controller {
+       
+       var $pcu_id = 0;
+       function index()
+       {
+               $this->load->helper(array('form', 'url'));
+               $data=array();
+               $data['stage'] = 0;
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage0', $data);
+               $this->load->view('footer', $data);
+       }
+       function stage1_addpcu()
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+
+               $rules['hostname']  = "trim|required";
+               $rules['ip']            = "trim|required|valid_ip";
+               $rules['username']  = "trim";
+               $rules['password']  = "trim|required";
+               $rules['notes']         = "trim";
+               $this->validation->set_rules($rules);
+
+               $fields['hostname']  = "Hostname";
+               $fields['ip']           = "IP Address";
+               $fields['username']  = "Username";
+               $fields['password']  = "Password";
+               $this->validation->set_fields($fields);
+
+               $person = new Person($plc->person);
+               $data = array();
+               if ($this->validation->run() == TRUE)
+               {
+                       /* b/c the submit is valid, it doesn't matter if pcu_register is set */
+                       $this->pcu_id = $this->add_pcu($data);
+               }
+               $data = $this->get_stage1_data($person, $data);
+               $data['stage'] = 1;
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage1_pcu_choose', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function add_pcu(&$data)
+       {
+               global $api, $plc;
+               /* add pcu, get pcu info */
+               $site_id = intval( $_REQUEST['site_id'] );
+               $fields= array( 'protocol'=>    '',
+                                               'model'=>               $_REQUEST['model'], 
+                                               'hostname'=>    $this->validation->hostname,
+                                               'ip'=>                  $this->validation->ip,
+                                               'username'=>    $this->validation->username, 
+                                               'password'=>    $this->validation->password, 
+                                               'notes'=>               $_REQUEST['notes'], );
+               $pcu_id= $api->AddPCU( $site_id, $fields );
+
+               if( $pcu_id == 0 ) {
+                       $data['error'] = $api->error();
+                       print $data['error'];
+               }
+               $data['pcu_id'] = $pcu_id;
+               
+               return $pcu_id;
+       }
+
+       function get_stage1_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['default_site_list'] = $person->getSites();
+               $data['pcu_types'] = $api->GetPCUTypes(NULL, array('model', 'name'));
+               $data['pcu_list'] = $this->getpculist($person);
+               $data['site_list'] = $this->getsitelist($person);
+               return $data;
+       }
+
+       function getpculist($person)
+       {
+               global $api, $plc;
+               $plc_pcu_list = $api->GetPCUs(array('site_id' => $person->getSites()));
+               return PlcObject::constructList('PCU', $plc_pcu_list);
+       }
+
+       function getsitelist($person)
+       {
+               global $api, $plc;
+               // get sites depending on role and sites associated.
+               if( $person->isAdmin() ) {
+                       $site_info= $api->GetSites( NULL, array( "name", "site_id", "login_base" ) );
+               } else {
+                       $site_info= $api->GetSites( $person->getSites(), array( "name", "site_id", "login_base" ) );
+               }
+               sort_sites( $site_info );
+               return $site_info;
+       }
+
+       var $run_update = True;
+       var $disp_errors = True;
+       function stage2_confirmpcu()
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+
+               if ( isset($_REQUEST['pcu_choose']) ) {
+                       $rules['pcu_id']  = "required";
+                       $this->validation->set_rules($rules);
+                       $fields['pcu_id']  = "PCU id";
+                       $this->validation->set_fields($fields);
+
+                       $result = $this->validation->run();
+                       /* I don't know, shouldn't we redirect to the first stage in this case? */
+                       $this->run_update = False;
+                       $this->disp_errors = False;
+                       print $this->validation->error_string . "<br>";
+
+               } else {
+                       # Information update
+
+                       $rules['pcu_id']  = "required";
+                       $rules['hostname']  = "trim|required";
+                       $rules['ip']            = "trim|required|valid_ip";
+                       $rules['username']  = "trim";
+                       $rules['password']  = "trim|required";
+                       $rules['notes']         = "trim";
+                       $this->validation->set_rules($rules);
+
+                       $fields['pcu_id']  = "PCU id";
+                       $fields['hostname']  = "Hostname";
+                       $fields['ip']           = "IP Address";
+                       $fields['username']  = "Username";
+                       $fields['password']  = "Password";
+                       $this->validation->set_fields($fields);
+
+                       if ( $this->validation->run() == FALSE )
+                       {
+                               print $this->validation->error_string . "<br>";
+                               $this->run_update = False;
+                       } 
+               }
+               $data = $this->get_stage2_data($person);
+               $data['stage'] = 2;
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage2_pcu_confirm', $data);
+               $this->load->view('footer', $data);
+
+       }
+
+       function update_pcu($data)
+       {
+               global $api, $plc;
+               /* add pcu, get pcu info */
+               $pcu_id = intval($this->validation->pcu_id);
+               $fields= array( 'protocol'=>    '',
+                                               'model'=>               $_REQUEST['model'], 
+                                               'hostname'=>    $this->validation->hostname,
+                                               'ip'=>                  $this->validation->ip,
+                                               'username'=>    $this->validation->username, 
+                                               'password'=>    $this->validation->password, 
+                                               'notes'=>               $_REQUEST['notes'], );
+               $ret = $api->UpdatePCU( $pcu_id, $fields );
+
+               if( $ret != 1 ) {
+                       $data['error'] = $api->error();
+                       print $data['error'];
+               }
+               
+               return $pcu_id;
+       }
+
+       function get_stage2_data($person)
+       {
+               global $api, $plc;
+
+               $data = array();
+               if ( $this->run_update && isset($_REQUEST['pcu_update']) ) 
+               {
+                       $this->update_pcu($data);
+               } 
+
+               if ( isset($_REQUEST['pcu_id']) ) 
+               {
+                       $pcu_id = intval($_REQUEST['pcu_id']);
+                       $pcu_data = $api->GetPCUs(array('pcu_id'=>$pcu_id));
+                       $pcu = new PCU($pcu_data[0]);
+                       $data['pcu'] = $pcu;
+                       $data['pcu_id'] = $pcu_id;
+                       $data['site_id'] = $pcu_data[0]['site_id'];
+               } 
+
+               $data['default_site_list'] = $person->getSites();
+               $data['pcu_types'] = $api->GetPCUTypes(NULL, array('model', 'name'));
+               $data['pcu_site'] = $api->GetSites( $pcu_data[0]['site_id'], array( "name", "site_id", "login_base" ) );
+               return $data;
+       }
+
+       var $node_id = 0;
+       function stage3_addnode($pcu_id, $site_id)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['site_id'] = intval($site_id);
+
+               if ( isset($_REQUEST['pcu_proceed']) ) {
+                       $rules['hostname']  = "";
+                       $rules['model']         = "";
+                       $rules['method']        = "";
+                       $rules['ip']            = "";
+                       $rules['netmask']  = "";
+                       $rules['network']  = "";
+                       $rules['gateway']  = "";
+                       $rules['broadcast']  = "";
+                       $rules['dns1']  = "";
+                       $rules['dns2']  = "";
+                       $this->validation->set_rules($rules);
+                       $fields['hostname']  = "Hostname";
+                       $fields['model']        = "Model";
+                       $fields['method']       = "Method";
+                       $fields['ip']           = "IP Address";
+                       $fields['netmask']              = "Netmask Address";
+                       $fields['network']              = "Network Address";
+                       $fields['gateway']              = "Gateway Address";
+                       $fields['broadcast']    = "Broadcast Address";
+                       $fields['dns1']                 = "Primary DNS Address";
+                       $fields['dns2']                 = "Secondary DNS Address";
+                       $this->validation->set_fields($fields);
+
+                       $result = $this->validation->run();
+                       /*print "RESULT: ".$result . "<br>";*/
+                       # TODO: if result is false, redirect to beginning.
+                       $this->disp_errors = False;
+                       print $this->validation->error_string . "<br>";
+               } else {
+                       $rules['hostname']  = "trim|required";
+                       $rules['model']         = "trim|required";
+                       $rules['method']        = "required";
+                       $rules['ip']            = "trim|required|valid_ip";
+                       if ( isset ($_REQUEST['method']) && $_REQUEST['method'] == 'static' )
+                       {
+                               $rules['netmask']  = "trim|valid_ip";
+                               $rules['network']  = "trim|valid_ip";
+                               $rules['gateway']  = "trim|valid_ip";
+                               $rules['broadcast']  = "trim|valid_ip";
+                               $rules['dns1']  = "trim|valid_ip";
+                               $rules['dns2']  = "trim|valid_ip";
+                       } else {
+                               $rules['netmask']  = "";
+                               $rules['network']  = "";
+                               $rules['gateway']  = "";
+                               $rules['broadcast']  = "";
+                               $rules['dns1']  = "";
+                               $rules['dns2']  = "";
+                       }
+                       $this->validation->set_rules($rules);
+
+                       $fields['hostname']  = "Hostname";
+                       $fields['model']        = "Model";
+                       $fields['method']       = "Method";
+                       $fields['ip']           = "IP Address";
+                       $fields['netmask']              = "Netmask Address";
+                       $fields['network']              = "Network Address";
+                       $fields['gateway']              = "Gateway Address";
+                       $fields['broadcast']    = "Broadcast Address";
+                       $fields['dns1']                 = "Primary DNS Address";
+                       $fields['dns2']                 = "Secondary DNS Address";
+                       $this->validation->set_fields($fields);
+
+                       if ($this->validation->run() == TRUE)
+                       {
+                               /* b/c the submit is valid, all values are minimally consistent. */
+                               $this->node_id = $this->add_node($data);
+                       }
+               }
+               $data = $this->get_stage3_data($person, $data);
+               $data['stage'] = 3;
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage3_node_choose', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function add_node(&$data)
+       {
+               global $api, $plc;
+               print "Adding Node\n<br>";
+               $hostname = trim($_REQUEST['hostname']);
+               $model= trim($_REQUEST['model']);
+               $method = trim($_REQUEST['method']);
+               $ip = trim($_REQUEST['ip']);
+               if ( $method == 'static' )
+               {
+                       $netmask = trim($_REQUEST['netmask']);
+                       $network = trim($_REQUEST['network']);
+                       $gateway = trim($_REQUEST['gateway']);
+                       $broadcast = trim($_REQUEST['broadcast']);
+                       $dns1 = trim($_REQUEST['dns1']);
+                       $dns2 = trim($_REQUEST['dns2']);
+               }
+
+               // used to generate error strings for static fields only
+               $static_fields= array();
+               $static_fields['netmask']= "Netmask address";
+               $static_fields['network']= "Network address";
+               $static_fields['gateway']= "Gateway address";
+               $static_fields['broadcast']= "Broadcast address";
+               $static_fields['dns1']= "Primary DNS address";
+               
+               if( $method == 'static' )
+               {
+                       if( !is_valid_network_addr($network,$netmask) )
+                       {
+                               $errors[] = "The network address does not coorespond to the netmask";
+                       }
+               }
+
+               if( !isset($errors) || count($errors) == 0 )
+               {
+                       // add new node and its network
+                       $optional_vals= array( "hostname"=>$hostname, "model"=>$model );
+
+                       $site_id= $data['site_id'];
+                       $node_id= $api->AddNode( intval( $site_id ), $optional_vals );
+                       if( $node_id <= 0 ) {
+                               $data['error'] = $api->error();
+                               print $data['error'];
+                       }
+
+                       // now, try to add the network.
+                       $optional_vals= array();
+                       $optional_vals['is_primary']= true;
+                       $optional_vals['ip']= $ip;
+                       $optional_vals['type']= 'ipv4';
+                       $optional_vals['method']= $method;
+                       
+                       if( $method == 'static' )
+                       {
+                               $optional_vals['gateway']= $gateway;
+                               $optional_vals['network']= $network;
+                               $optional_vals['broadcast']= $broadcast;
+                               $optional_vals['netmask']= $netmask;
+                               $optional_vals['dns1']= $dns1;
+                               if (!empty($dns2)) {
+                                       $optional_vals['dns2']= $dns2;
+                               }
+                       }
+
+                       $nodenetwork_id= $api->AddNodeNetwork( $node_id, $optional_vals);
+                       if( $nodenetwork_id <= 0 ) {
+                               $data['error'] = $api->error();
+                               print $data['error'];
+                       }
+
+                       $success = $api->AddNodeToPCU( $node_id, $data['pcu_id'], 1);
+                       if( !isset($success) || $success <= 0 ) {
+                               $data['error'] = $api->error();
+                               print $data['error'];
+                       }
+               }
+
+
+               $data['node_id'] = $node_id;
+               if ( isset($errors) ) { $data['errors'] = $errors; }
+               
+               return $node_id;
+       }
+
+       function get_stage3_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['default_site_list'] = array($data['site_id']);
+               $data['node_list'] = $this->getnodelist($data['site_id']);
+               $data['site'] = $this->getsite($data['site_id']);
+               return $data;
+       }
+
+       function getnodelist($site_id)
+       {
+               global $api, $plc;
+               $plc_node_list = $api->GetNodes(array('site_id' => intval($site_id) ));
+               return PlcObject::constructList('Node', $plc_node_list);
+       }
+
+       function getsite($site_id)
+       {
+               global $api, $plc;
+               $site_info = $api->GetSites($site_id, array( "name", "site_id", "login_base" ) );
+               return $site_info[0];
+       }
+
+       function stage45_mappcu($pcu_id=0, $site_id=0, $node_id=0)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+
+               $fields['port_number']  = "Port Number";
+               $this->validation->set_fields($fields);
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['site_id'] = intval($site_id);
+               $data['node_id'] = intval($node_id);
+
+               if ( isset($_REQUEST['node_confirm']) ) {
+                       /* skip the rules, since we're just displaying the page. */
+                       $rules['port_number']           = "";
+                       $this->validation->set_rules($rules);
+
+               } else {
+                       /* setup rules, to validate the form data. */
+                       $rules['port_number']           = "trim|required|intval";
+                       $this->validation->set_rules($rules);
+
+                       $result = $this->validation->run();
+                       if ( ! $result ) {
+                               print "ERROR";
+                       } else {
+                               $port = $this->validation->port_number;
+                               /* if we do not delete the node from the PCU first, a fault is raised */
+                               $ret = $api->DeleteNodeFromPCU($data['node_id'], $data['pcu_id']);
+                               $ret = $api->AddNodeToPCU($data['node_id'], $data['pcu_id'], $port);
+                               if ( $ret != 1 )
+                               {
+                                       $data['error'] = $api->error();
+                                       print $data['error'];
+                               }
+                       }
+                       $this->disp_errors = False;
+                       print $this->validation->error_string . "<br>";
+               }
+
+
+               $data['node'] = $this->getnode($data['node_id']);
+               $api_pcus = $api->GetPCUs($data['node']->pcu_ids);
+               $pcu = $api_pcus[0];
+
+               # NOTE: find index of node id, then pull out that index of
+               $index = array_search($data['node_id'], $pcu['node_ids']);
+               $data['pcu_port'] = $pcu['ports'][$index];
+               $data['stage'] = 4.5;
+               #$data = $this->get_stage4_data($person, $data);
+               $this->load->view('header', $data);
+               $this->load->view('debug', $data);
+               $this->load->view('stage45_pcuport', $data);
+               $this->load->view('footer', $data);
+       }
+
+       function stage4_confirmnode($pcu_id=0, $site_id=0)
+       {
+               global $api, $plc;
+               $this->load->helper(array('form', 'url'));
+               $this->load->library('validation');
+               
+               $this->validation->set_error_delimiters('<span class="error">', '</span>');
+               $person = new Person($plc->person);
+
+               $fields['hostname']     = "Hostname";
+               $fields['model']        = "Model";
+               $fields['method']       = "Method";
+               $fields['ip']           = "IP Address";
+               $fields['netmask']      = "Netmask Address";
+               $fields['network']      = "Network Address";
+               $fields['gateway']      = "Gateway Address";
+               $fields['broadcast']= "Broadcast Address";
+               $fields['dns1']         = "Primary DNS Address";
+               $fields['dns2']         = "Secondary DNS Address";
+               $fields['node_id']  = "NODE id";
+               $this->validation->set_fields($fields);
+
+               $data = array();
+               $data['pcu_id'] = intval($pcu_id);
+               $data['site_id'] = intval($site_id);
+
+               if ( isset($_REQUEST['node_choose']) ) {
+                       $rules['node_id']       = "required|intval";
+                       $rules['hostname']      = "";
+                       $rules['model']         = "";
+                       $rules['method']        = "";
+                       $rules['ip']            = "";
+                       $rules['netmask']       = "";
+                       $rules['network']       = "";
+                       $rules['gateway']       = "";
+                       $rules['broadcast']     = "";
+                       $rules['dns1']          = "";
+                       $rules['dns2']          = "";
+                       $this->validation->set_rules($rules);
+
+                       $result = $this->validation->run();
+                       /*print "RESULT: ".$result . "<br>";*/
+                       # TODO: if result is false, redirect to beginning.
+                       $this->disp_errors = False;
+                       print $this->validation->error_string . "<br>";
+               } else {
+                       $rules['hostname']  = "trim|required";
+                       $rules['model']         = "trim|required";
+                       $rules['method']        = "required";
+                       $rules['ip']            = "trim|required|valid_ip";
+                       if ( isset ($_REQUEST['method']) && $_REQUEST['method'] == 'static' )
+                       {
+                               $rules['netmask']  = "trim|valid_ip";
+                               $rules['network']  = "trim|valid_ip";
+                               $rules['gateway']  = "trim|valid_ip";
+                               $rules['broadcast']  = "trim|valid_ip";
+                               $rules['dns1']  = "trim|valid_ip";
+                               $rules['dns2']  = "trim";
+                       } else {
+                               # NOTE: There are no conditions that must be met for these fields.
+                               $rules['netmask']  = "";
+                               $rules['network']  = "";
+                               $rules['gateway']  = "";
+                               $rules['broadcast']  = "";
+                               $rules['dns1']  = "";
+                               $rules['dns2']  = "";
+                       }
+                       $rules['node_id']  = "required|intval";
+                       $this->validation->set_rules($rules);
+
+                       if ($this->validation->run() == TRUE)
+                       {
+                               /* b/c the submit is valid, all values are minimally consistent. */
+                               $this->node_id = $this->update_node($data);
+                       }
+               }
+               $data['node_id'] = intval($this->validation->node_id);
+               $data['stage'] = 4;
+               if ( $this->checknodeid($data['node_id']) )
+               {
+                       $data = $this->get_stage4_data($person, $data);
+                       $this->load->view('header', $data);
+                       $this->load->view('debug', $data);
+                       $this->load->view('stage4_node_confirm', $data);
+                       $this->load->view('footer', $data);
+               } else {
+                       print "You must select a valid Node before continuing.";
+               }
+       }
+
+       function update_node(&$data)
+       {
+               # TODO: RECODE To update values instead of adding them...
+               global $api, $plc;
+               $hostname = trim($_REQUEST['hostname']);
+               $model= trim($_REQUEST['model']);
+               $node_id = intval($this->validation->node_id);
+               $ret = $api->UpdateNode( $node_id, array('hostname' => $hostname, 
+                                                                                 'model' => $model));
+               if( $ret <= 0 ) {
+                       $data['error'] = $api->error();
+                       print $data['error'];
+               }
+
+               $api_node_list = $api->GetNodes($node_id);
+               if ( count($api_node_list) > 0 )
+               {
+                       $node_obj = new Node($api_node_list[0]);
+               } else {
+                       print "broken!!!";
+                       exit (1);
+               }
+               
+
+               $optional_vals= array();
+
+               $method = trim($_REQUEST['method']);
+               if ( $node_obj->method != $method ) {
+                       $optional_vals['method']= $method;
+               }
+
+               $ip = trim($_REQUEST['ip']);
+               if ( $node_obj->ip != $ip ) {
+                       $optional_vals['ip']= $ip;
+               }
+
+               // used to generate error strings for static fields only
+               $static_fields= array();
+               $static_fields['netmask']= "Netmask address";
+               $static_fields['network']= "Network address";
+               $static_fields['gateway']= "Gateway address";
+               $static_fields['broadcast']= "Broadcast address";
+               $static_fields['dns1']= "Primary DNS address";
+
+               if ( $method == 'static' )
+               {
+                       $netmask = trim($_REQUEST['netmask']);
+                       $network = trim($_REQUEST['network']);
+                       $gateway = trim($_REQUEST['gateway']);
+                       $broadcast = trim($_REQUEST['broadcast']);
+                       $dns1 = trim($_REQUEST['dns1']);
+                       $dns2 = trim($_REQUEST['dns2']);
+
+                       if( !is_valid_network_addr($network,$netmask) )
+                       {
+                               $errors[] = "The network address does not coorespond to the netmask";
+                       }
+               }
+
+               if ( !isset($errors) || count($errors) == 0 )
+               {
+                       // now, try to add the network.
+                       if( $method == 'static' )
+                       {
+                               if ( $node_obj->gateway != $gateway ) {
+                                       $optional_vals['gateway']= $gateway;
+                               }
+                               if ( $node_obj->network != $network ) {
+                                       $optional_vals['network']= $network;
+                               }
+                               if ( $node_obj->broadcast != $broadcast ) {
+                                       $optional_vals['broadcast']= $broadcast;
+                               }
+                               if ( $node_obj->netmask != $netmask ) {
+                                       $optional_vals['netmask']= $netmask;
+                               }
+                               if ( $node_obj->dns1 != $dns1 ) {
+                                       $optional_vals['dns1']= $dns1;
+                               }
+                               if ( $node_obj->dns2 != $dns2 ) {
+                                       $optional_vals['dns2']= $dns2;
+                               }
+                       }
+
+                       if ( count($optional_vals) > 0 )
+                       {
+                               print_r($optional_vals);
+                               $ret = $api->UpdateNodeNetwork( $node_obj->nodenetwork_id, $optional_vals);
+                               if( $ret <= 0 ) {
+                                       $data['error'] = $api->error();
+                                       print $data['error'];
+                               }
+                       }
+               }
+
+               $data['node_id'] = $node_id;
+               if ( isset($errors) ) { $data['errors'] = $errors; }
+               
+               return $node_id;
+       }
+
+       function get_stage4_data($person, $data=NULL)
+       {
+               global $api, $plc;
+               if ( $data == NULL ){
+                   $data = array();
+               }
+               $data['node'] = $this->getnode($data['node_id']);
+               $data['site'] = $this->getsite($data['site_id']);
+               /*print "SITENAME: " . $data['site']['login_base'] . "<BR>";*/
+               return $data;
+       }
+
+       function checknodeid($node_id)
+       {
+               global $api, $plc;
+               $plc_node_list = $api->GetNodes(array('node_id' => intval($node_id) ), array('node_id'));
+               if ( count($plc_node_list) > 0 ) {
+                       return True;
+               } else {
+                       return False;
+               }
+       }
+
+       function getnode($node_id)
+       {
+               global $api, $plc;
+               $plc_node_list = $api->GetNodes(array('node_id' => intval($node_id) ));
+               if ( count($plc_node_list) > 0 )
+               {
+                       return new Node($plc_node_list[0]);
+               } else {
+                       return NULL;
+               }
+       }
+
+}
+?>
diff --git a/application/controllers/welcome.php b/application/controllers/welcome.php
new file mode 100644 (file)
index 0000000..ec16000
--- /dev/null
@@ -0,0 +1,17 @@
+<?php\r
+\r
+class Welcome extends Controller {\r
+\r
+       function Welcome()\r
+       {\r
+               parent::Controller();   \r
+       }\r
+       \r
+       function index()\r
+       {\r
+               $this->load->view('welcome_message');\r
+       }\r
+}\r
+\r
+/* End of file welcome.php */\r
+/* Location: ./system/application/controllers/welcome.php */
\ No newline at end of file
diff --git a/application/errors/error_404.php b/application/errors/error_404.php
new file mode 100644 (file)
index 0000000..bfe9444
--- /dev/null
@@ -0,0 +1,35 @@
+<?php header("HTTP/1.1 404 Not Found"); ?>
+<html>
+<head>
+<title>404 Page Not Found</title>
+<style type="text/css">
+
+body {
+background-color:      #fff;
+margin:                                40px;
+font-family:           Lucida Grande, Verdana, Sans-serif;
+font-size:                     12px;
+color:                         #000;
+}
+
+#content  {
+border:                                #999 1px solid;
+background-color:      #fff;
+padding:                       20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:           normal;
+font-size:                     14px;
+color:                         #990000;
+margin:                        0 0 4px 0;
+}
+</style>
+</head>
+<body>
+       <div id="content">
+               <h1><?php echo $heading; ?></h1>
+               <?php echo $message; ?>
+       </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/application/errors/error_db.php b/application/errors/error_db.php
new file mode 100644 (file)
index 0000000..1ce52df
--- /dev/null
@@ -0,0 +1,34 @@
+<html>
+<head>
+<title>Database Error</title>
+<style type="text/css">
+
+body {
+background-color:      #fff;
+margin:                                40px;
+font-family:           Lucida Grande, Verdana, Sans-serif;
+font-size:                     12px;
+color:                         #000;
+}
+
+#content  {
+border:                                #999 1px solid;
+background-color:      #fff;
+padding:                       20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:           normal;
+font-size:                     14px;
+color:                         #990000;
+margin:                        0 0 4px 0;
+}
+</style>
+</head>
+<body>
+       <div id="content">
+               <h1><?php echo $heading; ?></h1>
+               <?php echo $message; ?>
+       </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/application/errors/error_general.php b/application/errors/error_general.php
new file mode 100644 (file)
index 0000000..d861070
--- /dev/null
@@ -0,0 +1,34 @@
+<html>
+<head>
+<title>Error</title>
+<style type="text/css">
+
+body {
+background-color:      #fff;
+margin:                                40px;
+font-family:           Lucida Grande, Verdana, Sans-serif;
+font-size:                     12px;
+color:                         #000;
+}
+
+#content  {
+border:                                #999 1px solid;
+background-color:      #fff;
+padding:                       20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:           normal;
+font-size:                     14px;
+color:                         #990000;
+margin:                        0 0 4px 0;
+}
+</style>
+</head>
+<body>
+       <div id="content">
+               <h1><?php echo $heading; ?></h1>
+               <?php echo $message; ?>
+       </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/application/errors/error_php.php b/application/errors/error_php.php
new file mode 100644 (file)
index 0000000..f085c20
--- /dev/null
@@ -0,0 +1,10 @@
+<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
+
+<h4>A PHP Error was encountered</h4>
+
+<p>Severity: <?php echo $severity; ?></p>
+<p>Message:  <?php echo $message; ?></p>
+<p>Filename: <?php echo $filepath; ?></p>
+<p>Line Number: <?php echo $line; ?></p>
+
+</div>
\ No newline at end of file
diff --git a/application/errors/index.html b/application/errors/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/helpers/index.html b/application/helpers/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/hooks/index.html b/application/hooks/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/index.html b/application/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/language/english/index.html b/application/language/english/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/libraries/index.html b/application/libraries/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/models/index.html b/application/models/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/views/AddConfFile.php b/application/views/AddConfFile.php
new file mode 100644 (file)
index 0000000..729455f
--- /dev/null
@@ -0,0 +1,166 @@
+<script language="javascript">
+
+function updateNodeCombo()
+{
+  node_ids= document.fm.node_ids;
+  nodegroup_ids= document.fm.nodegroup_ids;
+  scope= document.fm.scope;
+
+  for ( var i=0; i < scope.length ; i++ )
+  {
+       if ( scope[i].checked )
+       {
+         switch( scope[i].value )
+         {
+         case "global":
+               node_ids.disabled= 1;
+               nodegroup_ids.disabled= 1;
+               break;
+
+         case "group":
+               node_ids.disabled= 1;
+               nodegroup_ids.disabled= 0;
+               break;
+
+         case "node":
+               node_ids.disabled= 0;
+               nodegroup_ids.disabled= 1;
+               break;
+         }
+       }
+  }
+}
+
+</script>
+
+
+<a href="index.php">Return to listing...</a>
+<form name='fm' action="conffile/add" method="post">
+<input type="hidden" name="submitted" value="1">
+
+<p><table width=100% cellpadding=5 border=0>
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= $this->validation->set_checkbox('enabled', $this->validation->enabled ) ?> 
+                       name="enabled">Enabled</input>
+       <?= $this->validation->enabled_error ?>
+</td>
+</tr>
+<tr>
+<td>File Scope:</td>
+<td>
+<input type='radio' name='scope' value='global' onClick="updateNodeCombo();" <?= ( $scope == "global" ?  "checked" : "" ) ?>> Global<br>
+<input type='radio' name='scope' value='node' onClick="updateNodeCombo();" <?= ( $scope == "node" ?  "checked" : "" ) ?>> Node : 
+       <select name="node_ids">
+       <?php foreach( $nodes as $node ): ?>
+               <option $selected value="<?= $node['node_id'] ?>"><?= $node['hostname'] ?></option>
+       <?php endforeach; ?>
+       </select>
+<br>
+
+<input type='radio' name='scope' value='group' onChange="updateNodeCombo();" <?= ( $scope == "group" ?  "checked" : "" ) ?>> Group : 
+       <select name="nodegroup_ids">
+       <?php foreach( $nodegroups as $nodegroup ): ?>
+                 <option value="<?= $nodegroup['nodegroup_id'] ?>"><?= $nodegroup['name'] ?></option>
+       <?php endforeach; ?>
+       </select></td>
+
+</td>
+</tr>
+
+<tr>
+<td>Source:</td>
+<td><i>http://<?= PLC_BOOT_HOST ?>/</i> 
+<input name="source" value="<?= htmlspecialchars($this->validation->source) ?>" size=40 maxlength=255>
+<?= $this->validation->source_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Destination:</td>
+<td>
+<input name="dest" value="<?= htmlspecialchars($this->validation->dest) ?>" size=40 maxlength=255>
+<?= $this->validation->dest_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Permissions:</td>
+<td>
+<input name="file_permissions" value="<?= htmlspecialchars($this->validation->file_permissions) ?>" size=5 maxlength=20>
+<?= $this->validation->file_permissions_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Owner:</td>
+<td>
+<input name="file_owner" value="<?= htmlspecialchars($this->validation->file_owner) ?>" size=15 maxlength=50>
+<?= $this->validation->file_owner_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Group:</td>
+<td>
+<input name="file_group" value="<?= htmlspecialchars($this->validation->file_group) ?>" size=15 maxlength=50>
+<?= $this->validation->file_group_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Pre-Install Command:</td>
+<td>
+<input name="preinstall_cmd" value='<?= htmlspecialchars($this->validation->preinstall_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->preinstall_cmd_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Post-Install Command:</td>
+<td>
+<input name="postinstall_cmd" value='<?= htmlspecialchars($this->validation->postinstall_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->postinstall_cmd_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Error Command:</td>
+<td>
+<input name="error_cmd" value='<?= htmlspecialchars($this->validation->error_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->postinstall_cmd_error ?>
+<br>
+(run if an error occured, regardless if errors are being ignored)</td>
+</tr>
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= $this->validation->set_checkbox('ignore_cmd_errors', $this->validation->ignore_cmd_errors) ?> 
+                       name="ignore_cmd_errors">Ignore pre/post install command errors</input>
+       <?= $this->validation->ignore_cmd_errors_error?>
+</td>
+</tr>
+
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= $this->validation->set_checkbox('always_update', $this->validation->always_update) ?> 
+                       name="always_update">Always update this file, even if same as original</input>
+       <?= $this->validation->always_update_error?>
+</td>
+</tr>
+
+<tr>
+<td><input type="submit" value="<?= htmlspecialchars($submit_caption) ?>"></td>
+</tr>
+
+
+</table>
+</form>
+<script language="javascript">
+updateNodeCombo();
+</script>
diff --git a/application/views/ListConfFiles.php b/application/views/ListConfFiles.php
new file mode 100644 (file)
index 0000000..c690275
--- /dev/null
@@ -0,0 +1,71 @@
+
+<h2>All current node configuration files</h2>
+
+<p>
+
+<table width=100%>
+<tr>
+<th width=50%>Destination File <font size=-1>[click to view/edit details]</font></th>
+<th width=40%>Scope</th>
+<th width=10%>Enabled</th>
+</tr>
+
+
+<?php 
+       foreach( $all_conf_files as $conf_file )
+    {
+               $conf_file_id  = $conf_file['conf_file_id'];
+               $enabled       = $conf_file['enabled'];
+               $dest          = $conf_file['dest'];
+               $node_id       = $conf_file['node_ids'];
+               $nodegroup_id  = $conf_file['nodegroup_ids'];
+
+               if( $enabled == True )
+                       $enabled= "Yes";
+               else
+                       $enabled= "No";
+
+               // find out what the scope is for this conf file
+               if( count($node_id) == 0 && count($nodegroup_id) == 0)
+               {
+                       // if there is no associate entry, its a global scope
+                       $scope= "global";
+               } else {
+                       if( count($nodegroup_id) == 0 && is_numeric($node_id[0]) )
+                       {
+                               $nodes= $api->GetNodes( $node_id, array("hostname") );
+                                 
+                               $hostname= $nodes[0]["hostname"];
+                               $scope= "node: $hostname";
+                       } elseif(count($node_id) == 0 && is_numeric($nodegroup_id[0]) )
+                       {
+                               $nodegroups= $api->GetNodeGroups( $nodegroup_id );
+                               $group_name= $nodegroups[0]["name"];
+                               $scope= "group: $group_name";
+                       }
+               }
+      
+               print( "<tr>\n<td>" );
+               print( "<a href=\"conffile/update/$conf_file_id\">$dest</a></td>\n" );
+               print( "<td>$scope</td>\n" );
+               print( "<td>$enabled</td>\n</tr>\n" );
+       }
+?>
+
+
+</tr>
+</table>
+
+<p><a href="edit.php?action=create">Create new...</a>
+<br><a href="copy.php">Copy...</a>
+<br><a href="delete.php">Delete...</a>
+
+<p><br>
+<h2>File scope priority</h2>
+
+The following priority is applied to files that have the same destination:
+<ol>
+<li>Files that have a one-node scope
+<li>Files that have a group scope
+<li>Files that have a global scope
+</ol>
diff --git a/application/views/UpdateConfFile.php b/application/views/UpdateConfFile.php
new file mode 100644 (file)
index 0000000..9f13d16
--- /dev/null
@@ -0,0 +1,166 @@
+<script language="javascript">
+
+function updateNodeCombo()
+{
+  node_ids= document.fm.node_ids;
+  nodegroup_ids= document.fm.nodegroup_ids;
+  scope= document.fm.scope;
+
+  for ( var i=0; i < scope.length ; i++ )
+  {
+       if ( scope[i].checked )
+       {
+         switch( scope[i].value )
+         {
+         case "global":
+               node_ids.disabled= 1;
+               nodegroup_ids.disabled= 1;
+               break;
+
+         case "group":
+               node_ids.disabled= 1;
+               nodegroup_ids.disabled= 0;
+               break;
+
+         case "node":
+               node_ids.disabled= 0;
+               nodegroup_ids.disabled= 1;
+               break;
+         }
+       }
+  }
+}
+
+</script>
+
+
+<a href="index.php">Return to listing...</a>
+<?= form_open("conffile/update/$conf_file_id", array('name'=>'fm', 'method'=>'post')) ?>
+<input type="hidden" name="submitted" value="1">
+
+<p><table width=100% cellpadding=5 border=0>
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= ( $enabled ? "checked" : "" ) ?>
+                       name="enabled">Enabled</input>
+       <?= $this->validation->enabled_error ?>
+</td>
+</tr>
+<tr>
+<td>File Scope:</td>
+<td>
+<input type='radio' name='scope' value='global' onClick="updateNodeCombo();" <?= ( $scope == "global" ?  "checked" : "" ) ?>> Global<br>
+<input type='radio' name='scope' value='node' onClick="updateNodeCombo();" <?= ( $scope == "node" ?  "checked" : "" ) ?>> Node : 
+       <select name="node_ids">
+       <?php foreach( $nodes as $node ): ?>
+               <option $selected value="<?= $node['node_id'] ?>"><?= $node['hostname'] ?></option>
+       <?php endforeach; ?>
+       </select>
+<br>
+
+<input type='radio' name='scope' value='group' onChange="updateNodeCombo();" <?= ( $scope == "group" ?  "checked" : "" ) ?>> Group : 
+       <select name="nodegroup_ids">
+       <?php foreach( $nodegroups as $nodegroup ): ?>
+                 <option value="<?= $nodegroup['nodegroup_id'] ?>"><?= $nodegroup['name'] ?></option>
+       <?php endforeach; ?>
+       </select></td>
+
+</td>
+</tr>
+
+<tr>
+<td>Source:</td>
+<td><i>http://<?= PLC_BOOT_HOST ?>/</i> 
+<input name="source" value="<?= htmlspecialchars($source) ?>" size=40 maxlength=255>
+<?= $this->validation->source_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Destination:</td>
+<td>
+<input name="dest" value="<?= htmlspecialchars($dest) ?>" size=40 maxlength=255>
+<?= $this->validation->dest_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Permissions:</td>
+<td>
+<input name="file_permissions" value="<?= htmlspecialchars($file_permissions) ?>" size=5 maxlength=20>
+<?= $this->validation->file_permissions_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Owner:</td>
+<td>
+<input name="file_owner" value="<?= htmlspecialchars($file_owner) ?>" size=15 maxlength=50>
+<?= $this->validation->file_owner_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Group:</td>
+<td>
+<input name="file_group" value="<?= htmlspecialchars($file_group) ?>" size=15 maxlength=50>
+<?= $this->validation->file_group_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Pre-Install Command:</td>
+<td>
+<input name="preinstall_cmd" value='<?= htmlspecialchars($preinstall_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->preinstall_cmd_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Post-Install Command:</td>
+<td>
+<input name="postinstall_cmd" value='<?= htmlspecialchars($postinstall_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->postinstall_cmd_error ?>
+</td>
+</tr>
+
+<tr>
+<td>Error Command:</td>
+<td>
+<input name="error_cmd" value='<?= htmlspecialchars($error_cmd) ?>' size=70 maxlength=1024>
+<?= $this->validation->postinstall_cmd_error ?>
+<br>
+(run if an error occured, regardless if errors are being ignored)</td>
+</tr>
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= $this->validation->set_checkbox('ignore_cmd_errors', $ignore_cmd_errors) ?> 
+                       name="ignore_cmd_errors">Ignore pre/post install command errors</input>
+       <?= $this->validation->ignore_cmd_errors_error?>
+</td>
+</tr>
+
+
+<tr>
+<td></td>
+<td>
+       <input type=checkbox <?= $this->validation->set_checkbox('always_update', $always_update) ?> 
+                       name="always_update">Always update this file, even if same as original</input>
+       <?= $this->validation->always_update_error?>
+</td>
+</tr>
+
+<tr>
+<td><input type="submit" value="<?= htmlspecialchars($submit_caption) ?>"></td>
+</tr>
+
+
+</table>
+</form>
+<script language="javascript">
+updateNodeCombo();
+</script>
diff --git a/application/views/debug.php b/application/views/debug.php
new file mode 100644 (file)
index 0000000..723715c
--- /dev/null
@@ -0,0 +1,5 @@
+<!--
+<?php foreach ( $_REQUEST as $key => $value ): ?>
+       <?= $key ?>  ==  <?= $value ?> <br>
+<?php endforeach; ?>
+-->
diff --git a/application/views/footer.php b/application/views/footer.php
new file mode 100644 (file)
index 0000000..32a5bfb
--- /dev/null
@@ -0,0 +1,15 @@
+       </td>
+</tr>
+<tr>
+       <td align='center'>
+<div id="footer">Copyright Â© 2007 The Trustees of Princeton University</div>
+       </td>
+</tr>
+</table>
+<script type="text/javascript">
+Rounded('plroundedconfirm', 8, 8);
+Rounded('plroundedupdate', 8, 8);
+Rounded('plroundedwhite', 8, 8);
+</script>
+</body>
+</html>
diff --git a/application/views/header.php b/application/views/header.php
new file mode 100644 (file)
index 0000000..45ead67
--- /dev/null
@@ -0,0 +1,20 @@
+<html>
+<head>
+       <!-- How to add the standard CSS files? -->
+       <style type="text/css" media="all">@import "https://www.planet-lab.org/misc/drupal.css";</style>
+       <style type="text/css" media="all">@import "https://www.planet-lab.org/sites/default/themes/chameleon/common.css";</style>
+       <style type="text/css" media="all">@import "https://www.planet-lab.org/sites/default/themes/chameleon/planetlab/style.css";</style>
+       <link rel="shortcut icon" 
+                       href="https://www.planet-lab.org/sites/default/themes/chameleon/planetlab/favicon.ico" type="image/x-icon" />
+       <style type="text/css" media="all">@import "/registerwizard/rounded.css";</style>
+       <script src="/registerwizard/rounded.js"></script>
+</head>
+<body>
+<table align='center' width="650">
+       <tr>
+               <td>
+                       <h2>Stage <?= $stage ?> of 9</h2>
+               </td>
+       </tr>
+       <tr>
+               <td>
diff --git a/application/views/index.html b/application/views/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/application/views/stage0.php b/application/views/stage0.php
new file mode 100644 (file)
index 0000000..4d37540
--- /dev/null
@@ -0,0 +1,27 @@
+<div class="plroundedconfirm">
+<div class="plroundedwhite">
+
+<h3>What to Expect</h3>
+
+This wizard helps walk you through the sequence of steps needed to register,
+configure, and verify a node as part of the PlanetLab network.
+
+There are ten stages, which correspond to the following sections:
+
+<ol>
+       <li>Register and Confirm PCU Information</li>
+       <li>Register and Confirm Node Information</li>
+       <li>Map PCU to Node</li>
+       <li>Select and Download your Node's BootImage</li>
+       <li>Verify that Node Boots and Contacts PLC</li>
+       <li>Verify that the PCU can Control your Node</li>
+       <li>Complete!</li>
+</ol>
+<?= form_open("register/stage1_addpcu") ?>
+       <center>
+               <input type='submit' value='Continue'>
+       </center>
+</form>
+
+</div>
+</div>
diff --git a/application/views/stage1_pcu_choose.php b/application/views/stage1_pcu_choose.php
new file mode 100644 (file)
index 0000000..ff4845c
--- /dev/null
@@ -0,0 +1,121 @@
+<div class="plroundedconfirm">
+<?= form_open('register/stage2_confirmpcu') ?>
+               <table border=0 cellpadding=3>
+                       <tbody>
+               <?php if ( !empty($pcu_list) ): ?>
+                               <tr><td colspan='2'><h3>Choose an Existing PCU</h3></td></tr>
+                               <tr><th>PCU Name: </th><td>
+                                                       <select name='pcu_id'>
+                                                       <?php foreach ( $pcu_list as $pcu ): ?>
+                                                                       <option value='<?= $pcu->data['pcu_id'] ?>' <?= ( $this->pcu_id == $pcu->data['pcu_id'] ? "selected" : "") ?>>
+                                                                               <?= $pcu->pcu_name() ?>
+                                                                       </option>
+                                                       <?php endforeach; ?>
+                                                       </select>
+                                               </td>
+                               </tr>
+                               <tr><td></td>
+                                       <td>
+                                               <input type=submit name='pcu_choose' value='Continue'>
+                                       </td>
+                               </tr>
+               <?php endif; ?>
+               </tbody>
+       </table>
+</form>
+</div>
+<br>
+<div class="plroundedupdate">
+<?php if ( !isset($pcu_id) || $pcu_id == 0 ): ?>
+       <?= form_open('register/stage1_addpcu') ?>
+                       <table border=0 cellpadding=3>
+                               <tbody>
+                                       <tr><td colspan='2'><h3>Or, Register a New PCU</h3></td></tr>
+                       <?php if ( !empty($site_list) ): ?>
+                                       <tr><th>Site: </th><td>
+                                                               <select name='site_id'>
+                                                               <?php 
+                                                                        foreach ( $site_list as $site ) 
+                                                                        { 
+                                                                               if ( $site['site_id'] == $default_site_list[0] )
+                                                                                       $selected = " selected";
+                                                                               else
+                                                                                       $selected = "";
+                                                                               ?>
+                                                                               <option value='<?= $site['site_id'] ?>' <?= $selected ?>>
+                                                                                       <?= $site['name'] ?>
+                                                                               </option>
+                                                               <?php } ?>
+                                                               </select>
+                                                       </td>
+                                                       <td>
+                                                       </td>
+                                               </tr>
+                       <?php endif; ?>
+                                       <tr><th>Model: </th>
+                                               <td>
+                       <select name='model'>
+                               <option value='none-selected' 
+                                               <?= $this->validation->set_select('model', 'none-selected') ?>>---</option>
+                               <?php foreach( $pcu_types as $pcu_type ): ?>
+                                               <option value='<?= $pcu_type['model'] ?>' 
+                                                       <?= $this->validation->set_select('model', $pcu_type['model']) ?>>
+                                                       <?= $pcu_type['name'] ?>
+                                               </option>
+                               <?php endforeach; ?>
+                       </select>
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <th>Hostname: </th>
+                                               <td nowrap>
+                                                       <input  type=text name='hostname' size=40 
+                                                                       value='<?= $this->validation->hostname ?>'>
+                                                       <?= $this->validation->hostname_error ?>
+                                               </td>
+                                       </tr>
+                                       <tr><th>IP Address: </th>
+                                               <td nowrap>
+                                                       <input type=text name='ip' 
+                                                                       value='<?= $this->validation->ip ?>'>
+                                                       <?= $this->validation->ip_error ?>
+                                               </td>
+                                       </tr>
+                                       <tr><th>Username: </th>
+                                               <td nowrap>
+                                                       <input type=text name='username' 
+                                                                       value='<?= $this->validation->username ?>'>
+                                                       <?= $this->validation->username_error ?>
+                                               </td>
+                                       </tr>
+                                       <tr><th>Password: </th>
+                                               <td nowrap>
+                                                       <input type=text name='password' 
+                                                                       value='<?= $this->validation->password ?>'>
+                                                       <?= $this->validation->password_error ?>
+                                               </td>
+                                       </tr>
+                                       <tr><th>Notes: </th>
+                                               <td><textarea name="notes" rows=5 cols=40></textarea></td>
+                                       </tr>
+                                       <tr><td></td>
+                                               <td>
+                                                       <input type=submit name='pcu_register' value='Add New PCU'>
+                                               </td>
+                                       </tr>
+                               </tbody>
+                               </table>
+       </form>
+</div>
+<?php else: ?>
+       <table border=0 cellpadding=3>
+               <tbody>
+                       <tr><td></td><td><h3>PCU Added Successfully!!!!</h3></td></tr>
+                       <?php if ( ! empty($error) ): ?>
+                       <tr><td></td><td><?= $error ?></td></tr>
+                       <?php endif; ?>
+               </tbody>
+       </table>
+<?php endif; ?>
+       <br /><p>
+               <a href='/db/sites/index.php?id=<?= $default_site_list[0] ?>'>Back to Home Site</a>
diff --git a/application/views/stage2_pcu_confirm.php b/application/views/stage2_pcu_confirm.php
new file mode 100644 (file)
index 0000000..886096a
--- /dev/null
@@ -0,0 +1,79 @@
+<h3>Confirm PCU Information</h3>
+<div class="plroundedconfirm">
+<table><tr><td>
+If the information below is correct, then Proceed, otherwise Update the values
+below.
+</td></tr>
+<tr><td>
+                       <?= form_open("register/stage3_addnode/$pcu_id/$site_id", array('style' => 'display: inline; margin: 0px')) ?>
+
+       <center>
+                                       <input type=submit name='pcu_proceed' value='Confirm & Proceed ->'>
+       </center>
+                       </form>
+</td></tr></table>
+</div>
+<br>
+<div class="plroundedupdate">
+<?= form_open('register/stage2_confirmpcu', array('style' => 'display: inline; margin: 0px')) ?>
+                       <table border=0 cellpadding=3>
+                       <tbody>
+                                       <tr><th>Site: </th><td><?= $pcu_site[0]['name'] ?></td></tr>
+                               <tr><th>Model: </th>
+                                       <td>
+                                               <select name='model'>
+                                                       <option value='none-selected'>---</option>
+                                                       <?php 
+                                                                foreach( $pcu_types as $pcu_type ):
+                                                                       $model = $pcu_type['model'];
+                                                                       $name  = $pcu_type['name'];
+                                                                       if( $pcu->data['model'] == $model)
+                                                                               $selected = "selected";
+                                                                       else
+                                                                               $selected = "";
+                                                                       ?>
+                                                                       <option value='<?= $model ?>' <?= $selected ?>><?= $name ?></option>
+                                                       <?php endforeach; ?>
+                                               </select>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <th>Hostname: </th>
+                                       <td>
+                                               <input type=text name='hostname' size=40 value='<?= $pcu->data['hostname'] ?>'>
+                                               <?= ( $this->disp_errors ? $this->validation->hostname_error : "" ) ?>
+                                       </td>
+                               </tr>
+                               <tr><th>IP Address: </th>
+                                       <td><input type=text name='ip' value='<?= $pcu->data['ip'] ?>'>
+                                               <?= ( $this->disp_errors ? $this->validation->ip_error : "" ) ?>
+                                       </td>
+                               </tr>
+                               <tr><th>Username: </th>
+                                       <td><input type=text name='username' value='<?= $pcu->data['username'] ?>'>
+                                               <?= ( $this->disp_errors ? $this->validation->username_error : "" ) ?>
+                                       </td>
+                               </tr>
+                               <tr><th>Password: </th>
+                                       <td>
+                                               <input type=text name='password' value='<?= $pcu->data['password'] ?>'>
+                                               <?= ( $this->disp_errors ? $this->validation->password_error : "" ) ?>
+                                       </td>
+                               </tr>
+                               <tr><th>Notes: </th>
+                                       <td><textarea name="notes" rows=5 cols=40><?= $pcu->data['notes'] ?></textarea></td>
+                               </tr>
+               <tr>
+                       <td></td>
+                       <td>
+                               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+                               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+                               <input type=submit name='pcu_update' value='Update'> 
+                       </form>
+                       </td>
+               </tr>
+       </tbody>
+       </table>
+</div>
+        <br /><p>
+                       <a href='/db/sites/index.php?id=<?= $default_site_list[0] ?>'>Back to Home Site</a>
diff --git a/application/views/stage3_node_choose.php b/application/views/stage3_node_choose.php
new file mode 100644 (file)
index 0000000..0330f39
--- /dev/null
@@ -0,0 +1,170 @@
+<?php
+if( isset($errors) && count($errors) > 0 )
+{
+  print( "<p><strong>The following errors occured:</strong>" );
+  print( "<font color='red' size='-1'><ul>\n" );
+  foreach( $errors as $err )
+    {
+      print( "<li>$err\n" );
+    }
+  print( "</ul></font>\n" );
+}
+?>
+<script language="javascript">
+function updateStaticFields()
+{
+  var is_dhcp= document.fm.method[0].checked;
+
+  document.fm.netmask.disabled= is_dhcp;
+  document.fm.network.disabled= is_dhcp;
+  document.fm.gateway.disabled= is_dhcp;
+  document.fm.broadcast.disabled= is_dhcp;
+  document.fm.dns1.disabled= is_dhcp;
+  document.fm.dns2.disabled= is_dhcp;
+}
+</script>
+<div class="plroundedconfirm">
+<?= form_open("register/stage4_confirmnode/$pcu_id/$site_id") ?>
+               <table border=0 cellpadding=3>
+                       <tbody>
+                               <tr><td colspan='2'><h3>Choose a Node to Associate with PCU</h3></td></tr>
+               <?php if ( !empty($node_list) ): ?>
+                                       <tr><th>Node Name: </th><td>
+                                                       <select name='node_id'>
+                                                                       <option value='0'>--</option>
+                                                       <?php foreach ( $node_list as $node): ?>
+                                                                       <option value='<?= $node->data['node_id'] ?>' <?= ( $this->node_id == $node->data['node_id'] ? "selected" : "" ) ?>>
+                                                                               <?= $node->hostname ?>
+                                                                       </option>
+                                                       <?php endforeach; ?>
+                                                       </select>
+                                               </td>
+                                               <td>
+                                               </td>
+                               <tr><td></td>
+                                       <td>
+                                               <input type=submit name='node_choose' value='Continue'>
+                                       </td>
+                               </tr>
+                                       </tr>
+               <?php endif; ?>
+                       </tbody>
+                       </table>
+       </form>
+</div>
+<br>
+<div class="plroundedupdate">
+               <table border=0 cellpadding=3>
+                       <tbody>
+<?php if ( !isset($node_id) || $node_id == 0 ): ?>
+<?= form_open("register/stage3_addnode/$pcu_id/$site_id", array('name'=>'fm', 'method'=>'post')) ?>
+               <tr><td colspan='2'><h3>Or, Add a Node</h3></td></tr>
+                                       <tr><th>Site: </th><td><?= $site['name'] ?></td>
+                                       </tr>
+                               <tr>
+                                       <th width=200>Hostname:</td>
+                                       <td><input type="text" name="hostname" value="<?= $this->validation->hostname ?>" 
+                                                               size="40" maxlength="256">
+                                               <?= ( $this->disp_errors ? $this->validation->hostname_error : "")  ?>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <th>Model:</td>
+                                       <td>
+                                               <input type="text" name="model" value="<?= $this->validation->model ?>" 
+                                                               size="40" maxlength="256">
+                                               <?= ( $this->disp_errors ? $this->validation->model_error : "")  ?>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <td> <b>Network Settings</b> </td>
+                               </tr>
+
+                               <tr>
+                                       <th valign='top' width="200">Addressing Method</th>
+                                       <td>
+                                               <input type="radio" name="method" value="dhcp" onChange='updateStaticFields()'
+                                               <?= ( $this->validation->method == 'dhcp' ? "checked" : "" ) ?>>DHCP 
+                                               <input type="radio" name="method" value="static" onChange='updateStaticFields()'
+                                               <?= ( $this->validation->method == 'static' ? "checked" : "" ) ?>>Static 
+                                       </td>
+                               </tr>
+
+                               <tr><th valign='top'>IP Address</td>
+                                       <td><input type="text" name="ip" value="<?= $this->validation->ip ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->ip_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Netmask</font></td>
+                                       <td><input type="text" name="netmask" value="<?= $this->validation->netmask ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->netmask_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Network address</td>
+                                       <td><input type="text" name="network" value="<?= $this->validation->network ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->network_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Gateway Address</td>
+                                       <td><input type="text" name="gateway" value="<?= $this->validation->gateway ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->gateway_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Broadcast address</td>
+                                       <td><input type="text" name="broadcast" value="<?= $this->validation->broadcast ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->broadcast_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Primary DNS</td>
+                                       <td><input type="text" name="dns1" value="<?= $this->validation->dns1 ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->dns1_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr>
+                                       <th valign='top'>Secondary DNS</td>
+                                       <td><input type="text" name="dns2" value="<?= $this->validation->dns2 ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->dns2_error : "")  ?>
+                                               (optional)
+                                       </td>
+                               </tr>
+
+                               <tr><td></td>
+                                       <td>
+                                               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+                                               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+                                               <input type=submit name='register_node' value='Add New Node'>
+                                       </td>
+                               </tr>
+               </tbody>
+       </table>
+<?php else: ?>
+       <table border=0 cellpadding=3>
+               <tbody>
+                       <tr><td></td><td><h3>Node Added Successfully!!!!</h3></td></tr>
+                       <?php if ( isset($errors) and ! empty ($errors) ): ?>
+                               <?php foreach ( $errors as $error ): ?>
+                                       <tr><td></td><td><?= $error ?></td></tr>
+                               <?php endforeach; ?>
+                       <?php endif; ?>
+               </tbody>
+       </table>
+<?php endif; ?>
+</div>
+        <br /><p>
+                       <a href='/db/sites/index.php?id=<?= $default_site_list[0] ?>'>Back to Home Site</a>
+       
+       </form>
+<script language="javascript">
+updateStaticFields();
+</script>
diff --git a/application/views/stage45_pcuport.php b/application/views/stage45_pcuport.php
new file mode 100644 (file)
index 0000000..e076a59
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+if( isset($errors) && count($errors) > 0 )
+{
+  print( "<p><strong>The following errors occured:</strong>" );
+  print( "<font color='red' size='-1'><ul>\n" );
+  foreach( $errors as $err )
+    {
+      print( "<li>$err\n" );
+    }
+  print( "</ul></font>\n" );
+}
+?>
+<div class="plroundedconfirm">
+<h3>Confirm PCU Port to Node Mapping</h3>
+Please confirm that the node is associated with the correct port on the PCU.
+Most newer models have this function built-in, where as older models allow for
+multiple 'ports'.  Port 1 is appropriate for built-in models.
+<?= form_open("download/stage5_bootimage/$pcu_id/$site_id/$node_id", array('method'=>'post')) ?>
+<center>
+               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+               <input type=hidden name='node_id' value='<?= $node_id ?>'>
+               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+               <input type=submit name='node_confirm' value='Confirm & Proceed'>
+</center>
+</form>
+</div>
+<br>
+<div class="plroundedupdate">
+<?= form_open("register/stage45_mappcu/$pcu_id/$site_id/$node_id", array('name'=>'fm', 'method'=>'post')) ?>
+               <table border=0 cellpadding=3>
+                       <tbody>
+               <tr><td colspan='2'>
+               </td></tr>
+                               </tr>
+                                       <th width=200>Hostname : PCUPort</td>
+                                       <td><?= $node->hostname ?> : <?= $pcu_port ?></td>
+                               <tr>
+                                       <th>PCU Port:</th>
+                                       <td>
+                                               <select name='port_number'>
+                                                       <option value='noaction'>--</option>
+                                                       <?php 
+                                                                       $ports= array( 1, 2, 3, 4, 5, 6, 7, 8);
+                                                                       foreach ($ports as $port )
+                                                                       {?>
+                                                                               <option value='<?= $port ?>'>
+                                                                                       <?= $node->hostname ?> port <?= $port ?>
+                                                                               </option>
+                                                       <?php   } ?>
+                                               </select>
+
+                                       </td>
+                               </tr>
+                               <tr><td></td>
+                                       <td>
+                                               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+                                               <input type=hidden name='node_id' value='<?= $node_id ?>'>
+                                               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+                                               <input type=submit name='pcumap_update' value='Update & Return'> 
+                                       </td>
+                               </tr>
+                       </tbody>
+                       </table>
+</div>
+        <br /><p>
+                       <a href='/db/sites/index.php?id=<?= $site_id ?>'>Back to Home Site</a>
+       
+       </form>
diff --git a/application/views/stage4_node_confirm.php b/application/views/stage4_node_confirm.php
new file mode 100644 (file)
index 0000000..dbb4a78
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+if( isset($errors) && count($errors) > 0 )
+{
+  print( "<p><strong>The following errors occured:</strong>" );
+  print( "<font color='red' size='-1'><ul>\n" );
+  foreach( $errors as $err )
+    {
+      print( "<li>$err\n" );
+    }
+  print( "</ul></font>\n" );
+}
+?>
+<script language="javascript">
+function updateStaticFields()
+{
+  var is_dhcp= document.fm.method[0].checked;
+
+  document.fm.netmask.disabled= is_dhcp;
+  document.fm.network.disabled= is_dhcp;
+  document.fm.gateway.disabled= is_dhcp;
+  document.fm.broadcast.disabled= is_dhcp;
+  document.fm.dns1.disabled= is_dhcp;
+  document.fm.dns2.disabled= is_dhcp;
+}
+</script>
+<div class="plroundedconfirm">
+<h3>Confirm Node Information</h3>
+<?= form_open("register/stage45_mappcu/$pcu_id/$site_id/$node_id", array('method'=>'post')) ?>
+               <table border=0 cellpadding=3>
+                       <tbody>
+                               <tr><td colspan='2'>
+Please review the information below, and if it is correct, the Proceed to then
+next stage.  Otherwise, please Update the information as appropriate.
+                               </td></tr>
+                               <tr><td></td>
+                                       <td>
+                                       <center>
+                                               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+                                               <input type=hidden name='node_id' value='<?= $node_id ?>'>
+                                               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+                                               <input type=submit name='node_confirm' value='Confirm & Proceed'>
+                                       </center>
+                                       </td>
+                               </tr>
+                                       </tr>
+                       </tbody>
+                       </table>
+       </form>
+</div>
+<br>
+<div class="plroundedupdate">
+<?= form_open("register/stage4_confirmnode/$pcu_id/$site_id/$node_id", array('name'=>'fm', 'method'=>'post')) ?>
+               <table border=0 cellpadding=3>
+                       <tbody>
+               <tr><td colspan='2'>
+               </td></tr>
+               <?php if ( !empty($site) ) 
+                       { ?>
+                                       <tr><th>Site: </th><td> <?= $site['name'] ?> </td>
+                                       </tr>
+               <?php } ?>
+                               <tr>
+                               </tr>
+                                       <th width=200>Hostname:</td>
+                                       <td><input type="text" name="hostname" value="<?= $node->hostname ?>" 
+                                                               size="40" maxlength="256">
+                                               <?= ( $this->disp_errors ? $this->validation->hostname_error : "")  ?>
+                                       </td>
+                               <tr>
+                                       <th>Model:</th>
+                                       <td>
+                                               <input type="text" name="model" value="<?= $node->model ?>" 
+                                                               size="40" maxlength="256">
+                                               <?= ( $this->disp_errors ? $this->validation->model_error : "")  ?>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <th valign='top' width="200">Addressing Method</th>
+                                       <td>
+                                               <input type="radio" name="method" value="dhcp" onChange='updateStaticFields()'
+                                               <?= ( $node->method == 'dhcp' ? "checked" : "" ) ?>>DHCP 
+                                               <input type="radio" name="method" value="static" onChange='updateStaticFields()'
+                                               <?= ( $node->method == 'static' ? "checked" : "" ) ?>>Static 
+                                       </td>
+                               </tr>
+
+                               <tr><th valign='top'>IP Address</th>
+                                       <td><input type="text" name="ip" value="<?= $node->ip ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->ip_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Netmask</font></th>
+                                       <td><input type="text" name="netmask" value="<?= $node->netmask ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->netmask_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Network address</th>
+                                       <td><input type="text" name="network" value="<?= $node->network ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->network_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Gateway Address</th>
+                                       <td><input type="text" name="gateway" value="<?= $node->gateway ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->gateway_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Broadcast address</th>
+                                       <td><input type="text" name="broadcast" value="<?= $node->broadcast ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->broadcast_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr> 
+                                       <th valign='top'>Primary DNS</th>
+                                       <td><input type="text" name="dns1" value="<?= $node->dns1 ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->dns1_error : "")  ?>
+                                       </td>
+                               </tr>
+
+                               <tr>
+                                       <th valign='top'>Secondary DNS</th>
+                                       <td><input type="text" name="dns2" value="<?= $node->dns2 ?>">
+                                               <?= ( $this->disp_errors ? $this->validation->dns2_error : "")  ?>
+                                               (optional)
+                                       </td>
+                               </tr>
+
+                               <tr><td></td>
+                                       <td>
+                                               <input type=hidden name='pcu_id' value='<?= $pcu_id ?>'>
+                                               <input type=hidden name='node_id' value='<?= $node_id ?>'>
+                                               <input type=hidden name='site_id' value='<?= $site_id ?>'>
+                                               <input type=submit name='node_update' value='Update & Return'> 
+                                       </td>
+                               </tr>
+                       </tbody>
+                       </table>
+</div>
+        <br /><p>
+                       <a href='/db/sites/index.php?id=<?= $site_id ?>'>Back to Home Site</a>
+       
+       </form>
+<script language="javascript">
+updateStaticFields();
+</script>
diff --git a/application/views/stage5_bootimage.php b/application/views/stage5_bootimage.php
new file mode 100644 (file)
index 0000000..919e458
--- /dev/null
@@ -0,0 +1,47 @@
+<script language="javascript">
+function updateContinueEnabled()
+{
+       document.fm.download_bootimage.disabled = false;
+}
+</script>
+<h3>Choose a Boot Image</h3>
+<div class="plroundedupdate">
+<br>
+<?= form_open("download/stage6_download/$pcu_id/$site_id/$node_id", array('name' => 'fm', 'style' => 'display: inline; margin: 0px')) ?>
+
+<div class="plroundedwhite"
+               id="bootcd-sidebar">
+       <p> Pick one of the following options. Then, download the files needed for that option.</p>
+
+       <table style="font-size: 100%">
+       <tr>
+         <td><input type='radio' name='action' value='download-node-iso' onchange='updateContinueEnabled();'></td>
+         <td><img src="/misc/all-in-one-cd.png"/></td><td><b>All-In-One ISO image</b>.  
+                       Includes plnode.txt.  No additional formatting required.</td>
+       </tr>
+       <tr>
+         <td><input type='radio' name='action' value='download-node-usb' onchange='updateContinueEnabled();'></td>
+         <td><img src="/misc/all-in-one-usb.png" /></td><td><b>All-In-One USB image</b>. Includes plnode.txt, and filesystem only.  Requires additional USB stick formatting.**</td>
+       </tr>
+       <tr>
+         <td><input type='radio' name='action' value='download-node-usb-partition' onchange='updateContinueEnabled();'></td>
+         <td><img src="/misc/all-in-one-usb.png" /></td><td><b>All-In-One partitioned, USB image</b>.  Includes, plnode.txt, MBR, partition table, and filesystem.  No additional formatting required.**</td>
+       </tr>
+       <tr>
+         <td><input type='radio' name='action' value='download-node-floppy-with-iso' onchange='updateContinueEnabled();'></td>
+         <td><img src="/misc/generic-cd-and-floppy.png" /></td><td><b>Generic CD</b>, and <b>plnode.txt</b> on Floppy</td>
+       </tr>
+       <tr>
+         <td><input type='radio' name='action' value='download-node-floppy-with-usb' onchange='updateContinueEnabled();'></td>
+         <td><img src="/misc/generic-usb-and-floppy.png" /></td><td><b>Generic USB</b>, and <b>plnode.txt</b> on Floppy</td>
+       </tr>
+       </table>
+
+       <p>Additional directions are provided on the next page.</p>
+       <p>NOTE:  ** USB images are not guaranteed to work on all systems.</p>
+</div>
+       <center>
+       <input type=submit name='download_bootimage' disabled value='Select'> 
+       </center>
+</form>
+</div>
diff --git a/application/views/stage6_download.php b/application/views/stage6_download.php
new file mode 100644 (file)
index 0000000..f11c0aa
--- /dev/null
@@ -0,0 +1,63 @@
+<script language="javascript">
+function updateContinueEnabled()
+{
+       document.fm.button_continue.disabled = false;
+}
+</script>
+
+<div class="plroundedupdate">
+<div class="plroundedwhite">
+
+<h3>Download BootImage and Follow Steps Below</h3>
+
+<?php
+/*
+       if( $can_gen_config ):
+               if (method_exists($api,"GetBootMedium")):
+                       $preview=$api->GetBootMedium($node_id,"node-preview",""); ?>
+                       <h4>Current node configuration contents</h4>
+                       <pre><?= $preview ?></pre>
+                       <hr />
+       endif; 
+*/
+?>
+
+<dl>
+       <dt>Step 1</dt>
+        <?php  if ( $action == "download-node-floppy-with-iso" ): ?>                             
+               <dd>Download the <a href="/download/<?= $generic_iso_name 
+                       ?>.iso">Generic ISO image</a>.  Then,
+                       use the 'Download' button below to get the configuration file for your
+                       floppy disk. </dd>
+        <?php  elseif ( $action == "download-node-floppy-with-usb" ): ?>
+               <dd>Download the <a
+                       href="/download/<?= $generic_iso_name ?>.usb">Generic USB image</a>.  Then,
+                       use the 'Download' button below to get the configuration file for your
+                       floppy disk.  </dd>
+        <?php  else: ?>
+               <dd>Download your BootImage using 'Download' button below.</dd>
+        <?php  endif; ?>
+
+       <dt>Step 2</dt><dd>Burn or copy the BootImage to the <a target="_blank" href="http://www.planet-lab.org/doc/guides/bootcdsetup">appropriate read-only media</a></dd>
+       <dt>Step 3</dt><dd>Install the BootImage in your machine. Turn the machine on and allow it to boot.</dd>
+       <dt>Step 4</dt><dd>Continue to the next Stage.</dd>
+</dl>
+
+
+<p class='error'>WARNING: By using the download button below, we will generate
+a new node key for your machine. Therefore, all previous configuration files or All-in-one BootImages that you have downloaded will be expired.  Only continue if you will complete the installation process.</p>
+
+       <p>
+       <?= form_open("download/stage6_download/$pcu_id/$site_id/$node_id", array('style' => 'display: inline; margin: 0px')) ?>
+               <input type='hidden' name='action' value='<?= $action ?>'>
+               <input type='hidden' name='download' value='1'>
+               <input name='button_download' type='submit' value='Download <?= $format ?>' onclick='updateContinueEnabled();'>
+       </form>
+       <?= form_open("confirm/stage7_firstcontact/$pcu_id/$site_id/$node_id", array('name' => 'fm', 'style' => 'display: inline; margin: 0px')) ?>
+               <input name='button_continue' disabled type='submit' value='Continue ->'>
+       </form>
+</div>
+</div>
+<?php /*       else: 
+               <p><font color=red>Configuration file cannot be created.</font>
+<?php  endif; */ ?>
diff --git a/application/views/stage7_firstcontact.php b/application/views/stage7_firstcontact.php
new file mode 100644 (file)
index 0000000..540faf6
--- /dev/null
@@ -0,0 +1,55 @@
+<div class="plroundedupdate">
+<div class="plroundedwhite">
+<h3>Confirm Node Boot and PLC Contact</h3>
+<table><tbody>
+       <tr><th>Site: </th><td> <a href='/db/sites/index.php?id=$site_id'><?= $site['name'] ?></a></td></tr>
+       <tr><th>Hostname: </th><td nowrap='1'><?= $node['hostname'] ?></td></tr>
+       <tr><th>Boot State: </th><td><?= $node['boot_state'] ?> </td></tr>
+       <tr><th>Model: </th><td><?= $node['model'] ?></td></tr>
+       <tr><th>Version: </th><td nowrap='1'><?= $node['version'] ?></td></tr>
+       <tr><th>Last Contact: </th><td><?= $last_contact_str ?></td>
+               <td>
+               <?php if ( $last_contact_str == "Never" ): ?>
+                       <span class='error'> Once your machine has booted and contacted PLC,
+                               this field will update and you will be able to 'Continue' to the next
+                               stage.
+                       </span>
+                       <br>
+                       'Reload' to refresh this page.
+               <?php else: ?>
+                       <b>Success!!</b> Your machine has booted and contacted PLC.<br>
+                       'Continue' and test the remote reset function.
+               <?php endif; ?>
+               </td>
+       </tr>
+       <tr>
+               <td>&nbsp;</td>
+       </tr>
+       <tr>
+               <td>
+               </td>
+               <td colspan='2'>
+                       <?= form_open("confirm/stage7_firstcontact/$pcu_id/$site_id/$node_id", array('style' => 'display: inline; margin: 0px')) ?>
+                               <input type='submit' name='reload_contact' value='Reload'>
+                       </form>
+                       <?= form_open("confirm/stage8_rebootpcu/$pcu_id/$site_id/$node_id", array('style' => 'display: inline; margin: 0px')) ?>
+               <?php if ( $last_contact_str != "Never" ): ?>
+                               <input type='submit' value='Continue'>
+               <?php else: ?>
+                               <input type='submit' disabled value='Continue'>
+               <?php endif; ?>
+                               <input type='submit' value='Debug Continue'>
+                       </form>
+               </td>
+       </tr>
+</tbody></table><br/>
+</div>
+</div>
+<p>
+<h3>Trouble Shooting:</h3>
+<ul>
+<li>If you have booted the machine, but the <em>Last Contact</em> field has
+not updated, then there is very likely a local, network configuration problem. <br> 
+We recommend verifying that the machine's network settings are correct and operational.  You can achieve this using the <code>site_admin</code> account on the BootCD to manually diagnose the problem.</li>
+</ul>
+</p>
diff --git a/application/views/stage8_rebootpcu.php b/application/views/stage8_rebootpcu.php
new file mode 100644 (file)
index 0000000..6fafd21
--- /dev/null
@@ -0,0 +1,72 @@
+<div class="plroundedupdate">
+<div class="plroundedwhite">
+<h3>Confirm Reboot Node With PCU</h3>
+<table><tbody>
+       <tr><th>Site: </th><td> <a href='/db/sites/index.php?id=<?= $site_id ?>'><?= $site['name'] ?></a></td></tr>
+       <tr><th>Hostname: </th><td nowrap><?= $node['hostname'] ?></td></tr>
+       <tr><th>Boot State: </th><td><?= $node['boot_state'] ?> </td>
+               <td>
+               <?php if ( $node['boot_state'] == "disable" ): ?>
+                       <span class='error'> Begin by trying the 'Test Reboot' button.  
+                               This will set the boot state to 'rins' and attempt to reboot your machine 
+                               using the registered PCU.
+                       </span>
+                       If successful, your machine will reboot, install the bootstrap image, and 
+                       contacted PLC.  Finally, the boot state will be updated to 'boot'.
+               <?php elseif ( $node['boot_state'] == "rins" ): ?>
+                       <br>
+                       'Test Reboot' to try again.<br>
+                       'Reload' to Reload this page.
+               <?php else: ?>
+                       <b>Success!!</b> Your machine has booted and contacted PLC.
+                       'Continue' to the final stage.
+               <?php endif; ?>
+               </td>
+       </tr>
+       <tr><th>Model: </th><td><?= $node['model'] ?></td></tr>
+       <tr><th>Version: </th><td nowrap='1'><?= $node['version'] ?></td></tr>
+       <tr><th>Last Contact: </th><td><?= $last_contact_str ?></td></tr>
+<?php if ( isset($error) && ! empty($error) ): ?>
+       <tr>
+               <td colspan=2>
+                       <span class='error'> <?= $error ?> </span>
+               </td>
+       </tr>
+<?php endif; ?>
+       <tr>
+               <td>
+               </td>
+               <td colspan='2'>
+                       <?= form_open("confirm/reboot/$site_id/$pcu_id/$node_id", 
+                                                  array('style' => 'display: inline; margin: 0px')) ?>
+                               <input type='submit' name='reboot_node' value='Test Reboot'>
+                       </form>
+                       <?= form_open("confirm/stage8_rebootpcu/$pcu_id/$site_id/$node_id", array('style' => 'display: inline; margin: 0px')) ?>
+                               <input type='submit' name='reload_contact' value='Reload'>
+                       </form>
+                       <?= form_open("confirm/complete/$site_id/$pcu_id/$node_id", 
+                                                  array('style' => 'display: inline; margin: 0px')) ?>
+               <?php if ( $node['boot_state'] == "boot" ): ?>
+                               <input type='submit' value='Continue'>
+               <?php else: ?>
+                               <input type='submit' disabled value='Continue'>
+               <?php endif; ?>
+                               <input type='submit' value='Debug Continue'>
+               </form>
+</tbody></table><br />
+</div>
+</div>
+
+<h3>Tips:</h3>
+<ul>
+    <li>
+                       If you do not see an error, this does not mean that none have
+                       occurred.  We need your help in verifying that the PCU function is
+                       configured correctly.
+       </li>
+    <li>
+                       Please be patient.  Installations may take between 10 to 30
+                       minutes depending on the speed of your hardware and network.  Checking the
+                       console is the fastest way to verify that the installation is proceeding.
+       </li>
+</ul>
diff --git a/application/views/stage9_complete.php b/application/views/stage9_complete.php
new file mode 100644 (file)
index 0000000..e0f82a0
--- /dev/null
@@ -0,0 +1,18 @@
+<div class="plroundedconfirm">
+<div class="plroundedwhite">
+<h3>Congratulations!!!  You are done.</h3>
+<p>Your machine is configured correctly, online, and fully running.<br>
+<p>We sincerely thank you for the effort you have invested in setting up your
+machines.  With your contribution PlanetLab will have a more reliable and growing
+infrastructure to build upon.
+<p><em>Thank you.</em>
+<br>
+<p>If you have any questions, or suggestions for how to improve
+this process, please send us a hint at <a
+href="mailto:support@planet-lab.org?subject=Feedback regarding the Node Registration Wizard">PlanetLab Suggestions</a>
+<br>
+
+<br>
+</div>
+</div>
+<a href='/db/sites/index.php?id=<?= $site_id ?>'>Back to Home Site</a>
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
new file mode 100644 (file)
index 0000000..8313059
--- /dev/null
@@ -0,0 +1,62 @@
+<html>\r
+<head>\r
+<title>Welcome to CodeIgniter</title>\r
+\r
+<style type="text/css">\r
+\r
+body {\r
+ background-color: #fff;\r
+ margin: 40px;\r
+ font-family: Lucida Grande, Verdana, Sans-serif;\r
+ font-size: 14px;\r
+ color: #4F5155;\r
+}\r
+\r
+a {\r
+ color: #003399;\r
+ background-color: transparent;\r
+ font-weight: normal;\r
+}\r
+\r
+h1 {\r
+ color: #444;\r
+ background-color: transparent;\r
+ border-bottom: 1px solid #D0D0D0;\r
+ font-size: 16px;\r
+ font-weight: bold;\r
+ margin: 24px 0 2px 0;\r
+ padding: 5px 0 6px 0;\r
+}\r
+\r
+code {\r
+ font-family: Monaco, Verdana, Sans-serif;\r
+ font-size: 12px;\r
+ background-color: #f9f9f9;\r
+ border: 1px solid #D0D0D0;\r
+ color: #002166;\r
+ display: block;\r
+ margin: 14px 0 14px 0;\r
+ padding: 12px 10px 12px 10px;\r
+}\r
+\r
+</style>\r
+</head>\r
+<body>\r
+\r
+<h1>Welcome to CodeIgniter!</h1>\r
+\r
+<p>The page you are looking at is being generated dynamically by CodeIgniter.</p>\r
+\r
+<p>If you would like to edit this page you'll find it located at:</p>\r
+<code>system/application/views/welcome_message.php</code>\r
+\r
+<p>The corresponding controller for this page is found at:</p>\r
+<code>system/application/controllers/welcome.php</code>\r
+\r
+<p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>\r
+\r
+\r
+<p><br />Page rendered in {elapsed_time} seconds</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/cache/index.html b/cache/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/codeigniter/Base4.php b/codeigniter/Base4.php
new file mode 100644 (file)
index 0000000..b242c00
--- /dev/null
@@ -0,0 +1,69 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.3\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CI_BASE - For PHP 4\r
+ *\r
+ * This file is used only when CodeIgniter is being run under PHP 4.\r
+ *\r
+ * In order to allow CI to work under PHP 4 we had to make the Loader class\r
+ * the parent of the Controller Base class.  It's the only way we can\r
+ * enable functions like $this->load->library('email') to instantiate\r
+ * classes that can then be used within controllers as $this->email->send()\r
+ *\r
+ * PHP 4 also has trouble referencing the CI super object within application\r
+ * constructors since objects do not exist until the class is fully\r
+ * instantiated.  Basically PHP 4 sucks...\r
+ *\r
+ * Since PHP 5 doesn't suffer from this problem so we load one of\r
+ * two files based on the version of PHP being run.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage codeigniter\r
+ * @category   front-controller\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/\r
+ */\r
+ class CI_Base extends CI_Loader {\r
+\r
+       function CI_Base()\r
+       {\r
+               // This allows syntax like $this->load->foo() to work\r
+               parent::CI_Loader();\r
+               $this->load =& $this;\r
+               \r
+               // This allows resources used within controller constructors to work\r
+               global $OBJ;\r
+               $OBJ = $this->load; // Do NOT use a reference.\r
+       }\r
+}\r
+\r
+function &get_instance()\r
+{\r
+       global $CI, $OBJ;\r
+       \r
+       if (is_object($CI))\r
+       {\r
+               return $CI;\r
+       }\r
+       \r
+       return $OBJ->load;\r
+}\r
+\r
+\r
+/* End of file Base4.php */\r
+/* Location: ./system/codeigniter/Base4.php */
\ No newline at end of file
diff --git a/codeigniter/Base5.php b/codeigniter/Base5.php
new file mode 100644 (file)
index 0000000..8dd3ad0
--- /dev/null
@@ -0,0 +1,56 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.3\r
+ * @filesource\r
+ */\r
+\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CI_BASE - For PHP 5\r
+ *\r
+ * This file contains some code used only when CodeIgniter is being\r
+ * run under PHP 5.  It allows us to manage the CI super object more\r
+ * gracefully than what is possible with PHP 4.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage codeigniter\r
+ * @category   front-controller\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/\r
+ */\r
+\r
+class CI_Base {\r
+\r
+       private static $instance;\r
+\r
+       public function CI_Base()\r
+       {\r
+               self::$instance =& $this;\r
+       }\r
+\r
+       public static function &get_instance()\r
+       {\r
+               return self::$instance;\r
+       }\r
+}\r
+\r
+function &get_instance()\r
+{\r
+       return CI_Base::get_instance();\r
+}\r
+\r
+\r
+\r
+/* End of file Base5.php */\r
+/* Location: ./system/codeigniter/Base5.php */
\ No newline at end of file
diff --git a/codeigniter/CodeIgniter.php b/codeigniter/CodeIgniter.php
new file mode 100644 (file)
index 0000000..27094d2
--- /dev/null
@@ -0,0 +1,276 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * System Front Controller\r
+ *\r
+ * Loads the base classes and executes the request.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage codeigniter\r
+ * @category   Front-controller\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/\r
+ */\r
+\r
+// CI Version\r
+define('CI_VERSION',   '1.7.0');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Load the global functions\r
+ * ------------------------------------------------------\r
+ */\r
+require(BASEPATH.'codeigniter/Common'.EXT);\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Load the compatibility override functions\r
+ * ------------------------------------------------------\r
+ */\r
+require(BASEPATH.'codeigniter/Compat'.EXT);\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Load the framework constants\r
+ * ------------------------------------------------------\r
+ */\r
+require(APPPATH.'config/constants'.EXT);\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Define a custom error handler so we can log PHP errors\r
+ * ------------------------------------------------------\r
+ */\r
+set_error_handler('_exception_handler');\r
+set_magic_quotes_runtime(0); // Kill magic quotes\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Start the timer... tick tock tick tock...\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+$BM =& load_class('Benchmark');\r
+$BM->mark('total_execution_time_start');\r
+$BM->mark('loading_time_base_classes_start');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Instantiate the hooks class\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+$EXT =& load_class('Hooks');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Is there a "pre_system" hook?\r
+ * ------------------------------------------------------\r
+ */\r
+$EXT->_call_hook('pre_system');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Instantiate the base classes\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+$CFG =& load_class('Config');\r
+$URI =& load_class('URI');\r
+$RTR =& load_class('Router');\r
+$OUT =& load_class('Output');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *     Is there a valid cache file?  If so, we're done...\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+if ($EXT->_call_hook('cache_override') === FALSE)\r
+{\r
+       if ($OUT->_display_cache($CFG, $URI) == TRUE)\r
+       {\r
+               exit;\r
+       }\r
+}\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Load the remaining base classes\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+$IN            =& load_class('Input');\r
+$LANG  =& load_class('Language');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Load the app controller and local controller\r
+ * ------------------------------------------------------\r
+ *\r
+ *  Note: Due to the poor object handling in PHP 4 we'll\r
+ *  conditionally load different versions of the base\r
+ *  class.  Retaining PHP 4 compatibility requires a bit of a hack.\r
+ *\r
+ *  Note: The Loader class needs to be included first\r
+ *\r
+ */\r
+if (floor(phpversion()) < 5)\r
+{\r
+       load_class('Loader', FALSE);\r
+       require(BASEPATH.'codeigniter/Base4'.EXT);\r
+}\r
+else\r
+{\r
+       require(BASEPATH.'codeigniter/Base5'.EXT);\r
+}\r
+\r
+// Load the base controller class\r
+load_class('Controller', FALSE);\r
+\r
+// Load the local application controller\r
+// Note: The Router class automatically validates the controller path.  If this include fails it \r
+// means that the default controller in the Routes.php file is not resolving to something valid.\r
+if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))\r
+{\r
+       show_error('Unable to load your default controller.  Please make sure the controller specified in your Routes.php file is valid.');\r
+}\r
+\r
+include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);\r
+\r
+// Set a mark point for benchmarking\r
+$BM->mark('loading_time_base_classes_end');\r
+\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Security check\r
+ * ------------------------------------------------------\r
+ *\r
+ *  None of the functions in the app controller or the\r
+ *  loader class can be called via the URI, nor can\r
+ *  controller functions that begin with an underscore\r
+ */\r
+$class  = $RTR->fetch_class();\r
+$method = $RTR->fetch_method();\r
+\r
+if ( ! class_exists($class)\r
+       OR $method == 'controller'\r
+       OR strncmp($method, '_', 1) == 0\r
+       OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))\r
+       )\r
+{\r
+       show_404("{$class}/{$method}");\r
+}\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Is there a "pre_controller" hook?\r
+ * ------------------------------------------------------\r
+ */\r
+$EXT->_call_hook('pre_controller');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Instantiate the controller and call requested method\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+// Mark a start point so we can benchmark the controller\r
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');\r
+\r
+$CI = new $class();\r
+\r
+// Is this a scaffolding request?\r
+if ($RTR->scaffolding_request === TRUE)\r
+{\r
+       if ($EXT->_call_hook('scaffolding_override') === FALSE)\r
+       {\r
+               $CI->_ci_scaffolding();\r
+       }\r
+}\r
+else\r
+{\r
+       /*\r
+        * ------------------------------------------------------\r
+        *  Is there a "post_controller_constructor" hook?\r
+        * ------------------------------------------------------\r
+        */\r
+       $EXT->_call_hook('post_controller_constructor');\r
+       \r
+       // Is there a "remap" function?\r
+       if (method_exists($CI, '_remap'))\r
+       {\r
+               $CI->_remap($method);\r
+       }\r
+       else\r
+       {\r
+               // is_callable() returns TRUE on some versions of PHP 5 for private and protected\r
+               // methods, so we'll use this workaround for consistent behavior\r
+               if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))\r
+               {\r
+                       show_404("{$class}/{$method}");\r
+               }\r
+\r
+               // Call the requested method.\r
+               // Any URI segments present (besides the class/function) will be passed to the method for convenience\r
+               call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));\r
+       }\r
+}\r
+\r
+// Mark a benchmark end point\r
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Is there a "post_controller" hook?\r
+ * ------------------------------------------------------\r
+ */\r
+$EXT->_call_hook('post_controller');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Send the final rendered output to the browser\r
+ * ------------------------------------------------------\r
+ */\r
+\r
+if ($EXT->_call_hook('display_override') === FALSE)\r
+{\r
+       $OUT->_display();\r
+}\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Is there a "post_system" hook?\r
+ * ------------------------------------------------------\r
+ */\r
+$EXT->_call_hook('post_system');\r
+\r
+/*\r
+ * ------------------------------------------------------\r
+ *  Close the DB connection if one exists\r
+ * ------------------------------------------------------\r
+ */\r
+if (class_exists('CI_DB') AND isset($CI->db))\r
+{\r
+       $CI->db->close();\r
+}\r
+\r
+\r
+/* End of file CodeIgniter.php */\r
+/* Location: ./system/codeigniter/CodeIgniter.php */
\ No newline at end of file
diff --git a/codeigniter/Common.php b/codeigniter/Common.php
new file mode 100644 (file)
index 0000000..9212f07
--- /dev/null
@@ -0,0 +1,307 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Common Functions\r
+ *\r
+ * Loads the base classes and executes the request.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage codeigniter\r
+ * @category   Common Functions\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Tests for file writability\r
+ *\r
+ * is_writable() returns TRUE on Windows servers when you really can't write to \r
+ * the file, based on the read-only attribute.  is_writable() is also unreliable\r
+ * on Unix servers if safe_mode is on. \r
+ *\r
+ * @access     private\r
+ * @return     void\r
+ */\r
+function is_really_writable($file)\r
+{      \r
+       // If we're on a Unix server with safe_mode off we call is_writable\r
+       if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)\r
+       {\r
+               return is_writable($file);\r
+       }\r
+\r
+       // For windows servers and safe_mode "on" installations we'll actually\r
+       // write a file then read it.  Bah...\r
+       if (is_dir($file))\r
+       {\r
+               $file = rtrim($file, '/').'/'.md5(rand(1,100));\r
+\r
+               if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               fclose($fp);\r
+               @chmod($file, DIR_WRITE_MODE);\r
+               @unlink($file);\r
+               return TRUE;\r
+       }\r
+       elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       fclose($fp);\r
+       return TRUE;\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+* Class registry\r
+*\r
+* This function acts as a singleton.  If the requested class does not\r
+* exist it is instantiated and set to a static variable.  If it has\r
+* previously been instantiated the variable is returned.\r
+*\r
+* @access      public\r
+* @param       string  the class name being requested\r
+* @param       bool    optional flag that lets classes get loaded but not instantiated\r
+* @return      object\r
+*/\r
+function &load_class($class, $instantiate = TRUE)\r
+{\r
+       static $objects = array();\r
+\r
+       // Does the class exist?  If so, we're done...\r
+       if (isset($objects[$class]))\r
+       {\r
+               return $objects[$class];\r
+       }\r
+\r
+       // If the requested class does not exist in the application/libraries\r
+       // folder we'll load the native class from the system/libraries folder. \r
+       if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT))\r
+       {\r
+               require(BASEPATH.'libraries/'.$class.EXT);\r
+               require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT);\r
+               $is_subclass = TRUE;\r
+       }\r
+       else\r
+       {\r
+               if (file_exists(APPPATH.'libraries/'.$class.EXT))\r
+               {\r
+                       require(APPPATH.'libraries/'.$class.EXT);\r
+                       $is_subclass = FALSE;\r
+               }\r
+               else\r
+               {\r
+                       require(BASEPATH.'libraries/'.$class.EXT);\r
+                       $is_subclass = FALSE;\r
+               }\r
+       }\r
+\r
+       if ($instantiate == FALSE)\r
+       {\r
+               $objects[$class] = TRUE;\r
+               return $objects[$class];\r
+       }\r
+\r
+       if ($is_subclass == TRUE)\r
+       {\r
+               $name = config_item('subclass_prefix').$class;\r
+               $objects[$class] =& new $name();\r
+               return $objects[$class];\r
+       }\r
+\r
+       $name = ($class != 'Controller') ? 'CI_'.$class : $class;\r
+       \r
+       $objects[$class] =& new $name();\r
+       return $objects[$class];\r
+}\r
+\r
+/**\r
+* Loads the main config.php file\r
+*\r
+* @access      private\r
+* @return      array\r
+*/\r
+function &get_config()\r
+{\r
+       static $main_conf;\r
+\r
+       if ( ! isset($main_conf))\r
+       {\r
+               if ( ! file_exists(APPPATH.'config/config'.EXT))\r
+               {\r
+                       exit('The configuration file config'.EXT.' does not exist.');\r
+               }\r
+\r
+               require(APPPATH.'config/config'.EXT);\r
+\r
+               if ( ! isset($config) OR ! is_array($config))\r
+               {\r
+                       exit('Your config file does not appear to be formatted correctly.');\r
+               }\r
+\r
+               $main_conf[0] =& $config;\r
+       }\r
+       return $main_conf[0];\r
+}\r
+\r
+/**\r
+* Gets a config item\r
+*\r
+* @access      public\r
+* @return      mixed\r
+*/\r
+function config_item($item)\r
+{\r
+       static $config_item = array();\r
+\r
+       if ( ! isset($config_item[$item]))\r
+       {\r
+               $config =& get_config();\r
+\r
+               if ( ! isset($config[$item]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               $config_item[$item] = $config[$item];\r
+       }\r
+\r
+       return $config_item[$item];\r
+}\r
+\r
+\r
+/**\r
+* Error Handler\r
+*\r
+* This function lets us invoke the exception class and\r
+* display errors using the standard error template located\r
+* in application/errors/errors.php\r
+* This function will send the error page directly to the\r
+* browser and exit.\r
+*\r
+* @access      public\r
+* @return      void\r
+*/\r
+function show_error($message)\r
+{\r
+       $error =& load_class('Exceptions');\r
+       echo $error->show_error('An Error Was Encountered', $message);\r
+       exit;\r
+}\r
+\r
+\r
+/**\r
+* 404 Page Handler\r
+*\r
+* This function is similar to the show_error() function above\r
+* However, instead of the standard error template it displays\r
+* 404 errors.\r
+*\r
+* @access      public\r
+* @return      void\r
+*/\r
+function show_404($page = '')\r
+{\r
+       $error =& load_class('Exceptions');\r
+       $error->show_404($page);\r
+       exit;\r
+}\r
+\r
+\r
+/**\r
+* Error Logging Interface\r
+*\r
+* We use this as a simple mechanism to access the logging\r
+* class and send messages to be logged.\r
+*\r
+* @access      public\r
+* @return      void\r
+*/\r
+function log_message($level = 'error', $message, $php_error = FALSE)\r
+{\r
+       static $LOG;\r
+       \r
+       $config =& get_config();\r
+       if ($config['log_threshold'] == 0)\r
+       {\r
+               return;\r
+       }\r
+\r
+       $LOG =& load_class('Log');\r
+       $LOG->write_log($level, $message, $php_error);\r
+}\r
+\r
+/**\r
+* Exception Handler\r
+*\r
+* This is the custom exception handler that is declaired at the top\r
+* of Codeigniter.php.  The main reason we use this is permit\r
+* PHP errors to be logged in our own log files since we may\r
+* not have access to server logs. Since this function\r
+* effectively intercepts PHP errors, however, we also need\r
+* to display errors based on the current error_reporting level.\r
+* We do that with the use of a PHP error template.\r
+*\r
+* @access      private\r
+* @return      void\r
+*/\r
+function _exception_handler($severity, $message, $filepath, $line)\r
+{      \r
+        // We don't bother with "strict" notices since they will fill up\r
+        // the log file with information that isn't normally very\r
+        // helpful.  For example, if you are running PHP 5 and you\r
+        // use version 4 style class functions (without prefixes\r
+        // like "public", "private", etc.) you'll get notices telling\r
+        // you that these have been deprecated.\r
+       \r
+       if ($severity == E_STRICT)\r
+       {\r
+               return;\r
+       }\r
+\r
+       $error =& load_class('Exceptions');\r
+\r
+       // Should we display the error?\r
+       // We'll get the current error_reporting level and add its bits\r
+       // with the severity bits to find out.\r
+       \r
+       if (($severity & error_reporting()) == $severity)\r
+       {\r
+               $error->show_php_error($severity, $message, $filepath, $line);\r
+       }\r
+       \r
+       // Should we log the error?  No?  We're done...\r
+       $config =& get_config();\r
+       if ($config['log_threshold'] == 0)\r
+       {\r
+               return;\r
+       }\r
+\r
+       $error->log_exception($severity, $message, $filepath, $line);\r
+}\r
+\r
+\r
+\r
+/* End of file Common.php */\r
+/* Location: ./system/codeigniter/Common.php */
\ No newline at end of file
diff --git a/codeigniter/Compat.php b/codeigniter/Compat.php
new file mode 100644 (file)
index 0000000..291f01d
--- /dev/null
@@ -0,0 +1,93 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Compatibility Functions\r
+ *\r
+ * Function overrides for older versions of PHP or PHP environments missing\r
+ * certain extensions / libraries\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage codeigniter\r
+ * @category   Compatibility Functions\r
+ * @author             ExpressionEngine Development Team\r
+ * @link               http://codeigniter.com/user_guide/\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/*\r
+ * PHP versions prior to 5.0 don't support the E_STRICT constant\r
+ * so we need to explicitly define it otherwise the Exception class \r
+ * will generate errors when running under PHP 4\r
+ *\r
+ */\r
+if ( ! defined('E_STRICT'))\r
+{\r
+       define('E_STRICT', 2048);\r
+}\r
+\r
+/**\r
+ * ctype_digit()\r
+ *\r
+ * Determines if a string is comprised only of digits\r
+ * http://us.php.net/manual/en/function.ctype_digit.php\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     bool\r
+ */\r
+if ( ! function_exists('ctype_digit'))\r
+{\r
+       function ctype_digit($str)\r
+       {\r
+               if ( ! is_string($str) OR $str == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return ! preg_match('/[^0-9]/', $str);\r
+       }       \r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * ctype_alnum()\r
+ *\r
+ * Determines if a string is comprised of only alphanumeric characters\r
+ * http://us.php.net/manual/en/function.ctype-alnum.php\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     bool\r
+ */\r
+if ( ! function_exists('ctype_alnum'))\r
+{\r
+       function ctype_alnum($str)\r
+       {\r
+               if ( ! is_string($str) OR $str == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return ! preg_match('/[^0-9a-z]/i', $str);\r
+       }       \r
+}\r
+\r
+/* End of file Compat.php */\r
+/* Location: ./system/codeigniter/Compat.php */
\ No newline at end of file
diff --git a/codeigniter/index.html b/codeigniter/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/DB.php b/database/DB.php
new file mode 100644 (file)
index 0000000..2b3ff3d
--- /dev/null
@@ -0,0 +1,146 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Initialize the database\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+function &DB($params = '', $active_record_override = FALSE)\r
+{\r
+       // Load the DB config file if a DSN string wasn't passed\r
+       if (is_string($params) AND strpos($params, '://') === FALSE)\r
+       {\r
+               include(APPPATH.'config/database'.EXT);\r
+               \r
+               if ( ! isset($db) OR count($db) == 0)\r
+               {\r
+                       show_error('No database connection settings were found in the database config file.');\r
+               }\r
+               \r
+               if ($params != '')\r
+               {\r
+                       $active_group = $params;\r
+               }\r
+               \r
+               if ( ! isset($active_group) OR ! isset($db[$active_group]))\r
+               {\r
+                       show_error('You have specified an invalid database connection group.');\r
+               }\r
+               \r
+               $params = $db[$active_group];\r
+       }\r
+       elseif (is_string($params))\r
+       {\r
+               \r
+               /* parse the URL from the DSN string\r
+               *  Database settings can be passed as discreet\r
+               *  parameters or as a data source name in the first\r
+               *  parameter. DSNs must have this prototype:\r
+               *  $dsn = 'driver://username:password@hostname/database';\r
+               */\r
+       \r
+               if (($dns = @parse_url($params)) === FALSE)\r
+               {\r
+                       show_error('Invalid DB Connection String');\r
+               }\r
+               \r
+               $params = array(\r
+                                                       'dbdriver'      => $dns['scheme'],\r
+                                                       'hostname'      => (isset($dns['host'])) ? rawurldecode($dns['host']) : '',\r
+                                                       'username'      => (isset($dns['user'])) ? rawurldecode($dns['user']) : '',\r
+                                                       'password'      => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',\r
+                                                       'database'      => (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''\r
+                                               );\r
+               \r
+               // were additional config items set?\r
+               if (isset($dns['query']))\r
+               {\r
+                       parse_str($dns['query'], $extra);\r
+\r
+                       foreach($extra as $key => $val)\r
+                       {\r
+                               // booleans please\r
+                               if (strtoupper($val) == "TRUE")\r
+                               {\r
+                                       $val = TRUE;\r
+                               }\r
+                               elseif (strtoupper($val) == "FALSE")\r
+                               {\r
+                                       $val = FALSE;\r
+                               }\r
+\r
+                               $params[$key] = $val;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // No DB specified yet?  Beat them senseless...\r
+       if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')\r
+       {\r
+               show_error('You have not selected a database type to connect to.');\r
+       }\r
+\r
+       // Load the DB classes.  Note: Since the active record class is optional\r
+       // we need to dynamically create a class that extends proper parent class\r
+       // based on whether we're using the active record class or not.\r
+       // Kudos to Paul for discovering this clever use of eval()\r
+       \r
+       if ($active_record_override == TRUE)\r
+       {\r
+               $active_record = TRUE;\r
+       }\r
+       \r
+       require_once(BASEPATH.'database/DB_driver'.EXT);\r
+\r
+       if ( ! isset($active_record) OR $active_record == TRUE)\r
+       {\r
+               require_once(BASEPATH.'database/DB_active_rec'.EXT);\r
+               \r
+               if ( ! class_exists('CI_DB'))\r
+               {\r
+                       eval('class CI_DB extends CI_DB_active_record { }');\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if ( ! class_exists('CI_DB'))\r
+               {\r
+                       eval('class CI_DB extends CI_DB_driver { }');\r
+               }\r
+       }\r
+                       \r
+       require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);\r
+\r
+       // Instantiate the DB adapter\r
+       $driver = 'CI_DB_'.$params['dbdriver'].'_driver';\r
+       $DB =& new $driver($params);\r
+       \r
+       if ($DB->autoinit == TRUE)\r
+       {\r
+               $DB->initialize();\r
+       }\r
+       \r
+       return $DB;\r
+}      \r
+\r
+\r
+\r
+/* End of file DB.php */\r
+/* Location: ./system/database/DB.php */
\ No newline at end of file
diff --git a/database/DB_active_rec.php b/database/DB_active_rec.php
new file mode 100644 (file)
index 0000000..e379825
--- /dev/null
@@ -0,0 +1,1770 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Active Record Class\r
+ *\r
+ * This is the platform-independent base Active Record implementation class.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_active_record extends CI_DB_driver {\r
+\r
+       var $ar_select                          = array();\r
+       var $ar_distinct                        = FALSE;\r
+       var $ar_from                            = array();\r
+       var $ar_join                            = array();\r
+       var $ar_where                           = array();\r
+       var $ar_like                            = array();\r
+       var $ar_groupby                         = array();\r
+       var $ar_having                          = array();\r
+       var $ar_limit                           = FALSE;\r
+       var $ar_offset                          = FALSE;\r
+       var $ar_order                           = FALSE;\r
+       var $ar_orderby                         = array();\r
+       var $ar_set                                     = array();      \r
+       var $ar_wherein                         = array();\r
+       var $ar_aliased_tables          = array();\r
+       var $ar_store_array                     = array();\r
+       \r
+       // Active Record Caching variables\r
+       var $ar_caching                         = FALSE;\r
+       var $ar_cache_exists            = array();\r
+       var $ar_cache_select            = array();\r
+       var $ar_cache_from                      = array();\r
+       var $ar_cache_join                      = array();\r
+       var $ar_cache_where                     = array();\r
+       var $ar_cache_like                      = array();\r
+       var $ar_cache_groupby           = array();\r
+       var $ar_cache_having            = array();\r
+       var $ar_cache_orderby           = array();\r
+       var $ar_cache_set                       = array();      \r
+\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select\r
+        *\r
+        * Generates the SELECT portion of the query\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function select($select = '*', $escape = NULL)\r
+       {\r
+               // Set the global value if this was sepecified  \r
+               if (is_bool($escape))\r
+               {\r
+                       $this->_protect_identifiers = $escape;\r
+               }\r
+               \r
+               if (is_string($select))\r
+               {\r
+                       $select = explode(',', $select);\r
+               }\r
+\r
+               foreach ($select as $val)\r
+               {\r
+                       $val = trim($val);\r
+\r
+                       if ($val != '')\r
+                       {\r
+                               $this->ar_select[] = $val;\r
+\r
+                               if ($this->ar_caching === TRUE)\r
+                               {\r
+                                       $this->ar_cache_select[] = $val;\r
+                                       $this->ar_cache_exists[] = 'select';\r
+                               }\r
+                       }\r
+               }\r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select Max\r
+        *\r
+        * Generates a SELECT MAX(field) portion of a query\r
+        *\r
+        * @access      public\r
+        * @param       string  the field\r
+        * @param       string  an alias\r
+        * @return      object\r
+        */\r
+       function select_max($select = '', $alias = '')\r
+       {\r
+               return $this->_max_min_avg_sum($select, $alias, 'MAX');\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select Min\r
+        *\r
+        * Generates a SELECT MIN(field) portion of a query\r
+        *\r
+        * @access      public\r
+        * @param       string  the field\r
+        * @param       string  an alias\r
+        * @return      object\r
+        */\r
+       function select_min($select = '', $alias = '')\r
+       {\r
+               return $this->_max_min_avg_sum($select, $alias, 'MIN');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select Average\r
+        *\r
+        * Generates a SELECT AVG(field) portion of a query\r
+        *\r
+        * @access      public\r
+        * @param       string  the field\r
+        * @param       string  an alias\r
+        * @return      object\r
+        */\r
+       function select_avg($select = '', $alias = '')\r
+       {\r
+               return $this->_max_min_avg_sum($select, $alias, 'AVG');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select Sum\r
+        *\r
+        * Generates a SELECT SUM(field) portion of a query\r
+        *\r
+        * @access      public\r
+        * @param       string  the field\r
+        * @param       string  an alias\r
+        * @return      object\r
+        */\r
+       function select_sum($select = '', $alias = '')\r
+       {\r
+               return $this->_max_min_avg_sum($select, $alias, 'SUM');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Processing Function for the four functions above:\r
+        *\r
+        *      select_max()\r
+        *      select_min()\r
+        *      select_avg()\r
+        *  select_sum()\r
+        *      \r
+        * @access      public\r
+        * @param       string  the field\r
+        * @param       string  an alias\r
+        * @return      object\r
+        */\r
+       function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')\r
+       {\r
+               if ( ! is_string($select) OR $select == '')\r
+               {\r
+                       $this->display_error('db_invalid_query');\r
+               }\r
+       \r
+               $type = strtoupper($type);\r
+       \r
+               if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))\r
+               {\r
+                       show_error('Invalid function type: '.$type);\r
+               }\r
+       \r
+               if ($alias == '')\r
+               {\r
+                       $alias = $this->_create_alias_from_table(trim($select));\r
+               }\r
+       \r
+               $sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;\r
+\r
+               $this->ar_select[] = $sql;\r
+               \r
+               if ($this->ar_caching === TRUE)\r
+               {\r
+                       $this->ar_cache_select[] = $sql;\r
+                       $this->ar_cache_exists[] = 'select';\r
+               }\r
+               \r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determines the alias name based on the table\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _create_alias_from_table($item)\r
+       {\r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       return end(explode('.', $item));\r
+               }\r
+               \r
+               return $item;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * DISTINCT\r
+        *\r
+        * Sets a flag which tells the query string compiler to add DISTINCT\r
+        *\r
+        * @access      public\r
+        * @param       bool\r
+        * @return      object\r
+        */\r
+       function distinct($val = TRUE)\r
+       {\r
+               $this->ar_distinct = (is_bool($val)) ? $val : TRUE;\r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From\r
+        *\r
+        * Generates the FROM portion of the query\r
+        *\r
+        * @access      public\r
+        * @param       mixed   can be a string or array\r
+        * @return      object\r
+        */\r
+       function from($from)\r
+       {\r
+               foreach ((array)$from as $val)\r
+               {\r
+                       // Extract any aliases that might exist.  We use this information\r
+                       // in the _protect_identifiers to know whether to add a table prefix \r
+                       $this->_track_aliases($val);\r
+\r
+                       $this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);\r
+                       \r
+                       if ($this->ar_caching === TRUE)\r
+                       {\r
+                               $this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);\r
+                               $this->ar_cache_exists[] = 'from';\r
+                       }\r
+               }\r
+\r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Join\r
+        *\r
+        * Generates the JOIN portion of the query\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string  the join condition\r
+        * @param       string  the type of join\r
+        * @return      object\r
+        */\r
+       function join($table, $cond, $type = '')\r
+       {               \r
+               if ($type != '')\r
+               {\r
+                       $type = strtoupper(trim($type));\r
+\r
+                       if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))\r
+                       {\r
+                               $type = '';\r
+                       }\r
+                       else\r
+                       {\r
+                               $type .= ' ';\r
+                       }\r
+               }\r
+\r
+               // Extract any aliases that might exist.  We use this information\r
+               // in the _protect_identifiers to know whether to add a table prefix \r
+               $this->_track_aliases($table);\r
+\r
+               // Strip apart the condition and protect the identifiers\r
+               if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))\r
+               {\r
+                       $match[1] = $this->_protect_identifiers($match[1]);\r
+                       $match[3] = $this->_protect_identifiers($match[3]);\r
+               \r
+                       $cond = $match[1].$match[2].$match[3];          \r
+               }\r
+               \r
+               // Assemble the JOIN statement\r
+               $join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;\r
+\r
+               $this->ar_join[] = $join;\r
+               if ($this->ar_caching === TRUE)\r
+               {\r
+                       $this->ar_cache_join[] = $join;\r
+                       $this->ar_cache_exists[] = 'join';\r
+               }\r
+\r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where\r
+        *\r
+        * Generates the WHERE portion of the query. Separates\r
+        * multiple calls with AND\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function where($key, $value = NULL, $escape = TRUE)\r
+       {\r
+               return $this->_where($key, $value, 'AND ', $escape);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * OR Where\r
+        *\r
+        * Generates the WHERE portion of the query. Separates\r
+        * multiple calls with OR\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function or_where($key, $value = NULL, $escape = TRUE)\r
+       {\r
+               return $this->_where($key, $value, 'OR ', $escape);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * orwhere() is an alias of or_where()\r
+        * this function is here for backwards compatibility, as\r
+        * orwhere() has been deprecated\r
+        */\r
+       function orwhere($key, $value = NULL, $escape = TRUE)\r
+       {\r
+               return $this->or_where($key, $value, $escape);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where\r
+        *\r
+        * Called by where() or orwhere()\r
+        *\r
+        * @access      private\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)\r
+       {\r
+               if ( ! is_array($key))\r
+               {\r
+                       $key = array($key => $value);\r
+               }\r
+               \r
+               // If the escape value was not set will will base it on the global setting\r
+               if ( ! is_bool($escape))\r
+               {\r
+                       $escape = $this->_protect_identifiers;\r
+               }\r
+\r
+               foreach ($key as $k => $v)\r
+               {\r
+                       $prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;\r
+\r
+                       if (is_null($v) && ! $this->_has_operator($k))\r
+                       {\r
+                               // value appears not to have been set, assign the test to IS NULL\r
+                               $k .= ' IS NULL';\r
+                       }\r
+                       \r
+                       if ( ! is_null($v))\r
+                       {\r
+                               if ($escape === TRUE)\r
+                               {\r
+                                       $k = $this->_protect_identifiers($k, FALSE, $escape);\r
+                                       \r
+                                       $v = ' '.$this->escape($v);\r
+                               }\r
+\r
+                               if ( ! $this->_has_operator($k))\r
+                               {\r
+                                       $k .= ' =';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $k = $this->_protect_identifiers($k, FALSE, $escape);                   \r
+                       }\r
+\r
+                       $this->ar_where[] = $prefix.$k.$v;\r
+                       \r
+                       if ($this->ar_caching === TRUE)\r
+                       {\r
+                               $this->ar_cache_where[] = $prefix.$k.$v;\r
+                               $this->ar_cache_exists[] = 'where';\r
+                       }\r
+                       \r
+               }\r
+               \r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where_in\r
+        *\r
+        * Generates a WHERE field IN ('item', 'item') SQL query joined with\r
+        * AND if appropriate\r
+        *\r
+        * @access      public\r
+        * @param       string  The field to search\r
+        * @param       array   The values searched on\r
+        * @return      object\r
+        */\r
+       function where_in($key = NULL, $values = NULL)\r
+       {\r
+               return $this->_where_in($key, $values);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where_in_or\r
+        *\r
+        * Generates a WHERE field IN ('item', 'item') SQL query joined with\r
+        * OR if appropriate\r
+        *\r
+        * @access      public\r
+        * @param       string  The field to search\r
+        * @param       array   The values searched on\r
+        * @return      object\r
+        */\r
+       function or_where_in($key = NULL, $values = NULL)\r
+       {\r
+               return $this->_where_in($key, $values, FALSE, 'OR ');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where_not_in\r
+        *\r
+        * Generates a WHERE field NOT IN ('item', 'item') SQL query joined\r
+        * with AND if appropriate\r
+        *\r
+        * @access      public\r
+        * @param       string  The field to search\r
+        * @param       array   The values searched on\r
+        * @return      object\r
+        */\r
+       function where_not_in($key = NULL, $values = NULL)\r
+       {\r
+               return $this->_where_in($key, $values, TRUE);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where_not_in_or\r
+        *\r
+        * Generates a WHERE field NOT IN ('item', 'item') SQL query joined\r
+        * with OR if appropriate\r
+        *\r
+        * @access      public\r
+        * @param       string  The field to search\r
+        * @param       array   The values searched on\r
+        * @return      object\r
+        */\r
+       function or_where_not_in($key = NULL, $values = NULL)\r
+       {\r
+               return $this->_where_in($key, $values, TRUE, 'OR ');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Where_in\r
+        *\r
+        * Called by where_in, where_in_or, where_not_in, where_not_in_or\r
+        *\r
+        * @access      public\r
+        * @param       string  The field to search\r
+        * @param       array   The values searched on\r
+        * @param       boolean If the statement would be IN or NOT IN\r
+        * @param       string  \r
+        * @return      object\r
+        */\r
+       function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')\r
+       {\r
+               if ($key === NULL OR $values === NULL)\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               if ( ! is_array($values))\r
+               {\r
+                       $values = array($values);\r
+               }\r
+               \r
+               $not = ($not) ? ' NOT' : '';\r
+\r
+               foreach ($values as $value)\r
+               {\r
+                       $this->ar_wherein[] = $this->escape($value);\r
+               }\r
+\r
+               $prefix = (count($this->ar_where) == 0) ? '' : $type;\r
\r
+               $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";\r
+\r
+               $this->ar_where[] = $where_in;\r
+               if ($this->ar_caching === TRUE)\r
+               {\r
+                       $this->ar_cache_where[] = $where_in;\r
+                       $this->ar_cache_exists[] = 'where';\r
+               }\r
+\r
+               // reset the array for multiple calls\r
+               $this->ar_wherein = array();\r
+               return $this;\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Like\r
+        *\r
+        * Generates a %LIKE% portion of the query. Separates\r
+        * multiple calls with AND\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function like($field, $match = '', $side = 'both')\r
+       {\r
+               return $this->_like($field, $match, 'AND ', $side);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Not Like\r
+        *\r
+        * Generates a NOT LIKE portion of the query. Separates\r
+        * multiple calls with AND\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function not_like($field, $match = '', $side = 'both')\r
+       {\r
+               return $this->_like($field, $match, 'AND ', $side, 'NOT');\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * OR Like\r
+        *\r
+        * Generates a %LIKE% portion of the query. Separates\r
+        * multiple calls with OR\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function or_like($field, $match = '', $side = 'both')\r
+       {\r
+               return $this->_like($field, $match, 'OR ', $side);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * OR Not Like\r
+        *\r
+        * Generates a NOT LIKE portion of the query. Separates\r
+        * multiple calls with OR\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @return      object\r
+        */\r
+       function or_not_like($field, $match = '', $side = 'both')\r
+       {\r
+               return $this->_like($field, $match, 'OR ', $side, 'NOT');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * orlike() is an alias of or_like()\r
+        * this function is here for backwards compatibility, as\r
+        * orlike() has been deprecated\r
+        */\r
+       function orlike($field, $match = '', $side = 'both')\r
+       {\r
+               return $this->or_like($field, $match, $side);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Like\r
+        *\r
+        * Called by like() or orlike()\r
+        *\r
+        * @access      private\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')\r
+       {\r
+               if ( ! is_array($field))\r
+               {\r
+                       $field = array($field => $match);\r
+               }\r
+       \r
+               foreach ($field as $k => $v)\r
+               {\r
+                       $k = $this->_protect_identifiers($k);\r
+\r
+                       $prefix = (count($this->ar_like) == 0) ? '' : $type;\r
+\r
+                       $v = $this->escape_str($v);\r
+\r
+                       if ($side == 'before')\r
+                       {\r
+                               $like_statement = $prefix." $k $not LIKE '%{$v}'";\r
+                       }\r
+                       elseif ($side == 'after')\r
+                       {\r
+                               $like_statement = $prefix." $k $not LIKE '{$v}%'";\r
+                       }\r
+                       else\r
+                       {\r
+                               $like_statement = $prefix." $k $not LIKE '%{$v}%'";\r
+                       }\r
+                       \r
+                       $this->ar_like[] = $like_statement;\r
+                       if ($this->ar_caching === TRUE)\r
+                       {\r
+                               $this->ar_cache_like[] = $like_statement;\r
+                               $this->ar_cache_exists[] = 'like';\r
+                       }\r
+                       \r
+               }\r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * GROUP BY\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function group_by($by)\r
+       {\r
+               if (is_string($by))\r
+               {\r
+                       $by = explode(',', $by);\r
+               }\r
+       \r
+               foreach ($by as $val)\r
+               {\r
+                       $val = trim($val);\r
+               \r
+                       if ($val != '')\r
+                       {\r
+                               $this->ar_groupby[] = $this->_protect_identifiers($val);\r
+                               \r
+                               if ($this->ar_caching === TRUE)\r
+                               {\r
+                                       $this->ar_cache_groupby[] = $this->_protect_identifiers($val);\r
+                                       $this->ar_cache_exists[] = 'groupby';\r
+                               }\r
+                       }\r
+               }\r
+               return $this;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * groupby() is an alias of group_by()\r
+        * this function is here for backwards compatibility, as\r
+        * groupby() has been deprecated\r
+        */\r
+       function groupby($by)\r
+       {\r
+               return $this->group_by($by);\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the HAVING value\r
+        *\r
+        * Separates multiple calls with AND\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function having($key, $value = '', $escape = TRUE)\r
+       {\r
+               return $this->_having($key, $value, 'AND ', $escape);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * orhaving() is an alias of or_having()\r
+        * this function is here for backwards compatibility, as\r
+        * orhaving() has been deprecated\r
+        */\r
+\r
+       function orhaving($key, $value = '', $escape = TRUE)\r
+       {\r
+               return $this->or_having($key, $value, $escape);\r
+       }       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the OR HAVING value\r
+        *\r
+        * Separates multiple calls with OR\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function or_having($key, $value = '', $escape = TRUE)\r
+       {\r
+               return $this->_having($key, $value, 'OR ', $escape);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the HAVING values\r
+        *\r
+        * Called by having() or or_having()\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      object\r
+        */\r
+       function _having($key, $value = '', $type = 'AND ', $escape = TRUE)\r
+       {\r
+               if ( ! is_array($key))\r
+               {\r
+                       $key = array($key => $value);\r
+               }\r
+       \r
+               foreach ($key as $k => $v)\r
+               {\r
+                       $prefix = (count($this->ar_having) == 0) ? '' : $type;\r
+\r
+                       if ($escape === TRUE)\r
+                       {\r
+                               $k = $this->_protect_identifiers($k);\r
+                       }\r
+\r
+                       if ( ! $this->_has_operator($k))\r
+                       {\r
+                               $k .= ' = ';\r
+                       }\r
+\r
+                       if ($v != '')\r
+                       {\r
+                               $v = ' '.$this->escape_str($v);\r
+                       }\r
+                       \r
+                       $this->ar_having[] = $prefix.$k.$v;\r
+                       if ($this->ar_caching === TRUE)\r
+                       {\r
+                               $this->ar_cache_having[] = $prefix.$k.$v;\r
+                               $this->ar_cache_exists[] = 'having';\r
+                       }\r
+               }\r
+               \r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the ORDER BY value\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string  direction: asc or desc\r
+        * @return      object\r
+        */\r
+       function order_by($orderby, $direction = '')\r
+       {\r
+               if (strtolower($direction) == 'random')\r
+               {\r
+                       $orderby = ''; // Random results want or don't need a field name\r
+                       $direction = $this->_random_keyword;\r
+               }\r
+               elseif (trim($direction) != '')\r
+               {\r
+                       $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';\r
+               }\r
+               \r
+               $orderby_statement = $this->_protect_identifiers($orderby).$direction;\r
+               \r
+               $this->ar_orderby[] = $orderby_statement;\r
+               if ($this->ar_caching === TRUE)\r
+               {\r
+                       $this->ar_cache_orderby[] = $orderby_statement;\r
+                       $this->ar_cache_exists[] = 'orderby';\r
+               }\r
+\r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * orderby() is an alias of order_by()\r
+        * this function is here for backwards compatibility, as\r
+        * orderby() has been deprecated\r
+        */\r
+       function orderby($orderby, $direction = '')\r
+       {\r
+               return $this->order_by($orderby, $direction);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the LIMIT value\r
+        *\r
+        * @access      public\r
+        * @param       integer the limit value\r
+        * @param       integer the offset value\r
+        * @return      object\r
+        */\r
+       function limit($value, $offset = '')\r
+       {\r
+               $this->ar_limit = $value;\r
+\r
+               if ($offset != '')\r
+               {\r
+                       $this->ar_offset = $offset;\r
+               }\r
+               \r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sets the OFFSET value\r
+        *\r
+        * @access      public\r
+        * @param       integer the offset value\r
+        * @return      object\r
+        */\r
+       function offset($offset)\r
+       {\r
+               $this->ar_offset = $offset;\r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The "set" function.  Allows key/value pairs to be set for inserting or updating\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @param       boolean\r
+        * @return      object\r
+        */\r
+       function set($key, $value = '', $escape = TRUE)\r
+       {\r
+               $key = $this->_object_to_array($key);\r
+       \r
+               if ( ! is_array($key))\r
+               {\r
+                       $key = array($key => $value);\r
+               }       \r
+\r
+               foreach ($key as $k => $v)\r
+               {\r
+                       if ($escape === FALSE)\r
+                       {\r
+                               $this->ar_set[$this->_protect_identifiers($k)] = $v;\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);\r
+                       }\r
+               }\r
+               \r
+               return $this;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get\r
+        *\r
+        * Compiles the select statement based on the other functions called\r
+        * and runs the query\r
+        *\r
+        * @access      public\r
+        * @param       string  the table\r
+        * @param       string  the limit clause\r
+        * @param       string  the offset clause\r
+        * @return      object\r
+        */\r
+       function get($table = '', $limit = null, $offset = null)\r
+       {\r
+               if ($table != '')\r
+               {\r
+                       $this->_track_aliases($table);\r
+                       $this->from($table);\r
+               }\r
+               \r
+               if ( ! is_null($limit))\r
+               {\r
+                       $this->limit($limit, $offset);\r
+               }\r
+                       \r
+               $sql = $this->_compile_select();\r
+\r
+               $result = $this->query($sql);\r
+               $this->_reset_select();\r
+               return $result;\r
+       }\r
+\r
+       /**\r
+        * "Count All Results" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records \r
+        * returned by an Active Record query.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all_results($table = '')\r
+       {\r
+               if ($table != '')\r
+               {\r
+                       $this->_track_aliases($table);\r
+                       $this->from($table);\r
+               }\r
+               \r
+               $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));\r
+\r
+               $query = $this->query($sql);\r
+               $this->_reset_select();\r
+       \r
+               if ($query->num_rows() == 0)\r
+               {\r
+                       return '0';\r
+               }\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get_Where\r
+        *\r
+        * Allows the where clause, limit and offset to be added directly\r
+        *\r
+        * @access      public\r
+        * @param       string  the where clause\r
+        * @param       string  the limit clause\r
+        * @param       string  the offset clause\r
+        * @return      object\r
+        */\r
+       function get_where($table = '', $where = null, $limit = null, $offset = null)\r
+       {\r
+               if ($table != '')\r
+               {\r
+                       $this->from($table);\r
+               }\r
+\r
+               if ( ! is_null($where))\r
+               {\r
+                       $this->where($where);\r
+               }\r
+               \r
+               if ( ! is_null($limit))\r
+               {\r
+                       $this->limit($limit, $offset);\r
+               }\r
+                       \r
+               $sql = $this->_compile_select();\r
+\r
+               $result = $this->query($sql);\r
+               $this->_reset_select();\r
+               return $result;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * getwhere() is an alias of get_where()\r
+        * this function is here for backwards compatibility, as\r
+        * getwhere() has been deprecated\r
+        */\r
+       function getwhere($table = '', $where = null, $limit = null, $offset = null)\r
+       {\r
+               return $this->get_where($table, $where, $limit, $offset);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert\r
+        *\r
+        * Compiles an insert string and runs the query\r
+        *\r
+        * @access      public\r
+        * @param       string  the table to retrieve the results from\r
+        * @param       array   an associative array of insert values\r
+        * @return      object\r
+        */\r
+       function insert($table = '', $set = NULL)\r
+       {       \r
+               if ( ! is_null($set))\r
+               {\r
+                       $this->set($set);\r
+               }\r
+       \r
+               if (count($this->ar_set) == 0)\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_must_use_set');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+\r
+               if ($table == '')\r
+               {\r
+                       if ( ! isset($this->ar_from[0]))\r
+                       {\r
+                               if ($this->db_debug)\r
+                               {\r
+                                       return $this->display_error('db_must_set_table');\r
+                               }\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       $table = $this->ar_from[0];\r
+               }\r
+\r
+               $sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));\r
+               \r
+               $this->_reset_write();\r
+               return $this->query($sql);              \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update\r
+        *\r
+        * Compiles an update string and runs the query\r
+        *\r
+        * @access      public\r
+        * @param       string  the table to retrieve the results from\r
+        * @param       array   an associative array of update values\r
+        * @param       mixed   the where clause\r
+        * @return      object\r
+        */\r
+       function update($table = '', $set = NULL, $where = NULL, $limit = NULL)\r
+       {\r
+               // Combine any cached components with the current statements\r
+               $this->_merge_cache();\r
+\r
+               if ( ! is_null($set))\r
+               {\r
+                       $this->set($set);\r
+               }\r
+       \r
+               if (count($this->ar_set) == 0)\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_must_use_set');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+\r
+               if ($table == '')\r
+               {\r
+                       if ( ! isset($this->ar_from[0]))\r
+                       {\r
+                               if ($this->db_debug)\r
+                               {\r
+                                       return $this->display_error('db_must_set_table');\r
+                               }\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       $table = $this->ar_from[0];\r
+               }\r
+               \r
+               if ($where != NULL)\r
+               {\r
+                       $this->where($where);\r
+               }\r
+\r
+               if ($limit != NULL)\r
+               {\r
+                       $this->limit($limit);\r
+               }\r
+               \r
+               $sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);\r
+               \r
+               $this->_reset_write();\r
+               return $this->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Empty Table\r
+        *\r
+        * Compiles a delete string and runs "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table to empty\r
+        * @return      object\r
+        */\r
+       function empty_table($table = '')\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       if ( ! isset($this->ar_from[0]))\r
+                       {\r
+                               if ($this->db_debug)\r
+                               {\r
+                                       return $this->display_error('db_must_set_table');\r
+                               }\r
+                               return FALSE;\r
+                       }\r
+\r
+                       $table = $this->ar_from[0];\r
+               }\r
+               else\r
+               {\r
+                       $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
+               }\r
+\r
+               $sql = $this->_delete($table);\r
+\r
+               $this->_reset_write();\r
+               \r
+               return $this->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate\r
+        *\r
+        * Compiles a truncate string and runs the query\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table to truncate\r
+        * @return      object\r
+        */\r
+       function truncate($table = '')\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       if ( ! isset($this->ar_from[0]))\r
+                       {\r
+                               if ($this->db_debug)\r
+                               {\r
+                                       return $this->display_error('db_must_set_table');\r
+                               }\r
+                               return FALSE;\r
+                       }\r
+\r
+                       $table = $this->ar_from[0];\r
+               }\r
+               else\r
+               {\r
+                       $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
+               }\r
+\r
+               $sql = $this->_truncate($table);\r
+\r
+               $this->_reset_write();\r
+               \r
+               return $this->query($sql);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete\r
+        *\r
+        * Compiles a delete string and runs the query\r
+        *\r
+        * @access      public\r
+        * @param       mixed   the table(s) to delete from. String or array\r
+        * @param       mixed   the where clause\r
+        * @param       mixed   the limit clause\r
+        * @param       boolean\r
+        * @return      object\r
+        */\r
+       function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)\r
+       {\r
+               // Combine any cached components with the current statements\r
+               $this->_merge_cache();\r
+\r
+               if ($table == '')\r
+               {\r
+                       if ( ! isset($this->ar_from[0]))\r
+                       {\r
+                               if ($this->db_debug)\r
+                               {\r
+                                       return $this->display_error('db_must_set_table');\r
+                               }\r
+                               return FALSE;\r
+                       }\r
+\r
+                       $table = $this->ar_from[0];\r
+               }\r
+               elseif (is_array($table))\r
+               {\r
+                       foreach($table as $single_table)\r
+                       {\r
+                               $this->delete($single_table, $where, $limit, FALSE);\r
+                       }\r
+\r
+                       $this->_reset_write();\r
+                       return;\r
+               }\r
+               else\r
+               {\r
+                       $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);\r
+               }\r
+\r
+               if ($where != '')\r
+               {\r
+                       $this->where($where);\r
+               }\r
+\r
+               if ($limit != NULL)\r
+               {\r
+                       $this->limit($limit);\r
+               }\r
+\r
+               if (count($this->ar_where) == 0 && count($this->ar_like) == 0)\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_del_must_use_where');\r
+                       }\r
+\r
+                       return FALSE;\r
+               }               \r
+\r
+               $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);\r
+\r
+               if ($reset_data)\r
+               {\r
+                       $this->_reset_write();\r
+               }\r
+               \r
+               return $this->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * DB Prefix\r
+        *\r
+        * Prepends a database prefix if one exists in configuration\r
+        *\r
+        * @access      public\r
+        * @param       string  the table\r
+        * @return      string\r
+        */\r
+       function dbprefix($table = '')\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       $this->display_error('db_table_name_required');\r
+               }\r
+\r
+               return $this->dbprefix.$table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Track Aliases\r
+        *\r
+        * Used to track SQL statements written with aliased tables.\r
+        *\r
+        * @access      private\r
+        * @param       string  The table to inspect\r
+        * @return      string\r
+        */     \r
+       function _track_aliases($table)\r
+       {\r
+               if (is_array($table))\r
+               {\r
+                       foreach ($table as $t)\r
+                       {\r
+                               $this->_track_aliases($t);\r
+                       }\r
+                       return;\r
+               }\r
+               \r
+               // Does the string contain a comma?  If so, we need to separate\r
+               // the string into discreet statements\r
+               if (strpos($table, ',') !== FALSE)\r
+               {\r
+                       return $this->_track_aliases(explode(',', $table));\r
+               }\r
+       \r
+               // if a table alias is used we can recognize it by a space\r
+               if (strpos($table, " ") !== FALSE)\r
+               {\r
+                       // if the alias is written with the AS keyword, remove it\r
+                       $table = preg_replace('/ AS /i', ' ', $table);\r
+                       \r
+                       // Grab the alias\r
+                       $table = trim(strrchr($table, " "));\r
+                       \r
+                       // Store the alias, if it doesn't already exist\r
+                       if ( ! in_array($table, $this->ar_aliased_tables))\r
+                       {\r
+                               $this->ar_aliased_tables[] = $table;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Compile the SELECT statement\r
+        *\r
+        * Generates a query string based on which functions were used.\r
+        * Should not be called directly.  The get() function calls it.\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _compile_select($select_override = FALSE)\r
+       {\r
+               // Combine any cached components with the current statements\r
+               $this->_merge_cache();\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "select" portion of the query\r
+\r
+               if ($select_override !== FALSE)\r
+               {\r
+                       $sql = $select_override;\r
+               }\r
+               else\r
+               {\r
+                       $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';\r
+               \r
+                       if (count($this->ar_select) == 0)\r
+                       {\r
+                               $sql .= '*';            \r
+                       }\r
+                       else\r
+                       {                               \r
+                               // Cycle through the "select" portion of the query and prep each column name.\r
+                               // The reason we protect identifiers here rather then in the select() function\r
+                               // is because until the user calls the from() function we don't know if there are aliases\r
+                               foreach ($this->ar_select as $key => $val)\r
+                               {\r
+                                       $this->ar_select[$key] = $this->_protect_identifiers($val);\r
+                               }\r
+                               \r
+                               $sql .= implode(', ', $this->ar_select);\r
+                       }\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "FROM" portion of the query\r
+\r
+               if (count($this->ar_from) > 0)\r
+               {\r
+                       $sql .= "\nFROM ";\r
+\r
+                       $sql .= $this->_from_tables($this->ar_from);\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "JOIN" portion of the query\r
+\r
+               if (count($this->ar_join) > 0)\r
+               {\r
+                       $sql .= "\n";\r
+\r
+                       $sql .= implode("\n", $this->ar_join);\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "WHERE" portion of the query\r
+\r
+               if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)\r
+               {\r
+                       $sql .= "\n";\r
+\r
+                       $sql .= "WHERE ";\r
+               }\r
+\r
+               $sql .= implode("\n", $this->ar_where);\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "LIKE" portion of the query\r
+       \r
+               if (count($this->ar_like) > 0)\r
+               {\r
+                       if (count($this->ar_where) > 0)\r
+                       {\r
+                               $sql .= "\nAND ";\r
+                       }\r
+\r
+                       $sql .= implode("\n", $this->ar_like);\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "GROUP BY" portion of the query\r
+       \r
+               if (count($this->ar_groupby) > 0)\r
+               {\r
+                       $sql .= "\nGROUP BY ";\r
+                       \r
+                       $sql .= implode(', ', $this->ar_groupby);\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "HAVING" portion of the query\r
+               \r
+               if (count($this->ar_having) > 0)\r
+               {\r
+                       $sql .= "\nHAVING ";\r
+                       $sql .= implode("\n", $this->ar_having);\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "ORDER BY" portion of the query\r
+\r
+               if (count($this->ar_orderby) > 0)\r
+               {\r
+                       $sql .= "\nORDER BY ";\r
+                       $sql .= implode(', ', $this->ar_orderby);\r
+                       \r
+                       if ($this->ar_order !== FALSE)\r
+                       {\r
+                               $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';\r
+                       }               \r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+               \r
+               // Write the "LIMIT" portion of the query\r
+               \r
+               if (is_numeric($this->ar_limit))\r
+               {\r
+                       $sql .= "\n";\r
+                       $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);\r
+               }\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Object to Array\r
+        *\r
+        * Takes an object as input and converts the class variables to array key/vals\r
+        *\r
+        * @access      public\r
+        * @param       object\r
+        * @return      array\r
+        */\r
+       function _object_to_array($object)\r
+       {\r
+               if ( ! is_object($object))\r
+               {\r
+                       return $object;\r
+               }\r
+               \r
+               $array = array();\r
+               foreach (get_object_vars($object) as $key => $val)\r
+               {\r
+                       // There are some built in keys we need to ignore for this conversion\r
+                       if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')\r
+                       {\r
+                               $array[$key] = $val;\r
+                       }\r
+               }\r
+       \r
+               return $array;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Start Cache\r
+        *\r
+        * Starts AR caching\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function start_cache()\r
+       {\r
+               $this->ar_caching = TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Stop Cache\r
+        *\r
+        * Stops AR caching\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function stop_cache()\r
+       {\r
+               $this->ar_caching = FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Flush Cache\r
+        *\r
+        * Empties the AR cache\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function flush_cache()\r
+       {       \r
+               $this->_reset_run(\r
+                                                       array(\r
+                                                                       'ar_cache_select'       => array(), \r
+                                                                       'ar_cache_from'         => array(), \r
+                                                                       'ar_cache_join'         => array(),\r
+                                                                       'ar_cache_where'        => array(), \r
+                                                                       'ar_cache_like'         => array(), \r
+                                                                       'ar_cache_groupby'      => array(), \r
+                                                                       'ar_cache_having'       => array(), \r
+                                                                       'ar_cache_orderby'      => array(), \r
+                                                                       'ar_cache_set'          => array(),\r
+                                                                       'ar_cache_exists'       => array()\r
+                                                               )\r
+                                                       );      \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Merge Cache\r
+        *\r
+        * When called, this function merges any cached AR arrays with \r
+        * locally called ones.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _merge_cache()\r
+       {\r
+               if (count($this->ar_cache_exists) == 0)\r
+               {\r
+                       return;\r
+               }\r
+\r
+               foreach ($this->ar_cache_exists as $val)\r
+               {\r
+                       $ar_variable    = 'ar_'.$val;\r
+                       $ar_cache_var   = 'ar_cache_'.$val;\r
+\r
+                       if (count($this->$ar_cache_var) == 0)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       $this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));\r
+               }\r
+\r
+               // If we are "protecting identifiers" we need to examine the "from"\r
+               // portion of the query to determine if there are any aliases\r
+               if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)\r
+               {\r
+                       $this->_track_aliases($this->ar_from);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Resets the active record values.  Called by the get() function\r
+        *\r
+        * @access      private\r
+        * @param       array   An array of fields to reset\r
+        * @return      void\r
+        */\r
+       function _reset_run($ar_reset_items)\r
+       {\r
+               foreach ($ar_reset_items as $item => $default_value)\r
+               {\r
+                       if ( ! in_array($item, $this->ar_store_array))\r
+                       {\r
+                               $this->$item = $default_value;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Resets the active record values.  Called by the get() function\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _reset_select()\r
+       {\r
+               $ar_reset_items = array(\r
+                                                               'ar_select'                     => array(), \r
+                                                               'ar_from'                       => array(), \r
+                                                               'ar_join'                       => array(), \r
+                                                               'ar_where'                      => array(), \r
+                                                               'ar_like'                       => array(), \r
+                                                               'ar_groupby'            => array(), \r
+                                                               'ar_having'                     => array(), \r
+                                                               'ar_orderby'            => array(), \r
+                                                               'ar_wherein'            => array(), \r
+                                                               'ar_aliased_tables'     => array(),\r
+                                                               'ar_distinct'           => FALSE, \r
+                                                               'ar_limit'                      => FALSE, \r
+                                                               'ar_offset'                     => FALSE, \r
+                                                               'ar_order'                      => FALSE,\r
+                                                       );\r
+               \r
+               $this->_reset_run($ar_reset_items);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Resets the active record "write" values.\r
+        *\r
+        * Called by the insert() update() and delete() functions\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _reset_write()\r
+       {       \r
+               $ar_reset_items = array(\r
+                                                               'ar_set'                => array(), \r
+                                                               'ar_from'               => array(), \r
+                                                               'ar_where'              => array(), \r
+                                                               'ar_like'               => array(),\r
+                                                               'ar_orderby'    => array(), \r
+                                                               'ar_limit'              => FALSE, \r
+                                                               'ar_order'              => FALSE\r
+                                                               );\r
+\r
+               $this->_reset_run($ar_reset_items);\r
+       }\r
+       \r
+}\r
+\r
+/* End of file DB_active_rec.php */\r
+/* Location: ./system/database/DB_active_rec.php */
\ No newline at end of file
diff --git a/database/DB_cache.php b/database/DB_cache.php
new file mode 100644 (file)
index 0000000..9bb1b16
--- /dev/null
@@ -0,0 +1,195 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Database Cache Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_Cache {\r
+\r
+       var $CI;\r
+       var $db;        // allows passing of db object so that multiple database connections and returned db objects can be supported\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Grabs the CI super object instance so we can access it.\r
+        *\r
+        */     \r
+       function CI_DB_Cache(&$db)\r
+       {\r
+               // Assign the main CI object to $this->CI\r
+               // and load the file helper since we use it a lot\r
+               $this->CI =& get_instance();\r
+               $this->db =& $db;\r
+               $this->CI->load->helper('file');        \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Cache Directory Path\r
+        *\r
+        * @access      public\r
+        * @param       string  the path to the cache directory\r
+        * @return      bool\r
+        */             \r
+       function check_path($path = '')\r
+       {\r
+               if ($path == '')\r
+               {\r
+                       if ($this->db->cachedir == '')\r
+                       {\r
+                               return $this->db->cache_off();\r
+                       }\r
+               \r
+                       $path = $this->db->cachedir;\r
+               }\r
+       \r
+               // Add a trailing slash to the path if needed\r
+               $path = preg_replace("/(.+?)\/*$/", "\\1/",  $path);\r
+\r
+               if ( ! is_dir($path) OR ! is_really_writable($path))\r
+               {\r
+                       // If the path is wrong we'll turn off caching\r
+                       return $this->db->cache_off();\r
+               }\r
+               \r
+               $this->db->cachedir = $path;\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Retrieve a cached query\r
+        *\r
+        * The URI being requested will become the name of the cache sub-folder.\r
+        * An MD5 hash of the SQL statement will become the cache file name\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function read($sql)\r
+       {\r
+               if ( ! $this->check_path())\r
+               {\r
+                       return $this->db->cache_off();\r
+               }\r
+\r
+               $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);\r
+               \r
+               $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);\r
+       \r
+               $filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);            \r
+               \r
+               if (FALSE === ($cachedata = read_file($filepath)))\r
+               {       \r
+                       return FALSE;\r
+               }\r
+               \r
+               return unserialize($cachedata);                 \r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Write a query to a cache file\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */\r
+       function write($sql, $object)\r
+       {\r
+               if ( ! $this->check_path())\r
+               {\r
+                       return $this->db->cache_off();\r
+               }\r
+\r
+               $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);\r
+               \r
+               $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);\r
+       \r
+               $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';\r
+               \r
+               $filename = md5($sql);\r
+       \r
+               if ( ! @is_dir($dir_path))\r
+               {\r
+                       if ( ! @mkdir($dir_path, DIR_WRITE_MODE))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       @chmod($dir_path, DIR_WRITE_MODE);                      \r
+               }\r
+               \r
+               if (write_file($dir_path.$filename, serialize($object)) === FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               @chmod($dir_path.$filename, DIR_WRITE_MODE);\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete cache files within a particular directory\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */\r
+       function delete($segment_one = '', $segment_two = '')\r
+       {       \r
+               if ($segment_one == '')\r
+               {\r
+                       $segment_one  = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);\r
+               }\r
+               \r
+               if ($segment_two == '')\r
+               {\r
+                       $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);\r
+               }\r
+               \r
+               $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';\r
+               \r
+               delete_files($dir_path, TRUE);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete all existing cache files\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */\r
+       function delete_all()\r
+       {\r
+               delete_files($this->db->cachedir, TRUE);\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file DB_cache.php */\r
+/* Location: ./system/database/DB_cache.php */
\ No newline at end of file
diff --git a/database/DB_driver.php b/database/DB_driver.php
new file mode 100644 (file)
index 0000000..07c19c5
--- /dev/null
@@ -0,0 +1,1319 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Database Driver Class\r
+ *\r
+ * This is the platform-independent base DB implementation class.\r
+ * This class will not be called directly. Rather, the adapter\r
+ * class for the specific database will extend and instantiate it.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_driver {\r
+\r
+       var $username;\r
+       var $password;\r
+       var $hostname;\r
+       var $database;\r
+       var $dbdriver           = 'mysql';\r
+       var $dbprefix           = '';\r
+       var $char_set           = 'utf8';\r
+       var $dbcollat           = 'utf8_general_ci';\r
+       var $autoinit           = TRUE; // Whether to automatically initialize the DB\r
+       var $swap_pre           = '';\r
+       var $port                       = '';\r
+       var $pconnect           = FALSE;\r
+       var $conn_id            = FALSE;\r
+       var $result_id          = FALSE;\r
+       var $db_debug           = FALSE;\r
+       var $benchmark          = 0;\r
+       var $query_count        = 0;\r
+       var $bind_marker        = '?';\r
+       var $save_queries       = TRUE;\r
+       var $queries            = array();\r
+       var $query_times        = array();\r
+       var $data_cache         = array();\r
+       var $trans_enabled      = TRUE;\r
+       var $trans_strict       = TRUE;\r
+       var $_trans_depth       = 0;\r
+       var $_trans_status      = TRUE; // Used with transactions to determine if a rollback should occur\r
+       var $cache_on           = FALSE;\r
+       var $cachedir           = '';\r
+       var $cache_autodel      = FALSE;\r
+       var $CACHE; // The cache class object\r
+\r
+       // Private variables\r
+       var $_protect_identifiers       = TRUE;\r
+       var $_reserved_identifiers      = array('*'); // Identifiers that should NOT be escaped\r
+\r
+       // These are use with Oracle\r
+       var $stmt_id;\r
+       var $curs_id;\r
+       var $limit_used;\r
+\r
+\r
+       \r
+       /**\r
+        * Constructor.  Accepts one parameter containing the database\r
+        * connection settings.\r
+        *\r
+        * @param array\r
+        */     \r
+       function CI_DB_driver($params)\r
+       {\r
+               if (is_array($params))\r
+               {\r
+                       foreach ($params as $key => $val)\r
+                       {\r
+                               $this->$key = $val;\r
+                       }\r
+               }\r
+\r
+               log_message('debug', 'Database Driver Class Initialized');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize Database Settings\r
+        *\r
+        * @access      private Called by the constructor\r
+        * @param       mixed\r
+        * @return      void\r
+        */     \r
+       function initialize()\r
+       {\r
+               // If an existing connection resource is available\r
+               // there is no need to connect and select the database\r
+               if (is_resource($this->conn_id) OR is_object($this->conn_id))\r
+               {\r
+                       return TRUE;\r
+               }\r
+       \r
+               // ----------------------------------------------------------------\r
+               \r
+               // Connect to the database and set the connection ID\r
+               $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();\r
+\r
+               // No connection resource?  Throw an error\r
+               if ( ! $this->conn_id)\r
+               {\r
+                       log_message('error', 'Unable to connect to the database');\r
+                       \r
+                       if ($this->db_debug)\r
+                       {\r
+                               $this->display_error('db_unable_to_connect');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+\r
+               // ----------------------------------------------------------------\r
+\r
+               // Select the DB... assuming a database name is specified in the config file\r
+               if ($this->database != '')\r
+               {\r
+                       if ( ! $this->db_select())\r
+                       {\r
+                               log_message('error', 'Unable to select database: '.$this->database);\r
+                       \r
+                               if ($this->db_debug)\r
+                               {\r
+                                       $this->display_error('db_unable_to_select', $this->database);\r
+                               }\r
+                               return FALSE;                   \r
+                       }\r
+                       else\r
+                       {\r
+                               // We've selected the DB. Now we set the character set\r
+                               if ( ! $this->db_set_charset($this->char_set, $this->dbcollat))\r
+                               {\r
+                                       return FALSE;\r
+                               }\r
+               \r
+                               return TRUE;\r
+                       }\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               if ( ! $this->_db_set_charset($this->char_set, $this->dbcollat))\r
+               {\r
+                       log_message('error', 'Unable to set database connection charset: '.$this->char_set);\r
+               \r
+                       if ($this->db_debug)\r
+                       {\r
+                               $this->display_error('db_unable_to_set_charset', $this->char_set);\r
+                       }\r
+                       \r
+                       return FALSE;\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The name of the platform in use (mysql, mssql, etc...)\r
+        *\r
+        * @access      public\r
+        * @return      string          \r
+        */     \r
+       function platform()\r
+       {\r
+               return $this->dbdriver;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Database Version Number.  Returns a string containing the\r
+        * version of the database being used\r
+        *\r
+        * @access      public\r
+        * @return      string  \r
+        */     \r
+       function version()\r
+       {\r
+               if (FALSE === ($sql = $this->_version()))\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_unsupported_function');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               \r
+               if ($this->dbdriver == 'oci8')\r
+               {\r
+                       return $sql;\r
+               }\r
+       \r
+               $query = $this->query($sql);\r
+               return $query->row('ver');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * Accepts an SQL string as input and returns a result object upon\r
+        * successful execution of a "read" type query.  Returns boolean TRUE\r
+        * upon successful execution of a "write" type query. Returns boolean\r
+        * FALSE upon failure, and if the $db_debug variable is set to TRUE\r
+        * will raise an error.\r
+        *\r
+        * @access      public\r
+        * @param       string  An SQL query string\r
+        * @param       array   An array of binding data\r
+        * @return      mixed           \r
+        */     \r
+       function query($sql, $binds = FALSE, $return_object = TRUE)\r
+       {\r
+               if ($sql == '')\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               log_message('error', 'Invalid query: '.$sql);\r
+                               return $this->display_error('db_invalid_query');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+\r
+               // Verify table prefix and replace if necessary\r
+               if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )\r
+               {                       \r
+                       $sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);\r
+               }\r
+               \r
+               // Is query caching enabled?  If the query is a "read type"\r
+               // we will load the caching class and return the previously\r
+               // cached query if it exists\r
+               if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))\r
+               {\r
+                       if ($this->_cache_init())\r
+                       {\r
+                               $this->load_rdriver();\r
+                               if (FALSE !== ($cache = $this->CACHE->read($sql)))\r
+                               {\r
+                                       return $cache;\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               // Compile binds if needed\r
+               if ($binds !== FALSE)\r
+               {\r
+                       $sql = $this->compile_binds($sql, $binds);\r
+               }\r
+\r
+               // Save the  query for debugging\r
+               if ($this->save_queries == TRUE)\r
+               {\r
+                       $this->queries[] = $sql;\r
+               }\r
+               \r
+               // Start the Query Timer\r
+               $time_start = list($sm, $ss) = explode(' ', microtime());\r
+       \r
+               // Run the Query\r
+               if (FALSE === ($this->result_id = $this->simple_query($sql)))\r
+               {\r
+                       if ($this->save_queries == TRUE)\r
+                       {\r
+                               $this->query_times[] = 0;\r
+                       }\r
+               \r
+                       // This will trigger a rollback if transactions are being used\r
+                       $this->_trans_status = FALSE;\r
+\r
+                       if ($this->db_debug)\r
+                       {\r
+                               // grab the error number and message now, as we might run some\r
+                               // additional queries before displaying the error\r
+                               $error_no = $this->_error_number();\r
+                               $error_msg = $this->_error_message();\r
+                               \r
+                               // We call this function in order to roll-back queries\r
+                               // if transactions are enabled.  If we don't call this here\r
+                               // the error message will trigger an exit, causing the \r
+                               // transactions to remain in limbo.\r
+                               $this->trans_complete();\r
+\r
+                               // Log and display errors\r
+                               log_message('error', 'Query error: '.$error_msg);\r
+                               return $this->display_error(\r
+                                                                               array(\r
+                                                                                               'Error Number: '.$error_no,\r
+                                                                                               $error_msg,\r
+                                                                                               $sql\r
+                                                                                       )\r
+                                                                               );\r
+                       }\r
+               \r
+                       return FALSE;\r
+               }\r
+               \r
+               // Stop and aggregate the query time results\r
+               $time_end = list($em, $es) = explode(' ', microtime());\r
+               $this->benchmark += ($em + $es) - ($sm + $ss);\r
+\r
+               if ($this->save_queries == TRUE)\r
+               {\r
+                       $this->query_times[] = ($em + $es) - ($sm + $ss);\r
+               }\r
+               \r
+               // Increment the query counter\r
+               $this->query_count++;\r
+               \r
+               // Was the query a "write" type?\r
+               // If so we'll simply return true\r
+               if ($this->is_write_type($sql) === TRUE)\r
+               {\r
+                       // If caching is enabled we'll auto-cleanup any\r
+                       // existing files related to this particular URI\r
+                       if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())\r
+                       {\r
+                               $this->CACHE->delete();\r
+                       }\r
+               \r
+                       return TRUE;\r
+               }\r
+               \r
+               // Return TRUE if we don't need to create a result object\r
+               // Currently only the Oracle driver uses this when stored\r
+               // procedures are used\r
+               if ($return_object !== TRUE)\r
+               {\r
+                       return TRUE;\r
+               }\r
+       \r
+               // Load and instantiate the result driver       \r
+               \r
+               $driver                 = $this->load_rdriver();\r
+               $RES                    = new $driver();\r
+               $RES->conn_id   = $this->conn_id;\r
+               $RES->result_id = $this->result_id;\r
+\r
+               if ($this->dbdriver == 'oci8')\r
+               {\r
+                       $RES->stmt_id           = $this->stmt_id;\r
+                       $RES->curs_id           = NULL;\r
+                       $RES->limit_used        = $this->limit_used;\r
+                       $this->stmt_id          = FALSE;\r
+               }\r
+               \r
+               // oci8 vars must be set before calling this\r
+               $RES->num_rows  = $RES->num_rows();\r
+                               \r
+               // Is query caching enabled?  If so, we'll serialize the\r
+               // result object and save it to a cache file.\r
+               if ($this->cache_on == TRUE AND $this->_cache_init())\r
+               {\r
+                       // We'll create a new instance of the result object\r
+                       // only without the platform specific driver since\r
+                       // we can't use it with cached data (the query result\r
+                       // resource ID won't be any good once we've cached the\r
+                       // result object, so we'll have to compile the data\r
+                       // and save it)\r
+                       $CR = new CI_DB_result();\r
+                       $CR->num_rows           = $RES->num_rows();\r
+                       $CR->result_object      = $RES->result_object();\r
+                       $CR->result_array       = $RES->result_array();\r
+                       \r
+                       // Reset these since cached objects can not utilize resource IDs.\r
+                       $CR->conn_id            = NULL;\r
+                       $CR->result_id          = NULL;\r
+\r
+                       $this->CACHE->write($sql, $CR);\r
+               }\r
+               \r
+               return $RES;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Load the result drivers\r
+        *\r
+        * @access      public\r
+        * @return      string  the name of the result class            \r
+        */             \r
+       function load_rdriver()\r
+       {\r
+               $driver = 'CI_DB_'.$this->dbdriver.'_result';\r
+\r
+               if ( ! class_exists($driver))\r
+               {\r
+                       include_once(BASEPATH.'database/DB_result'.EXT);\r
+                       include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);\r
+               }\r
+               \r
+               return $driver;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Simple Query\r
+        * This is a simplified version of the query() function.  Internally\r
+        * we only use it when running transaction commands since they do\r
+        * not require all the features of the main query() function.\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query\r
+        * @return      mixed           \r
+        */     \r
+       function simple_query($sql)\r
+       {\r
+               if ( ! $this->conn_id)\r
+               {\r
+                       $this->initialize();\r
+               }\r
+\r
+               return $this->_execute($sql);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Disable Transactions\r
+        * This permits transactions to be disabled at run-time.\r
+        *\r
+        * @access      public\r
+        * @return      void            \r
+        */     \r
+       function trans_off()\r
+       {\r
+               $this->trans_enabled = FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Enable/disable Transaction Strict Mode\r
+        * When strict mode is enabled, if you are running multiple groups of\r
+        * transactions, if one group fails all groups will be rolled back.\r
+        * If strict mode is disabled, each group is treated autonomously, meaning\r
+        * a failure of one group will not affect any others\r
+        *\r
+        * @access      public\r
+        * @return      void            \r
+        */     \r
+       function trans_strict($mode = TRUE)\r
+       {\r
+               $this->trans_strict = is_bool($mode) ? $mode : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Start Transaction\r
+        *\r
+        * @access      public\r
+        * @return      void            \r
+        */     \r
+       function trans_start($test_mode = FALSE)\r
+       {       \r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       $this->_trans_depth += 1;\r
+                       return;\r
+               }\r
+               \r
+               $this->trans_begin($test_mode);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Complete Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_complete()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 1)\r
+               {\r
+                       $this->_trans_depth -= 1;\r
+                       return TRUE;\r
+               }\r
+       \r
+               // The query() function will set this flag to FALSE in the event that a query failed\r
+               if ($this->_trans_status === FALSE)\r
+               {\r
+                       $this->trans_rollback();\r
+                       \r
+                       // If we are NOT running in strict mode, we will reset\r
+                       // the _trans_status flag so that subsequent groups of transactions\r
+                       // will be permitted.\r
+                       if ($this->trans_strict === FALSE)\r
+                       {\r
+                               $this->_trans_status = TRUE;\r
+                       }\r
+\r
+                       log_message('debug', 'DB Transaction Failure');\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->trans_commit();\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Lets you retrieve the transaction flag to determine if it has failed\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_status()\r
+       {\r
+               return $this->_trans_status;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Compile Bindings\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql statement\r
+        * @param       array   an array of bind data\r
+        * @return      string          \r
+        */     \r
+       function compile_binds($sql, $binds)\r
+       {\r
+               if (strpos($sql, $this->bind_marker) === FALSE)\r
+               {\r
+                       return $sql;\r
+               }\r
+               \r
+               if ( ! is_array($binds))\r
+               {\r
+                       $binds = array($binds);\r
+               }\r
+               \r
+               // Get the sql segments around the bind markers\r
+               $segments = explode($this->bind_marker, $sql);\r
+\r
+               // The count of bind should be 1 less then the count of segments\r
+               // If there are more bind arguments trim it down\r
+               if (count($binds) >= count($segments)) {\r
+                       $binds = array_slice($binds, 0, count($segments)-1);\r
+               }\r
+\r
+               // Construct the binded query\r
+               $result = $segments[0];\r
+               $i = 0;\r
+               foreach ($binds as $bind)\r
+               {\r
+                       $result .= $this->escape($bind);\r
+                       $result .= $segments[++$i];\r
+               }\r
+\r
+               return $result;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determines if a query is a "write" type.\r
+        *\r
+        * @access      public\r
+        * @param       string  An SQL query string\r
+        * @return      boolean         \r
+        */     \r
+       function is_write_type($sql)\r
+       {\r
+               if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Calculate the aggregate query elapsed time\r
+        *\r
+        * @access      public\r
+        * @param       integer The number of decimal places\r
+        * @return      integer         \r
+        */     \r
+       function elapsed_time($decimals = 6)\r
+       {\r
+               return number_format($this->benchmark, $decimals);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the total number of queries\r
+        *\r
+        * @access      public\r
+        * @return      integer         \r
+        */     \r
+       function total_queries()\r
+       {\r
+               return $this->query_count;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the last query that was executed\r
+        *\r
+        * @access      public\r
+        * @return      void            \r
+        */     \r
+       function last_query()\r
+       {\r
+               return end($this->queries);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Smart" Escape String\r
+        *\r
+        * Escapes data based on type\r
+        * Sets boolean and null types\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      integer         \r
+        */     \r
+       function escape($str)\r
+       {       \r
+               switch (gettype($str))\r
+               {\r
+                       case 'string'   :       $str = "'".$this->escape_str($str)."'";\r
+                               break;\r
+                       case 'boolean'  :       $str = ($str === FALSE) ? 0 : 1;\r
+                               break;\r
+                       default                 :       $str = ($str === NULL) ? 'NULL' : $str;\r
+                               break;\r
+               }               \r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Primary\r
+        *\r
+        * Retrieves the primary key.  It assumes that the row in the first\r
+        * position is the primary key\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string          \r
+        */     \r
+       function primary($table = '')\r
+       {       \r
+               $fields = $this->list_fields($table);\r
+               \r
+               if ( ! is_array($fields))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return current($fields);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns an array of table names\r
+        *\r
+        * @access      public\r
+        * @return      array           \r
+        */     \r
+       function list_tables($constrain_by_prefix = FALSE)\r
+       {\r
+               // Is there a cached result?\r
+               if (isset($this->data_cache['table_names']))\r
+               {\r
+                       return $this->data_cache['table_names'];\r
+               }\r
+       \r
+               if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_unsupported_function');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+\r
+               $retval = array();\r
+               $query = $this->query($sql);\r
+               \r
+               if ($query->num_rows() > 0)\r
+               {\r
+                       foreach($query->result_array() as $row)\r
+                       {\r
+                               if (isset($row['TABLE_NAME']))\r
+                               {\r
+                                       $retval[] = $row['TABLE_NAME'];\r
+                               }\r
+                               else\r
+                               {\r
+                                       $retval[] = array_shift($row);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               $this->data_cache['table_names'] = $retval;\r
+               return $this->data_cache['table_names'];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determine if a particular table exists\r
+        * @access      public\r
+        * @return      boolean\r
+        */\r
+       function table_exists($table_name)\r
+       {       \r
+               return ( ! in_array($this->_protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables())) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch MySQL Field Names\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      array           \r
+        */\r
+       function list_fields($table = '')\r
+       {\r
+               // Is there a cached result?\r
+               if (isset($this->data_cache['field_names'][$table]))\r
+               {\r
+                       return $this->data_cache['field_names'][$table];\r
+               }\r
+       \r
+               if ($table == '')\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_field_param_missing');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               \r
+               if (FALSE === ($sql = $this->_list_columns($this->_protect_identifiers($table, TRUE, NULL, FALSE))))\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_unsupported_function');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               \r
+               $query = $this->query($sql);\r
+               \r
+               $retval = array();\r
+               foreach($query->result_array() as $row)\r
+               {\r
+                       if (isset($row['COLUMN_NAME']))\r
+                       {\r
+                               $retval[] = $row['COLUMN_NAME'];\r
+                       }\r
+                       else\r
+                       {\r
+                               $retval[] = current($row);\r
+                       }               \r
+               }\r
+               \r
+               $this->data_cache['field_names'][$table] = $retval;\r
+               return $this->data_cache['field_names'][$table];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determine if a particular field exists\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      boolean\r
+        */\r
+       function field_exists($field_name, $table_name)\r
+       {       \r
+               return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns an object with field data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object          \r
+        */     \r
+       function field_data($table = '')\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_field_param_missing');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               \r
+               $query = $this->query($this->_field_data($this->_protect_identifiers($table, TRUE, NULL, FALSE)));\r
+\r
+               return $query->field_data();\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate an insert string\r
+        *\r
+        * @access      public\r
+        * @param       string  the table upon which the query will be performed\r
+        * @param       array   an associative array data of key/values\r
+        * @return      string          \r
+        */     \r
+       function insert_string($table, $data)\r
+       {\r
+               $fields = array();\r
+               $values = array();\r
+               \r
+               foreach($data as $key => $val)\r
+               {\r
+                       $fields[] = $this->_escape_identifiers($key);\r
+                       $values[] = $this->escape($val);\r
+               }\r
+                               \r
+               return $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values);\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate an update string\r
+        *\r
+        * @access      public\r
+        * @param       string  the table upon which the query will be performed\r
+        * @param       array   an associative array data of key/values\r
+        * @param       mixed   the "where" statement\r
+        * @return      string          \r
+        */     \r
+       function update_string($table, $data, $where)\r
+       {\r
+               if ($where == '')\r
+               {\r
+                       return false;\r
+               }\r
+                                       \r
+               $fields = array();\r
+               foreach($data as $key => $val)\r
+               {\r
+                       $fields[$this->_protect_identifiers($key)] = $this->escape($val);\r
+               }\r
+\r
+               if ( ! is_array($where))\r
+               {\r
+                       $dest = array($where);\r
+               }\r
+               else\r
+               {\r
+                       $dest = array();\r
+                       foreach ($where as $key => $val)\r
+                       {\r
+                               $prefix = (count($dest) == 0) ? '' : ' AND ';\r
+       \r
+                               if ($val !== '')\r
+                               {\r
+                                       if ( ! $this->_has_operator($key))\r
+                                       {\r
+                                               $key .= ' =';\r
+                                       }\r
+                               \r
+                                       $val = ' '.$this->escape($val);\r
+                               }\r
+                                                       \r
+                               $dest[] = $prefix.$key.$val;\r
+                       }\r
+               }               \r
+\r
+               return $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $dest);\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Tests whether the string has an SQL operator\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function _has_operator($str)\r
+       {\r
+               $str = trim($str);\r
+               if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Enables a native PHP function to be run, using a platform agnostic wrapper.\r
+        *\r
+        * @access      public\r
+        * @param       string  the function name\r
+        * @param       mixed   any parameters needed by the function\r
+        * @return      mixed           \r
+        */     \r
+       function call_function($function)\r
+       {\r
+               $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';\r
+       \r
+               if (FALSE === strpos($driver, $function))\r
+               {\r
+                       $function = $driver.$function;\r
+               }\r
+               \r
+               if ( ! function_exists($function))\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               return $this->display_error('db_unsupported_function');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               else\r
+               {\r
+                       $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;\r
+\r
+                       return call_user_func_array($function, $args);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Cache Directory Path\r
+        *\r
+        * @access      public\r
+        * @param       string  the path to the cache directory\r
+        * @return      void\r
+        */             \r
+       function cache_set_path($path = '')\r
+       {\r
+               $this->cachedir = $path;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Enable Query Caching\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function cache_on()\r
+       {\r
+               $this->cache_on = TRUE;\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Disable Query Caching\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function cache_off()\r
+       {\r
+               $this->cache_on = FALSE;\r
+               return FALSE;\r
+       }\r
+       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete the cache files associated with a particular URI\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function cache_delete($segment_one = '', $segment_two = '')\r
+       {\r
+               if ( ! $this->_cache_init())\r
+               {\r
+                       return FALSE;\r
+               }\r
+               return $this->CACHE->delete($segment_one, $segment_two);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete All cache files\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function cache_delete_all()\r
+       {\r
+               if ( ! $this->_cache_init())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return $this->CACHE->delete_all();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize the Cache Class\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _cache_init()\r
+       {\r
+               if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))\r
+               {\r
+                       return TRUE;\r
+               }\r
+       \r
+               if ( ! @include(BASEPATH.'database/DB_cache'.EXT))\r
+               {\r
+                       return $this->cache_off();\r
+               }\r
+               \r
+               $this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @return      void            \r
+        */     \r
+       function close()\r
+       {\r
+               if (is_resource($this->conn_id) OR is_object($this->conn_id))\r
+               {\r
+                       $this->_close($this->conn_id);\r
+               }\r
+               $this->conn_id = FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Display an error message\r
+        *\r
+        * @access      public\r
+        * @param       string  the error message\r
+        * @param       string  any "swap" values\r
+        * @param       boolean whether to localize the message\r
+        * @return      string  sends the application/error_db.php template             \r
+        */     \r
+       function display_error($error = '', $swap = '', $native = FALSE)\r
+       {\r
+               $LANG =& load_class('Language');\r
+               $LANG->load('db');\r
+\r
+               $heading = $LANG->line('db_error_heading');\r
+\r
+               if ($native == TRUE)\r
+               {\r
+                       $message = $error;\r
+               }\r
+               else\r
+               {\r
+                       $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;\r
+               }\r
+               \r
+               $error =& load_class('Exceptions');\r
+               echo $error->show_error($heading, $message, 'error_db');\r
+               exit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Protect Identifiers\r
+        *\r
+        * This function adds backticks if appropriate based on db type\r
+        *\r
+        * @access      private\r
+        * @param       mixed   the item to escape\r
+        * @return      mixed   the item with backticks\r
+        */\r
+       function protect_identifiers($item, $prefix_single = FALSE)\r
+       {\r
+               return $this->_protect_identifiers($item, $prefix_single);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Protect Identifiers\r
+        *\r
+        * This function is used extensively by the Active Record class, and by\r
+        * a couple functions in this class. \r
+        * It takes a column or table name (optionally with an alias) and inserts\r
+        * the table prefix onto it.  Some logic is necessary in order to deal with\r
+        * column names that include the path.  Consider a query like this:\r
+        *\r
+        * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table\r
+        *\r
+        * Or a query with aliasing:\r
+        *\r
+        * SELECT m.member_id, m.member_name FROM members AS m\r
+        *\r
+        * Since the column name can include up to four segments (host, DB, table, column)\r
+        * or also have an alias prefix, we need to do a bit of work to figure this out and\r
+        * insert the table prefix (if it exists) in the proper position, and escape only\r
+        * the correct identifiers.\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       bool\r
+        * @param       mixed\r
+        * @param       bool\r
+        * @return      string\r
+        */     \r
+       function _protect_identifiers($item, $prefix_single = FALSE, $protect_identifiers = NULL, $field_exists = TRUE)\r
+       {\r
+               if ( ! is_bool($protect_identifiers))\r
+               {\r
+                       $protect_identifiers = $this->_protect_identifiers;\r
+               }\r
+               \r
+               // Convert tabs or multiple spaces into single spaces\r
+               $item = preg_replace('/[\t| ]+/', ' ', $item);\r
+       \r
+               // If the item has an alias declaration we remove it and set it aside.\r
+               // Basically we remove everything to the right of the first space\r
+               $alias = '';\r
+               if (strpos($item, ' ') !== FALSE)\r
+               {               \r
+                       $alias = strstr($item, " ");\r
+                       $item = substr($item, 0, - strlen($alias));\r
+               }\r
+\r
+               // Break the string apart if it contains periods, then insert the table prefix\r
+               // in the correct location, assuming the period doesn't indicate that we're dealing\r
+               // with an alias. While we're at it, we will escape the components\r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $parts  = explode('.', $item);\r
+                       \r
+                       // Does the first segment of the exploded item match\r
+                       // one of the aliases previously identified?  If so,\r
+                       // we have nothing more to do other then escape the item\r
+                       if (in_array($parts[0], $this->ar_aliased_tables))\r
+                       {                               \r
+                               if ($protect_identifiers === TRUE)\r
+                               {\r
+                                       foreach ($parts as $key => $val)\r
+                                       {\r
+                                               if ( ! in_array($val, $this->_reserved_identifiers))\r
+                                               {\r
+                                                       $parts[$key] = $this->_escape_identifiers($val);\r
+                                               }\r
+                                       }\r
+                               \r
+                                       $item = implode('.', $parts);\r
+                               }                       \r
+                               return $item.$alias;\r
+                       }\r
+                       \r
+                       // Is there a table prefix defined in the config file?  If not, no need to do anything\r
+                       if ($this->dbprefix != '')\r
+                       {\r
+                               // We now add the table prefix based on some logic.\r
+                               // Do we have 4 segments (hostname.database.table.column)?\r
+                               // If so, we add the table prefix to the column name in the 3rd segment.\r
+                               if (isset($parts[3]))\r
+                               {\r
+                                       $i = 2;\r
+                               }\r
+                               // Do we have 3 segments (database.table.column)?\r
+                               // If so, we add the table prefix to the column name in 2nd position\r
+                               elseif (isset($parts[2]))\r
+                               {\r
+                                       $i = 1;\r
+                               }\r
+                               // Do we have 2 segments (table.column)?\r
+                               // If so, we add the table prefix to the column name in 1st segment\r
+                               else\r
+                               {\r
+                                       $i = 0;\r
+                               }\r
+                               \r
+                               // This flag is set when the supplied $item does not contain a field name.\r
+                               // This can happen when this function is being called from a JOIN.\r
+                               if ($field_exists == FALSE)\r
+                               {\r
+                                       $i++;\r
+                               }\r
+                               \r
+                               // We only add the table prefix if it does not already exist\r
+                               if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix)\r
+                               {\r
+                                       $parts[$i] = $this->dbprefix.$parts[$i];\r
+                               }\r
+                               \r
+                               // Put the parts back together\r
+                               $item = implode('.', $parts);\r
+                       }\r
+                       \r
+                       if ($protect_identifiers === TRUE)\r
+                       {\r
+                               $item = $this->_escape_identifiers($item);\r
+                       }\r
+                       \r
+                       return $item.$alias;\r
+               }\r
+\r
+               // This is basically a bug fix for queries that use MAX, MIN, etc.\r
+               // If a parenthesis is found we know that we do not need to \r
+               // escape the data or add a prefix.  There's probably a more graceful\r
+               // way to deal with this, but I'm not thinking of it -- Rick\r
+               if (strpos($item, '(') !== FALSE)\r
+               {\r
+                       return $item.$alias;\r
+               }\r
+               \r
+               // Is there a table prefix?  If not, no need to insert it\r
+               if ($this->dbprefix != '')\r
+               {\r
+                       // Do we prefix an item with no segments?\r
+                       if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix)\r
+                       {\r
+                               $item = $this->dbprefix.$item;\r
+                       }               \r
+               }\r
+               \r
+               if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers))\r
+               {\r
+                       $item = $this->_escape_identifiers($item);\r
+               }\r
+               \r
+               return $item.$alias;\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+/* End of file DB_driver.php */\r
+/* Location: ./system/database/DB_driver.php */
\ No newline at end of file
diff --git a/database/DB_forge.php b/database/DB_forge.php
new file mode 100644 (file)
index 0000000..20f0a30
--- /dev/null
@@ -0,0 +1,355 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * Code Igniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Database Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_forge {\r
+\r
+       var $fields                     = array();\r
+       var $keys                       = array();\r
+       var $primary_keys       = array();\r
+       var $db_char_set        =       '';\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Grabs the CI super object instance so we can access it.\r
+        *\r
+        */     \r
+       function CI_DB_forge()\r
+       {\r
+               // Assign the main database object to $this->db\r
+               $CI =& get_instance();\r
+               $this->db =& $CI->db;\r
+               log_message('debug', "Database Forge Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function create_database($db_name)\r
+       {\r
+               $sql = $this->_create_database($db_name);\r
+               \r
+               if (is_bool($sql))\r
+               {\r
+                       return $sql;\r
+               }\r
+       \r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function drop_database($db_name)\r
+       {\r
+               $sql = $this->_drop_database($db_name);\r
+               \r
+               if (is_bool($sql))\r
+               {\r
+                       return $sql;\r
+               }\r
+       \r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Key\r
+        *\r
+        * @access      public\r
+        * @param       string  key\r
+        * @param       string  type\r
+        * @return      void\r
+        */\r
+       function add_key($key = '', $primary = FALSE)\r
+       {\r
+               if (is_array($key))\r
+               {\r
+                       foreach($key as $one)\r
+                       {\r
+                               $this->add_key($one, $primary);\r
+                       }\r
+                       \r
+                       return;\r
+               }\r
+       \r
+               if ($key == '')\r
+               {\r
+                       show_error('Key information is required for that operation.');\r
+               }\r
+               \r
+               if ($primary === TRUE)\r
+               {\r
+                       $this->primary_keys[] = $key;\r
+               }\r
+               else\r
+               {\r
+                       $this->keys[] = $key;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Field\r
+        *\r
+        * @access      public\r
+        * @param       string  collation\r
+        * @return      void\r
+        */\r
+       function add_field($field = '')\r
+       {\r
+               if ($field == '')\r
+               {\r
+                       show_error('Field information is required.');\r
+               }\r
+               \r
+               if (is_string($field))\r
+               {\r
+                       if ($field == 'id')\r
+                       {\r
+                               $this->add_field(array(\r
+                                                                               'id' => array(\r
+                                                                                                       'type' => 'INT',\r
+                                                                                                       'constraint' => 9,\r
+                                                                                                       'auto_increment' => TRUE\r
+                                                                                                       )\r
+                                                               ));\r
+                               $this->add_key('id', TRUE);\r
+                       }\r
+                       else\r
+                       {\r
+                               if (strpos($field, ' ') === FALSE)\r
+                               {\r
+                                       show_error('Field information is required for that operation.');\r
+                               }\r
+                               \r
+                               $this->fields[] = $field;\r
+                       }\r
+               }\r
+               \r
+               if (is_array($field))\r
+               {\r
+                       $this->fields = array_merge($this->fields, $field);\r
+               }\r
+               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      bool\r
+        */\r
+       function create_table($table = '', $if_not_exists = FALSE)\r
+       {       \r
+               if ($table == '')\r
+               {\r
+                       show_error('A table name is required for that operation.');\r
+               }\r
+                       \r
+               if (count($this->fields) == 0)\r
+               {       \r
+                       show_error('Field information is required.');\r
+               }\r
+\r
+               $sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);\r
+               \r
+               $this->_reset();\r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      bool\r
+        */\r
+       function drop_table($table_name)\r
+       {\r
+               $sql = $this->_drop_table($this->db->dbprefix.$table_name);\r
+               \r
+               if (is_bool($sql))\r
+               {\r
+                       return $sql;\r
+               }\r
+       \r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename Table\r
+        *\r
+        * @access      public\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      bool\r
+        */\r
+       function rename_table($table_name, $new_table_name)\r
+       {\r
+               if ($table_name == '' OR $new_table_name == '')\r
+               {\r
+                       show_error('A table name is required for that operation.');\r
+               }\r
+                       \r
+               $sql = $this->_rename_table($table_name, $new_table_name);\r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Column Add\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       string  the column name\r
+        * @param       string  the column definition\r
+        * @return      bool\r
+        */\r
+       function add_column($table = '', $field = array(), $after_field = '')\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       show_error('A table name is required for that operation.');\r
+               }\r
+\r
+               // add field info into field array, but we can only do one at a time\r
+               // so only grab the first field in the event there are more then one\r
+               $this->add_field(array_slice($field, 0, 1));\r
+\r
+               if (count($this->fields) == 0)\r
+               {       \r
+                       show_error('Field information is required.');\r
+               }\r
+\r
+               $sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);\r
+\r
+               $this->_reset();\r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Column Drop\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       string  the column name\r
+        * @return      bool\r
+        */\r
+       function drop_column($table = '', $column_name = '')\r
+       {\r
+       \r
+               if ($table == '')\r
+               {\r
+                       show_error('A table name is required for that operation.');\r
+               }\r
+\r
+               if ($column_name == '')\r
+               {\r
+                       show_error('A column name is required for that operation.');\r
+               }\r
+\r
+               $sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);\r
+       \r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Column Modify\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       string  the column name\r
+        * @param       string  the column definition\r
+        * @return      bool\r
+        */\r
+       function modify_column($table = '', $field = array())\r
+       {\r
+               if ($table == '')\r
+               {\r
+                       show_error('A table name is required for that operation.');\r
+               }\r
+\r
+               // add field info into field array, but we can only do one at a time\r
+               // so only grab the first field in the event there are more then one\r
+               $this->add_field(array_slice($field, 0, 1));\r
+\r
+               if (count($this->fields) == 0)\r
+               {       \r
+                       show_error('Field information is required.');\r
+               }\r
+\r
+               $sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);\r
+\r
+               $this->_reset();\r
+               return $this->db->query($sql);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Reset\r
+        *\r
+        * Resets table creation vars\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _reset()\r
+       {\r
+               $this->fields           = array();\r
+               $this->keys                     = array();\r
+               $this->primary_keys     = array();\r
+       }\r
+\r
+}\r
+\r
+/* End of file DB_forge.php */\r
+/* Location: ./system/database/DB_forge.php */
\ No newline at end of file
diff --git a/database/DB_result.php b/database/DB_result.php
new file mode 100644 (file)
index 0000000..8f55f67
--- /dev/null
@@ -0,0 +1,342 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Database Result Class\r
+ *\r
+ * This is the platform-independent result class.\r
+ * This class will not be called directly. Rather, the adapter\r
+ * class for the specific database will extend and instantiate it.\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_result {\r
+\r
+       var $conn_id            = NULL;\r
+       var $result_id          = NULL;\r
+       var $result_array       = array();\r
+       var $result_object      = array();\r
+       var $current_row        = 0;\r
+       var $num_rows           = 0;\r
+       var $row_data           = NULL;\r
+\r
+\r
+       /**\r
+        * Query result.  Acts as a wrapper function for the following functions.\r
+        *\r
+        * @access      public\r
+        * @param       string  can be "object" or "array"\r
+        * @return      mixed   either a result object or array \r
+        */     \r
+       function result($type = 'object')\r
+       {       \r
+               return ($type == 'object') ? $this->result_object() : $this->result_array();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Query result.  "object" version.\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function result_object()\r
+       {\r
+               if (count($this->result_object) > 0)\r
+               {\r
+                       return $this->result_object;\r
+               }\r
+               \r
+               // In the event that query caching is on the result_id variable \r
+               // will return FALSE since there isn't a valid SQL resource so \r
+               // we'll simply return an empty array.\r
+               if ($this->result_id === FALSE OR $this->num_rows() == 0)\r
+               {\r
+                       return array();\r
+               }\r
+\r
+               $this->_data_seek(0);\r
+               while ($row = $this->_fetch_object())\r
+               {\r
+                       $this->result_object[] = $row;\r
+               }\r
+               \r
+               return $this->result_object;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Query result.  "array" version.\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */     \r
+       function result_array()\r
+       {\r
+               if (count($this->result_array) > 0)\r
+               {\r
+                       return $this->result_array;\r
+               }\r
+\r
+               // In the event that query caching is on the result_id variable \r
+               // will return FALSE since there isn't a valid SQL resource so \r
+               // we'll simply return an empty array.\r
+               if ($this->result_id === FALSE OR $this->num_rows() == 0)\r
+               {\r
+                       return array();\r
+               }\r
+\r
+               $this->_data_seek(0);\r
+               while ($row = $this->_fetch_assoc())\r
+               {\r
+                       $this->result_array[] = $row;\r
+               }\r
+               \r
+               return $this->result_array;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Query result.  Acts as a wrapper function for the following functions.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string  can be "object" or "array"\r
+        * @return      mixed   either a result object or array \r
+        */     \r
+       function row($n = 0, $type = 'object')\r
+       {\r
+               if ( ! is_numeric($n))\r
+               {\r
+                       // We cache the row data for subsequent uses\r
+                       if ( ! is_array($this->row_data))\r
+                       {\r
+                               $this->row_data = $this->row_array(0);\r
+                       }\r
+               \r
+                       // array_key_exists() instead of isset() to allow for MySQL NULL values\r
+                       if (array_key_exists($n, $this->row_data))\r
+                       {\r
+                               return $this->row_data[$n];\r
+                       }\r
+                       // reset the $n variable if the result was not achieved                 \r
+                       $n = 0;\r
+               }\r
+               \r
+               return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Assigns an item into a particular column slot\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function set_row($key, $value = NULL)\r
+       {\r
+               // We cache the row data for subsequent uses\r
+               if ( ! is_array($this->row_data))\r
+               {\r
+                       $this->row_data = $this->row_array(0);\r
+               }\r
+       \r
+               if (is_array($key))\r
+               {\r
+                       foreach ($key as $k => $v)\r
+                       {\r
+                               $this->row_data[$k] = $v;\r
+                       }\r
+                       \r
+                       return;\r
+               }\r
+       \r
+               if ($key != '' AND ! is_null($value))\r
+               {\r
+                       $this->row_data[$key] = $value;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns a single result row - object version\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function row_object($n = 0)\r
+       {\r
+               $result = $this->result_object();\r
+               \r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+\r
+               if ($n != $this->current_row AND isset($result[$n]))\r
+               {\r
+                       $this->current_row = $n;\r
+               }\r
+\r
+               return $result[$this->current_row];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns a single result row - array version\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */     \r
+       function row_array($n = 0)\r
+       {\r
+               $result = $this->result_array();\r
+\r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+                       \r
+               if ($n != $this->current_row AND isset($result[$n]))\r
+               {\r
+                       $this->current_row = $n;\r
+               }\r
+               \r
+               return $result[$this->current_row];\r
+       }\r
+\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the "first" row\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function first_row($type = 'object')\r
+       {\r
+               $result = $this->result($type);\r
+\r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+               return $result[0];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the "last" row\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function last_row($type = 'object')\r
+       {\r
+               $result = $this->result($type);\r
+\r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+               return $result[count($result) -1];\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the "next" row\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function next_row($type = 'object')\r
+       {\r
+               $result = $this->result($type);\r
+\r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+\r
+               if (isset($result[$this->current_row + 1]))\r
+               {\r
+                       ++$this->current_row;\r
+               }\r
+                               \r
+               return $result[$this->current_row];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Returns the "previous" row\r
+        *\r
+        * @access      public\r
+        * @return      object\r
+        */     \r
+       function previous_row($type = 'object')\r
+       {\r
+               $result = $this->result($type);\r
+\r
+               if (count($result) == 0)\r
+               {\r
+                       return $result;\r
+               }\r
+\r
+               if (isset($result[$this->current_row - 1]))\r
+               {\r
+                       --$this->current_row;\r
+               }\r
+               return $result[$this->current_row];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The following functions are normally overloaded by the identically named\r
+        * methods in the platform-specific driver -- except when query caching\r
+        * is used.  When caching is enabled we do not load the other driver.\r
+        * These functions are primarily here to prevent undefined function errors\r
+        * when a cached result object is in use.  They are not otherwise fully\r
+        * operational due to the unavailability of the database resource IDs with\r
+        * cached results.\r
+        */\r
+       function num_rows() { return $this->num_rows; }\r
+       function num_fields() { return 0; }\r
+       function list_fields() { return array(); }\r
+       function field_data() { return array(); }       \r
+       function free_result() { return TRUE; }\r
+       function _data_seek() { return TRUE; }\r
+       function _fetch_assoc() { return array(); }     \r
+       function _fetch_object() { return array(); }\r
+       \r
+}\r
+// END DB_result class\r
+\r
+/* End of file DB_result.php */\r
+/* Location: ./system/database/DB_result.php */
\ No newline at end of file
diff --git a/database/DB_utility.php b/database/DB_utility.php
new file mode 100644 (file)
index 0000000..a37522d
--- /dev/null
@@ -0,0 +1,389 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * Code Igniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Database Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_utility extends CI_DB_forge {\r
+\r
+       var $db;\r
+       var $data_cache         = array();\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Grabs the CI super object instance so we can access it.\r
+        *\r
+        */     \r
+       function CI_DB_utility()\r
+       {\r
+               // Assign the main database object to $this->db\r
+               $CI =& get_instance();\r
+               $this->db =& $CI->db;\r
+               \r
+               log_message('debug', "Database Utility Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */\r
+       function list_databases()\r
+       {       \r
+               // Is there a cached result?\r
+               if (isset($this->data_cache['db_names']))\r
+               {\r
+                       return $this->data_cache['db_names'];\r
+               }\r
+       \r
+               $query = $this->db->query($this->_list_databases());\r
+               $dbs = array();\r
+               if ($query->num_rows() > 0)\r
+               {\r
+                       foreach ($query->result_array() as $row)\r
+                       {\r
+                               $dbs[] = current($row);\r
+                       }\r
+               }\r
+                       \r
+               $this->data_cache['db_names'] = $dbs;\r
+               return $this->data_cache['db_names'];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize Table\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      bool\r
+        */\r
+       function optimize_table($table_name)\r
+       {\r
+               $sql = $this->_optimize_table($table_name);\r
+               \r
+               if (is_bool($sql))\r
+               {\r
+                               show_error('db_must_use_set');\r
+               }\r
+       \r
+               $query = $this->db->query($sql);\r
+               $res = $query->result_array();\r
+               \r
+               // Note: Due to a bug in current() that affects some versions\r
+               // of PHP we can not pass function call directly into it\r
+               return current($res);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize Database\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function optimize_database()\r
+       {\r
+               $result = array();\r
+               foreach ($this->db->list_tables() as $table_name)\r
+               {\r
+                       $sql = $this->_optimize_table($table_name);\r
+                       \r
+                       if (is_bool($sql))\r
+                       {\r
+                               return $sql;\r
+                       }\r
+                       \r
+                       $query = $this->db->query($sql);\r
+                       \r
+                       // Build the result array...\r
+                       // Note: Due to a bug in current() that affects some versions\r
+                       // of PHP we can not pass function call directly into it\r
+                       $res = $query->result_array();\r
+                       $res = current($res);\r
+                       $key = str_replace($this->db->database.'.', '', current($res));\r
+                       $keys = array_keys($res);\r
+                       unset($res[$keys[0]]);\r
+                       \r
+                       $result[$key] = $res;\r
+               }\r
+\r
+               return $result;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair Table\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      bool\r
+        */\r
+       function repair_table($table_name)\r
+       {\r
+               $sql = $this->_repair_table($table_name);\r
+               \r
+               if (is_bool($sql))\r
+               {\r
+                       return $sql;\r
+               }\r
+       \r
+               $query = $this->db->query($sql);\r
+               \r
+               // Note: Due to a bug in current() that affects some versions\r
+               // of PHP we can not pass function call directly into it\r
+               $res = $query->result_array();\r
+               return current($res);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate CSV from a query result object\r
+        *\r
+        * @access      public\r
+        * @param       object  The query result object\r
+        * @param       string  The delimiter - comma by default\r
+        * @param       string  The newline character - \n by default\r
+        * @param       string  The enclosure - double quote by default\r
+        * @return      string\r
+        */\r
+       function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')\r
+       {\r
+               if ( ! is_object($query) OR ! method_exists($query, 'field_names'))\r
+               {\r
+                       show_error('You must submit a valid result object');\r
+               }       \r
+       \r
+               $out = '';\r
+               \r
+               // First generate the headings from the table column names\r
+               foreach ($query->list_fields() as $name)\r
+               {\r
+                       $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;\r
+               }\r
+               \r
+               $out = rtrim($out);\r
+               $out .= $newline;\r
+               \r
+               // Next blast through the result array and build out the rows\r
+               foreach ($query->result_array() as $row)\r
+               {\r
+                       foreach ($row as $item)\r
+                       {\r
+                               $out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;                     \r
+                       }\r
+                       $out = rtrim($out);\r
+                       $out .= $newline;\r
+               }\r
+\r
+               return $out;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate XML data from a query result object\r
+        *\r
+        * @access      public\r
+        * @param       object  The query result object\r
+        * @param       array   Any preferences\r
+        * @return      string\r
+        */\r
+       function xml_from_result($query, $params = array())\r
+       {\r
+               if ( ! is_object($query) OR ! method_exists($query, 'field_names'))\r
+               {\r
+                       show_error('You must submit a valid result object');\r
+               }\r
+               \r
+               // Set our default values\r
+               foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)\r
+               {\r
+                       if ( ! isset($params[$key]))\r
+                       {\r
+                               $params[$key] = $val;\r
+                       }\r
+               }\r
+               \r
+               // Create variables for convenience\r
+               extract($params);\r
+                       \r
+               // Load the xml helper\r
+               $CI =& get_instance();\r
+               $CI->load->helper('xml');\r
+\r
+               // Generate the result\r
+               $xml = "<{$root}>".$newline;\r
+               foreach ($query->result_array() as $row)\r
+               {\r
+                       $xml .= $tab."<{$element}>".$newline;\r
+                       \r
+                       foreach ($row as $key => $val)\r
+                       {\r
+                               $xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;\r
+                       }\r
+                       $xml .= $tab."</{$element}>".$newline;\r
+               }\r
+               $xml .= "</$root>".$newline;\r
+               \r
+               return $xml;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Database Backup\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function backup($params = array())\r
+       {\r
+               // If the parameters have not been submitted as an\r
+               // array then we know that it is simply the table\r
+               // name, which is a valid short cut.\r
+               if (is_string($params))\r
+               {\r
+                       $params = array('tables' => $params);\r
+               }\r
+               \r
+               // ------------------------------------------------------\r
+       \r
+               // Set up our default preferences\r
+               $prefs = array(\r
+                                                       'tables'                => array(),\r
+                                                       'ignore'                => array(),\r
+                                                       'filename'              => '',\r
+                                                       'format'                => 'gzip', // gzip, zip, txt\r
+                                                       'add_drop'              => TRUE,\r
+                                                       'add_insert'    => TRUE,\r
+                                                       'newline'               => "\n"\r
+                                               );\r
+\r
+               // Did the user submit any preferences? If so set them....\r
+               if (count($params) > 0)\r
+               {\r
+                       foreach ($prefs as $key => $val)\r
+                       {\r
+                               if (isset($params[$key]))\r
+                               {\r
+                                       $prefs[$key] = $params[$key];\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+\r
+               // Are we backing up a complete database or individual tables?  \r
+               // If no table names were submitted we'll fetch the entire table list\r
+               if (count($prefs['tables']) == 0)\r
+               {\r
+                       $prefs['tables'] = $this->db->list_tables();\r
+               }\r
+               \r
+               // ------------------------------------------------------\r
+\r
+               // Validate the format\r
+               if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))\r
+               {\r
+                       $prefs['format'] = 'txt';\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+\r
+               // Is the encoder supported?  If not, we'll either issue an\r
+               // error or use plain text depending on the debug settings\r
+               if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))\r
+                OR ($prefs['format'] == 'zip'  AND ! @function_exists('gzcompress')))\r
+               {\r
+                       if ($this->db->db_debug)\r
+                       {\r
+                               return $this->db->display_error('db_unsuported_compression');\r
+                       }\r
+               \r
+                       $prefs['format'] = 'txt';\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+\r
+               // Set the filename if not provided - Only needed with Zip files\r
+               if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')\r
+               {\r
+                       $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;\r
+                       $prefs['filename'] .= '_'.date('Y-m-d_H-i', time());\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+                               \r
+               // Was a Gzip file requested?\r
+               if ($prefs['format'] == 'gzip')\r
+               {\r
+                       return gzencode($this->_backup($prefs));\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+               \r
+               // Was a text file requested?\r
+               if ($prefs['format'] == 'txt')\r
+               {\r
+                       return $this->_backup($prefs);\r
+               }\r
+\r
+               // ------------------------------------------------------\r
+\r
+               // Was a Zip file requested?            \r
+               if ($prefs['format'] == 'zip')\r
+               {\r
+                       // If they included the .zip file extension we'll remove it\r
+                       if (preg_match("|.+?\.zip$|", $prefs['filename']))\r
+                       {\r
+                               $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);\r
+                       }\r
+                       \r
+                       // Tack on the ".sql" file extension if needed\r
+                       if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))\r
+                       {\r
+                               $prefs['filename'] .= '.sql';\r
+                       }\r
+\r
+                       // Load the Zip class and output it\r
+                       \r
+                       $CI =& get_instance();\r
+                       $CI->load->library('zip');\r
+                       $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));                                                 \r
+                       return $CI->zip->get_zip();\r
+               }\r
+               \r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file DB_utility.php */\r
+/* Location: ./system/database/DB_utility.php */
\ No newline at end of file
diff --git a/database/drivers/index.html b/database/drivers/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/mssql/index.html b/database/drivers/mssql/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/mssql/mssql_driver.php b/database/drivers/mssql/mssql_driver.php
new file mode 100644 (file)
index 0000000..72dc263
--- /dev/null
@@ -0,0 +1,611 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MS SQL Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mssql_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'mssql';\r
+       \r
+       // The character used for escaping\r
+       var $_escape_char = '';\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(*) AS ";\r
+       var $_random_keyword = ' ASC'; // not currently supported\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {\r
+               if ($this->port != '')\r
+               {\r
+                       $this->hostname .= ','.$this->port;\r
+               }\r
+\r
+               return @mssql_connect($this->hostname, $this->username, $this->password);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               if ($this->port != '')\r
+               {\r
+                       $this->hostname .= ','.$this->port;\r
+               }\r
+\r
+               return @mssql_pconnect($this->hostname, $this->username, $this->password);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               // Note: The brackets are required in the event that the DB name\r
+               // contains reserved characters\r
+               return @mssql_select_db('['.$this->database.']', $this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               // @todo - add support if needed\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);\r
+               return @mssql_query($sql, $this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+\r
+               $this->simple_query('BEGIN TRAN');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('COMMIT TRAN');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('ROLLBACK TRAN');\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {\r
+               // Access the CI object\r
+               $CI =& get_instance();\r
+               \r
+               // Escape single quotes\r
+               return str_replace("'", "''", $CI->input->_remove_invisible_characters($str));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @mssql_rows_affected($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+       * Insert ID\r
+       *\r
+       * Returns the last id created in the Identity column.\r
+       *\r
+       * @access public\r
+       * @return integer\r
+       */\r
+       function insert_id()\r
+       {\r
+               $ver = self::_parse_major_version($this->version());\r
+               $sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");\r
+               $query = $this->query($sql);\r
+               $row = $query->row();\r
+               return $row->last_id;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+       * Parse major version\r
+       *\r
+       * Grabs the major version number from the \r
+       * database server version string passed in.\r
+       *\r
+       * @access private\r
+       * @param string $version\r
+       * @return int16 major version number\r
+       */\r
+       function _parse_major_version($version)\r
+       {\r
+               preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);\r
+               return $ver_info[1]; // return the major version b/c that's all we're interested in.\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+       * Version number query string\r
+       *\r
+       * @access public\r
+       * @return string\r
+       */\r
+       function _version()\r
+       {\r
+               return "SELECT @@VERSION AS ver";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+       \r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+\r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";\r
+               \r
+               // for future compatibility\r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       //$sql .= " LIKE '".$this->dbprefix."%'";\r
+                       return FALSE; // not currently supported\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";      \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT TOP 1 * FROM ".$table;   \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               // Are errros even supported in MS SQL?\r
+               return '';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               // Are error numbers supported?\r
+               return '';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return implode(', ', $tables);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return "TRUNCATE ".$table;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {\r
+               $i = $limit + $offset;\r
+       \r
+               return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @mssql_close($conn_id);\r
+       }       \r
+\r
+}\r
+\r
+\r
+\r
+/* End of file mssql_driver.php */\r
+/* Location: ./system/database/drivers/mssql/mssql_driver.php */
\ No newline at end of file
diff --git a/database/drivers/mssql/mssql_forge.php b/database/drivers/mssql/mssql_forge.php
new file mode 100644 (file)
index 0000000..8665dc0
--- /dev/null
@@ -0,0 +1,248 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MS SQL Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mssql_forge extends CI_DB_forge {\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               return "DROP TABLE ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       array   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+               $current_field_count = 0;\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+                               \r
+                               $sql .=  ' '.$attributes['TYPE'];\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)\r
+                               {\r
+                                       $sql .= ' NULL';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $sql .= ' NOT NULL';                    \r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+               \r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key = array($this->db->_protect_identifiers($key));\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+               \r
+               $sql .= "\n)";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       string  the table name\r
+        * @param       string  the column definition\r
+        * @param       string  the default value\r
+        * @param       boolean should 'NOT NULL' be added\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql;\r
+               }\r
+\r
+               $sql .= " $column_definition";\r
+\r
+               if ($default_value != '')\r
+               {\r
+                       $sql .= " DEFAULT \"$default_value\"";\r
+               }\r
+\r
+               if ($null === NULL)\r
+               {\r
+                       $sql .= ' NULL';\r
+               }\r
+               else\r
+               {\r
+                       $sql .= ' NOT NULL';\r
+               }\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               // I think this syntax will work, but can find little documentation on renaming tables in MSSQL\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+}\r
+\r
+/* End of file mssql_forge.php */\r
+/* Location: ./system/database/drivers/mssql/mssql_forge.php */
\ No newline at end of file
diff --git a/database/drivers/mssql/mssql_result.php b/database/drivers/mssql/mssql_result.php
new file mode 100644 (file)
index 0000000..33fdda9
--- /dev/null
@@ -0,0 +1,169 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MS SQL Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mssql_result extends CI_DB_result {\r
+       \r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @mssql_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @mssql_num_fields($this->result_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               while ($field = mssql_fetch_field($this->result_id))\r
+               {\r
+                       $field_names[] = $field->name;\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               while ($field = mssql_fetch_field($this->result_id))\r
+               {       \r
+                       $F                              = new stdClass();\r
+                       $F->name                = $field->name;\r
+                       $F->type                = $field->type;\r
+                       $F->max_length  = $field->max_length;\r
+                       $F->primary_key = 0;\r
+                       $F->default             = '';\r
+                       \r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_resource($this->result_id))\r
+               {\r
+                       mssql_free_result($this->result_id);\r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return mssql_data_seek($this->result_id, $n);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               return mssql_fetch_assoc($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               return mssql_fetch_object($this->result_id);\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file mssql_result.php */\r
+/* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
diff --git a/database/drivers/mssql/mssql_utility.php b/database/drivers/mssql/mssql_utility.php
new file mode 100644 (file)
index 0000000..1736fba
--- /dev/null
@@ -0,0 +1,123 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MS SQL Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mssql_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be optimized\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return FALSE; // Is this supported in MS SQL?\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be repaired\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return FALSE; // Is this supported in MS SQL?\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * MSSQL Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file mssql_utility.php */\r
+/* Location: ./system/database/drivers/mssql/mssql_utility.php */
\ No newline at end of file
diff --git a/database/drivers/mysql/index.html b/database/drivers/mysql/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/mysql/mysql_driver.php b/database/drivers/mysql/mysql_driver.php
new file mode 100644 (file)
index 0000000..e0a1cee
--- /dev/null
@@ -0,0 +1,623 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQL Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysql_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'mysql';\r
+\r
+       // The character used for escaping\r
+       var     $_escape_char = '`';\r
+       \r
+       /**\r
+        * Whether to use the MySQL "delete hack" which allows the number\r
+        * of affected rows to be shown. Uses a preg_replace when enabled,\r
+        * adding a bit more processing to all queries.\r
+        */     \r
+       var $delete_hack = TRUE;\r
+       \r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = 'SELECT COUNT(*) AS ';\r
+       var $_random_keyword = ' RAND()'; // database specific random keyword\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {\r
+               if ($this->port != '')\r
+               {\r
+                       $this->hostname .= ':'.$this->port;\r
+               }\r
+               \r
+               return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               if ($this->port != '')\r
+               {\r
+                       $this->hostname .= ':'.$this->port;\r
+               }\r
+\r
+               return @mysql_pconnect($this->hostname, $this->username, $this->password);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               return @mysql_select_db($this->database, $this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _version()\r
+       {\r
+               return "SELECT version() AS ver";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);\r
+               return @mysql_query($sql, $this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               // "DELETE FROM TABLE" returns 0 affected rows This hack modifies\r
+               // the query so that it returns the number of affected rows\r
+               if ($this->delete_hack === TRUE)\r
+               {\r
+                       if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))\r
+                       {\r
+                               $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);\r
+                       }\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+               \r
+               $this->simple_query('SET AUTOCOMMIT=0');\r
+               $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('COMMIT');\r
+               $this->simple_query('SET AUTOCOMMIT=1');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('ROLLBACK');\r
+               $this->simple_query('SET AUTOCOMMIT=1');\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {       \r
+               if (is_array($str))\r
+               {\r
+                       foreach($str as $key => $val)\r
+                       {\r
+                               $str[$key] = $this->escape_str($val);\r
+                       }\r
+               \r
+                       return $str;\r
+               }\r
+\r
+               if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))\r
+               {\r
+                       return mysql_real_escape_string($str, $this->conn_id);\r
+               }\r
+               elseif (function_exists('mysql_escape_string'))\r
+               {\r
+                       return mysql_escape_string($str);\r
+               }\r
+               else\r
+               {\r
+                       return addslashes($str);\r
+               }\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @mysql_affected_rows($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               return @mysql_insert_id($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+       \r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+               \r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return (int)$row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;     \r
+\r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       $sql .= " LIKE '".$this->dbprefix."%'";\r
+               }\r
+\r
+               return $sql;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SHOW COLUMNS FROM ".$table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT * FROM ".$table." LIMIT 1";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               return mysql_error($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               return mysql_errno($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return '('.implode(', ', $tables).')';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return "TRUNCATE ".$table;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {       \r
+               if ($offset == 0)\r
+               {\r
+                       $offset = '';\r
+               }\r
+               else\r
+               {\r
+                       $offset .= ", ";\r
+               }\r
+               \r
+               return $sql."LIMIT ".$offset.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @mysql_close($conn_id);\r
+       }\r
+       \r
+}\r
+\r
+\r
+/* End of file mysql_driver.php */\r
+/* Location: ./system/database/drivers/mysql/mysql_driver.php */
\ No newline at end of file
diff --git a/database/drivers/mysql/mysql_forge.php b/database/drivers/mysql/mysql_forge.php
new file mode 100644 (file)
index 0000000..28a77b3
--- /dev/null
@@ -0,0 +1,254 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQL Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysql_forge extends CI_DB_forge {\r
+       \r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Process Fields\r
+        *\r
+        * @access      private\r
+        * @param       mixed   the fields\r
+        * @return      string\r
+        */\r
+       function _process_fields($fields)\r
+       {\r
+               $current_field_count = 0;\r
+               $sql = '';\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+\r
+                               if (array_key_exists('NAME', $attributes))\r
+                               {\r
+                                       $sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';\r
+                               }\r
+                               \r
+                               if (array_key_exists('TYPE', $attributes))\r
+                               {\r
+                                       $sql .=  ' '.$attributes['TYPE'];\r
+                               }\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes))\r
+                               {\r
+                                       $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';\r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       mixed   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+\r
+               $sql .= $this->_process_fields($fields);\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+\r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key_name = $this->db->_protect_identifiers(implode('_', $key));\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key_name = $this->db->_protect_identifiers($key);\r
+                                       $key = array($key_name);\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+\r
+               $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       array   fields\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $fields, $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql.$this->db->_protect_identifiers($fields);\r
+               }\r
+\r
+               $sql .= $this->_process_fields($fields);\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+}\r
+\r
+/* End of file mysql_forge.php */\r
+/* Location: ./system/database/drivers/mysql/mysql_forge.php */
\ No newline at end of file
diff --git a/database/drivers/mysql/mysql_result.php b/database/drivers/mysql/mysql_result.php
new file mode 100644 (file)
index 0000000..a28a198
--- /dev/null
@@ -0,0 +1,169 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQL Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysql_result extends CI_DB_result {\r
+\r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @mysql_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @mysql_num_fields($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               while ($field = mysql_fetch_field($this->result_id))\r
+               {\r
+                       $field_names[] = $field->name;\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               while ($field = mysql_fetch_field($this->result_id))\r
+               {       \r
+                       $F                              = new stdClass();\r
+                       $F->name                = $field->name;\r
+                       $F->type                = $field->type;\r
+                       $F->default             = $field->def;\r
+                       $F->max_length  = $field->max_length;\r
+                       $F->primary_key = $field->primary_key;\r
+                       \r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_resource($this->result_id))\r
+               {\r
+                       mysql_free_result($this->result_id);\r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return mysql_data_seek($this->result_id, $n);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               return mysql_fetch_assoc($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               return mysql_fetch_object($this->result_id);\r
+       }\r
+       \r
+}\r
+\r
+\r
+/* End of file mysql_result.php */\r
+/* Location: ./system/database/drivers/mysql/mysql_result.php */
\ No newline at end of file
diff --git a/database/drivers/mysql/mysql_utility.php b/database/drivers/mysql/mysql_utility.php
new file mode 100644 (file)
index 0000000..d2c10db
--- /dev/null
@@ -0,0 +1,245 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQL Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysql_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               return "SHOW DATABASES";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be optimized\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be repaired\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return "REPAIR TABLE ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       /**\r
+        * MySQL Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               if (count($params) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // Extract the prefs for simplicity\r
+               extract($params);\r
+       \r
+               // Build the output\r
+               $output = '';\r
+               foreach ((array)$tables as $table)\r
+               {\r
+                       // Is the table in the "ignore" list?\r
+                       if (in_array($table, (array)$ignore, TRUE))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // Get the table schema\r
+                       $query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.'.$table);\r
+                       \r
+                       // No result means the table name was invalid\r
+                       if ($query === FALSE)\r
+                       {\r
+                               continue;\r
+                       }\r
+                       \r
+                       // Write out the table schema\r
+                       $output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;\r
+\r
+                       if ($add_drop == TRUE)\r
+                       {\r
+                               $output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;\r
+                       }\r
+                       \r
+                       $i = 0;\r
+                       $result = $query->result_array();\r
+                       foreach ($result[0] as $val)\r
+                       {\r
+                               if ($i++ % 2)\r
+                               {                                       \r
+                                       $output .= $val.';'.$newline.$newline;\r
+                               }\r
+                       }\r
+                       \r
+                       // If inserts are not needed we're done...\r
+                       if ($add_insert == FALSE)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // Grab all the data from the current table\r
+                       $query = $this->db->query("SELECT * FROM $table");\r
+                       \r
+                       if ($query->num_rows() == 0)\r
+                       {\r
+                               continue;\r
+                       }\r
+               \r
+                       // Fetch the field names and determine if the field is an\r
+                       // integer type.  We use this info to decide whether to\r
+                       // surround the data with quotes or not\r
+                       \r
+                       $i = 0;\r
+                       $field_str = '';\r
+                       $is_int = array();\r
+                       while ($field = mysql_fetch_field($query->result_id))\r
+                       {\r
+                               // Most versions of MySQL store timestamp as a string\r
+                               $is_int[$i] = (in_array(\r
+                                                                               strtolower(mysql_field_type($query->result_id, $i)),\r
+                                                                               array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), \r
+                                                                               TRUE)\r
+                                                                               ) ? TRUE : FALSE;\r
+                                                                               \r
+                               // Create a string of field names\r
+                               $field_str .= '`'.$field->name.'`, ';\r
+                               $i++;\r
+                       }\r
+                       \r
+                       // Trim off the end comma\r
+                       $field_str = preg_replace( "/, $/" , "" , $field_str);\r
+                       \r
+                       \r
+                       // Build the insert string\r
+                       foreach ($query->result_array() as $row)\r
+                       {\r
+                               $val_str = '';\r
+                       \r
+                               $i = 0;\r
+                               foreach ($row as $v)\r
+                               {\r
+                                       // Is the value NULL?\r
+                                       if ($v === NULL)\r
+                                       {\r
+                                               $val_str .= 'NULL';\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // Escape the data if it's not an integer\r
+                                               if ($is_int[$i] == FALSE)\r
+                                               {\r
+                                                       $val_str .= $this->db->escape($v);\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       $val_str .= $v;\r
+                                               }                                       \r
+                                       }                                       \r
+                                       \r
+                                       // Append a comma\r
+                                       $val_str .= ', ';\r
+                                       $i++;\r
+                               }\r
+                               \r
+                               // Remove the comma at the end of the string\r
+                               $val_str = preg_replace( "/, $/" , "" , $val_str);\r
+                                                               \r
+                               // Build the INSERT string\r
+                               $output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;\r
+                       }\r
+                       \r
+                       $output .= $newline.$newline;\r
+               }\r
+\r
+               return $output;\r
+       }\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+}\r
+\r
+/* End of file mysql_utility.php */\r
+/* Location: ./system/database/drivers/mysql/mysql_utility.php */
\ No newline at end of file
diff --git a/database/drivers/mysqli/index.html b/database/drivers/mysqli/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/mysqli/mysqli_driver.php b/database/drivers/mysqli/mysqli_driver.php
new file mode 100644 (file)
index 0000000..4bbe5eb
--- /dev/null
@@ -0,0 +1,606 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQLi Database Adapter Class - MySQLi only works with PHP 5\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysqli_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'mysqli';\r
+       \r
+       // The character used for escaping\r
+       var $_escape_char = '`';\r
+\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(*) AS ";\r
+       var $_random_keyword = ' RAND()'; // database specific random keyword\r
+\r
+       /**\r
+        * Whether to use the MySQL "delete hack" which allows the number\r
+        * of affected rows to be shown. Uses a preg_replace when enabled,\r
+        * adding a bit more processing to all queries.\r
+        */     \r
+       var $delete_hack = TRUE;\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {\r
+               return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               return $this->db_connect();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               return @mysqli_select_db($this->conn_id, $this->database);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function _db_set_charset($charset, $collation)\r
+       {\r
+               return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _version()\r
+       {\r
+               return "SELECT version() AS ver";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);        \r
+               $result = @mysqli_query($this->conn_id, $sql);\r
+               return $result;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               // "DELETE FROM TABLE" returns 0 affected rows This hack modifies\r
+               // the query so that it returns the number of affected rows\r
+               if ($this->delete_hack === TRUE)\r
+               {\r
+                       if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))\r
+                       {\r
+                               $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);\r
+                       }\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+\r
+               $this->simple_query('SET AUTOCOMMIT=0');\r
+               $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('COMMIT');\r
+               $this->simple_query('SET AUTOCOMMIT=1');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('ROLLBACK');\r
+               $this->simple_query('SET AUTOCOMMIT=1');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {\r
+               if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))\r
+               {\r
+                       return mysqli_real_escape_string($this->conn_id, $str);\r
+               }\r
+               elseif (function_exists('mysql_escape_string'))\r
+               {\r
+                       return mysql_escape_string($str);\r
+               }\r
+               else\r
+               {\r
+                       return addslashes($str);\r
+               }\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @mysqli_affected_rows($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               return @mysqli_insert_id($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+               \r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+               \r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;     \r
+               \r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       $sql .= " LIKE '".$this->dbprefix."%'";\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SHOW COLUMNS FROM ".$table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT * FROM ".$table." LIMIT 1";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               return mysqli_error($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               return mysqli_errno($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return '('.implode(', ', $tables).')';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+               \r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+               \r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return "TRUNCATE ".$table;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {       \r
+               $sql .= "LIMIT ".$limit;\r
+       \r
+               if ($offset > 0)\r
+               {\r
+                       $sql .= " OFFSET ".$offset;\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @mysqli_close($conn_id);\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+/* End of file mysqli_driver.php */\r
+/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
\ No newline at end of file
diff --git a/database/drivers/mysqli/mysqli_forge.php b/database/drivers/mysqli/mysqli_forge.php
new file mode 100644 (file)
index 0000000..c7889bf
--- /dev/null
@@ -0,0 +1,254 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQLi Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysqli_forge extends CI_DB_forge {\r
+       \r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Process Fields\r
+        *\r
+        * @access      private\r
+        * @param       mixed   the fields\r
+        * @return      string\r
+        */\r
+       function _process_fields($fields)\r
+       {\r
+               $current_field_count = 0;\r
+               $sql = '';\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+\r
+                               if (array_key_exists('NAME', $attributes))\r
+                               {\r
+                                       $sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';\r
+                               }\r
+                               \r
+                               if (array_key_exists('TYPE', $attributes))\r
+                               {\r
+                                       $sql .=  ' '.$attributes['TYPE'];\r
+                               }\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes))\r
+                               {\r
+                                       $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';\r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       mixed   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+\r
+               $sql .= $this->_process_fields($fields);\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+\r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key_name = $this->db->_protect_identifiers(implode('_', $key));\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key_name = $this->db->_protect_identifiers($key);\r
+                                       $key = array($key_name);\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+\r
+               $sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       array   fields\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $fields, $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql.$this->db->_protect_identifiers($fields);\r
+               }\r
+\r
+               $sql .= $this->_process_fields($fields);\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+}\r
+\r
+/* End of file mysqli_forge.php */\r
+/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
\ No newline at end of file
diff --git a/database/drivers/mysqli/mysqli_result.php b/database/drivers/mysqli/mysqli_result.php
new file mode 100644 (file)
index 0000000..b690914
--- /dev/null
@@ -0,0 +1,169 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQLi Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysqli_result extends CI_DB_result {\r
+       \r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @mysqli_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @mysqli_num_fields($this->result_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               while ($field = mysqli_fetch_field($this->result_id))\r
+               {\r
+                       $field_names[] = $field->name;\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               while ($field = mysqli_fetch_field($this->result_id))\r
+               {       \r
+                       $F                              = new stdClass();\r
+                       $F->name                = $field->name;\r
+                       $F->type                = $field->type;\r
+                       $F->default             = $field->def;\r
+                       $F->max_length  = $field->max_length;\r
+                       $F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0;\r
+                       \r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_object($this->result_id))\r
+               {\r
+                       mysqli_free_result($this->result_id);\r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return mysqli_data_seek($this->result_id, $n);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               return mysqli_fetch_assoc($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               return mysqli_fetch_object($this->result_id);\r
+       }\r
+       \r
+}\r
+\r
+\r
+/* End of file mysqli_result.php */\r
+/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
\ No newline at end of file
diff --git a/database/drivers/mysqli/mysqli_utility.php b/database/drivers/mysqli/mysqli_utility.php
new file mode 100644 (file)
index 0000000..d19b643
--- /dev/null
@@ -0,0 +1,123 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * MySQLi Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_mysqli_utility extends CI_DB_utility {\r
+       \r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               return "SHOW DATABASES";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be optimized\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be repaired\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return "REPAIR TABLE ".$this->db->_escape_identifiers($table);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * MySQLi Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+}\r
+\r
+/* End of file mysqli_utility.php */\r
+/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
\ No newline at end of file
diff --git a/database/drivers/oci8/index.html b/database/drivers/oci8/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/oci8/oci8_driver.php b/database/drivers/oci8/oci8_driver.php
new file mode 100644 (file)
index 0000000..365c9e7
--- /dev/null
@@ -0,0 +1,726 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * oci8 Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage  Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+\r
+/**\r
+ * oci8 Database Adapter Class\r
+ *\r
+ * This is a modification of the DB_driver class to\r
+ * permit access to oracle databases\r
+ *\r
+ * NOTE: this uses the PHP 4 oci methods\r
+ *\r
+ * @author       Kelly McArdle\r
+ *\r
+ */\r
+\r
+class CI_DB_oci8_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'oci8';\r
+       \r
+       // The character used for excaping\r
+       var $_escape_char = '"';\r
+\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(1) AS ";\r
+       var $_random_keyword = ' ASC'; // not currently supported\r
+\r
+       // Set "auto commit" by default\r
+       var $_commit = OCI_COMMIT_ON_SUCCESS;\r
+\r
+       // need to track statement id and cursor id\r
+       var $stmt_id;\r
+       var $curs_id;\r
+\r
+       // if we use a limit, we will add a field that will\r
+       // throw off num_fields later\r
+       var $limit_used;\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access  private called by the base class\r
+        * @return  resource\r
+        */\r
+       function db_connect()\r
+       {\r
+               return @ocilogon($this->username, $this->password, $this->hostname);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access  private called by the base class\r
+        * @return  resource\r
+        */\r
+       function db_pconnect()\r
+       {\r
+               return @ociplogon($this->username, $this->password, $this->hostname);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access  private called by the base class\r
+        * @return  resource\r
+        */\r
+       function db_select()\r
+       {\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               // @todo - add support if needed\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access  public\r
+        * @return  string\r
+        */\r
+       function _version()\r
+       {\r
+               return ociserverversion($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access  private called by the base class\r
+        * @param   string  an SQL query\r
+        * @return  resource\r
+        */\r
+       function _execute($sql)\r
+       {\r
+               // oracle must parse the query before it is run. All of the actions with\r
+               // the query are based on the statement id returned by ociparse\r
+               $this->stmt_id = FALSE;\r
+               $this->_set_stmt_id($sql);\r
+               ocisetprefetch($this->stmt_id, 1000);\r
+               return @ociexecute($this->stmt_id, $this->_commit);\r
+       }\r
+\r
+       /**\r
+        * Generate a statement ID\r
+        *\r
+        * @access  private\r
+        * @param   string  an SQL query\r
+        * @return  none\r
+        */\r
+       function _set_stmt_id($sql)\r
+       {\r
+               if ( ! is_resource($this->stmt_id))\r
+               {\r
+                       $this->stmt_id = ociparse($this->conn_id, $this->_prep_query($sql));\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access  private called by execute()\r
+        * @param   string  an SQL query\r
+        * @return  string\r
+        */\r
+       function _prep_query($sql)\r
+       {\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * getCursor.  Returns a cursor from the datbase\r
+        *\r
+        * @access  public\r
+        * @return  cursor id\r
+        */\r
+       function get_cursor()\r
+       {\r
+               $this->curs_id = ocinewcursor($this->conn_id);\r
+               return $this->curs_id;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Stored Procedure.  Executes a stored procedure\r
+        *\r
+        * @access  public\r
+        * @param   package      package stored procedure is in\r
+        * @param   procedure   stored procedure to execute\r
+        * @param   params        array of parameters\r
+        * @return  array\r
+        *\r
+        * params array keys\r
+        *\r
+        * KEY    OPTIONAL      NOTES\r
+        * name         no              the name of the parameter should be in :<param_name> format\r
+        * value        no              the value of the parameter.  If this is an OUT or IN OUT parameter,\r
+        *                                      this should be a reference to a variable\r
+        * type         yes             the type of the parameter\r
+        * length       yes             the max size of the parameter\r
+        */\r
+       function stored_procedure($package, $procedure, $params)\r
+       {\r
+               if ($package == '' OR $procedure == '' OR ! is_array($params))\r
+               {\r
+                       if ($this->db_debug)\r
+                       {\r
+                               log_message('error', 'Invalid query: '.$package.'.'.$procedure);\r
+                               return $this->display_error('db_invalid_query');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               \r
+               // build the query string\r
+               $sql = "begin $package.$procedure(";\r
+\r
+               $have_cursor = FALSE;\r
+               foreach($params as $param)\r
+               {\r
+                       $sql .= $param['name'] . ",";\r
+                       \r
+                       if (array_key_exists('type', $param) && ($param['type'] == OCI_B_CURSOR))\r
+                       {\r
+                               $have_cursor = TRUE;\r
+                       }\r
+               }\r
+               $sql = trim($sql, ",") . "); end;";\r
+                               \r
+               $this->stmt_id = FALSE;\r
+               $this->_set_stmt_id($sql);\r
+               $this->_bind_params($params);\r
+               $this->query($sql, FALSE, $have_cursor);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Bind parameters\r
+        *\r
+        * @access  private\r
+        * @return  none\r
+        */\r
+       function _bind_params($params)\r
+       {\r
+               if ( ! is_array($params) OR ! is_resource($this->stmt_id))\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               foreach ($params as $param)\r
+               {\r
+                       foreach (array('name', 'value', 'type', 'length') as $val)\r
+                       {\r
+                               if ( ! isset($param[$val]))\r
+                               {\r
+                                       $param[$val] = '';\r
+                               }\r
+                       }\r
+\r
+                       ocibindbyname($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+               \r
+               $this->_commit = OCI_DEFAULT;\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $ret = OCIcommit($this->conn_id);\r
+               $this->_commit = OCI_COMMIT_ON_SUCCESS;\r
+               return $ret;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $ret = OCIrollback($this->conn_id);\r
+               $this->_commit = OCI_COMMIT_ON_SUCCESS;\r
+               return $ret;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access  public\r
+        * @param   string\r
+        * @return  string\r
+        */\r
+       function escape_str($str)\r
+       {\r
+               // Access the CI object\r
+               $CI =& get_instance();\r
+\r
+               return $CI->_remove_invisible_characters($str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access  public\r
+        * @return  integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @ocirowcount($this->stmt_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access  public\r
+        * @return  integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               // not supported in oracle\r
+               return $this->display_error('db_unsupported_function');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access  public\r
+        * @param   string\r
+        * @return  string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+\r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+\r
+               if ($query == FALSE)\r
+                       {\r
+                       return 0;\r
+                       }\r
+\r
+               $row = $query->row();\r
+               return $row->NUMROWS;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access  private\r
+        * @param       boolean\r
+        * @return  string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SELECT TABLE_NAME FROM ALL_TABLES";\r
+\r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       $sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'";\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access  public\r
+        * @param   string  the table name\r
+        * @return  string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access  public\r
+        * @param   string  the table name\r
+        * @return  object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT * FROM ".$table." where rownum = 1";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access  private\r
+        * @return  string\r
+        */\r
+       function _error_message()\r
+       {\r
+               $error = ocierror($this->conn_id);\r
+               return $error['message'];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access  private\r
+        * @return  integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               $error = ocierror($this->conn_id);\r
+               return $error['code'];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return implode(', ', $tables);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access  public\r
+        * @param   string  the table name\r
+        * @param   array   the insert keys\r
+        * @param   array   the insert values\r
+        * @return  string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {\r
+       return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return "TRUNCATE TABLE ".$table;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access  public\r
+        * @param   string  the sql query string\r
+        * @param   integer the number of rows to limit the query to\r
+        * @param   integer the offset value\r
+        * @return  string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {\r
+               $limit = $offset + $limit;\r
+               $newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)";\r
+\r
+               if ($offset != 0)\r
+               {\r
+                       $newsql .= " WHERE rnum >= $offset";\r
+               }\r
+\r
+               // remember that we used limits\r
+               $this->limit_used = TRUE;\r
+\r
+               return $newsql;\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access  public\r
+        * @param   resource\r
+        * @return  void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @ocilogoff($conn_id);\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+\r
+/* End of file oci8_driver.php */\r
+/* Location: ./system/database/drivers/oci8/oci8_driver.php */
\ No newline at end of file
diff --git a/database/drivers/oci8/oci8_forge.php b/database/drivers/oci8/oci8_forge.php
new file mode 100644 (file)
index 0000000..4b073d0
--- /dev/null
@@ -0,0 +1,248 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Oracle Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_oci8_forge extends CI_DB_forge {\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       array   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+               $current_field_count = 0;\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+                               \r
+                               $sql .=  ' '.$attributes['TYPE'];\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)\r
+                               {\r
+                                       $sql .= ' NULL';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $sql .= ' NOT NULL';                    \r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+\r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key = array($this->db->_protect_identifiers($key));\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+               \r
+               $sql .= "\n)";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       string  the table name\r
+        * @param       string  the column definition\r
+        * @param       string  the default value\r
+        * @param       boolean should 'NOT NULL' be added\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql;\r
+               }\r
+\r
+               $sql .= " $column_definition";\r
+\r
+               if ($default_value != '')\r
+               {\r
+                       $sql .= " DEFAULT \"$default_value\"";\r
+               }\r
+\r
+               if ($null === NULL)\r
+               {\r
+                       $sql .= ' NULL';\r
+               }\r
+               else\r
+               {\r
+                       $sql .= ' NOT NULL';\r
+               }\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+\r
+}\r
+\r
+/* End of file oci8_forge.php */\r
+/* Location: ./system/database/drivers/oci8/oci8_forge.php */
\ No newline at end of file
diff --git a/database/drivers/oci8/oci8_result.php b/database/drivers/oci8/oci8_result.php
new file mode 100644 (file)
index 0000000..4cfbfa4
--- /dev/null
@@ -0,0 +1,249 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * oci8 Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_oci8_result extends CI_DB_result {\r
+\r
+       var $stmt_id;\r
+       var $curs_id;\r
+       var $limit_used;\r
+\r
+       /**\r
+        * Number of rows in the result set.\r
+        *\r
+        * Oracle doesn't have a graceful way to retun the number of rows\r
+        * so we have to use what amounts to a hack.\r
+        * \r
+        *\r
+        * @access  public\r
+        * @return  integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               $rowcount = count($this->result_array());\r
+               @ociexecute($this->stmt_id);\r
+\r
+               if ($this->curs_id)\r
+               {\r
+                       @ociexecute($this->curs_id);\r
+               }\r
+\r
+               return $rowcount;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access  public\r
+        * @return  integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               $count = @ocinumcols($this->stmt_id);\r
+\r
+               // if we used a limit we subtract it\r
+               if ($this->limit_used)\r
+               {\r
+                       $count = $count - 1;\r
+               }\r
+\r
+               return $count;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               $fieldCount = $this->num_fields();\r
+               for ($c = 1; $c <= $fieldCount; $c++)\r
+               {\r
+                       $field_names[] = ocicolumnname($this->stmt_id, $c);\r
+               }\r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access  public\r
+        * @return  array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               $fieldCount = $this->num_fields();\r
+               for ($c = 1; $c <= $fieldCount; $c++)\r
+               {\r
+                       $F                        = new stdClass();\r
+                       $F->name                = ocicolumnname($this->stmt_id, $c);\r
+                       $F->type                = ocicolumntype($this->stmt_id, $c);\r
+                       $F->max_length  = ocicolumnsize($this->stmt_id, $c);\r
+\r
+                       $retval[] = $F;\r
+               }\r
+\r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_resource($this->result_id))\r
+               {\r
+                       ocifreestatement($this->result_id);                     \r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access  private\r
+        * @return  array\r
+        */\r
+       function _fetch_assoc(&$row)\r
+       {\r
+               $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;\r
+       \r
+               return ocifetchinto($id, $row, OCI_ASSOC + OCI_RETURN_NULLS);   \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access  private\r
+        * @return  object\r
+        */\r
+       function _fetch_object()\r
+       {       \r
+               $result = array();\r
+\r
+               // If PHP 5 is being used we can fetch an result object\r
+               if (function_exists('oci_fetch_object'))\r
+               {\r
+                       $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;\r
+                       \r
+                       return @oci_fetch_object($id);\r
+               }\r
+               \r
+               // If PHP 4 is being used we have to build our own result\r
+               foreach ($this->result_array() as $key => $val)\r
+               {\r
+                       $obj = new stdClass();\r
+                       if (is_array($val))\r
+                       {\r
+                               foreach ($val as $k => $v)\r
+                               {\r
+                                       $obj->$k = $v;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $obj->$key = $val;\r
+                       }\r
+                       \r
+                       $result[] = $obj;\r
+               }\r
+\r
+               return $result;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Query result.  "array" version.\r
+        *\r
+        * @access  public\r
+        * @return  array\r
+        */\r
+       function result_array()\r
+       {\r
+               if (count($this->result_array) > 0)\r
+               {\r
+                       return $this->result_array;\r
+               }\r
+\r
+               // oracle's fetch functions do not return arrays.\r
+               // The information is returned in reference parameters\r
+               $row = NULL;\r
+               while ($this->_fetch_assoc($row))\r
+               {\r
+                       $this->result_array[] = $row;\r
+               }\r
+\r
+               return $this->result_array;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return FALSE; // Not needed\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file oci8_result.php */\r
+/* Location: ./system/database/drivers/oci8/oci8_result.php */
\ No newline at end of file
diff --git a/database/drivers/oci8/oci8_utility.php b/database/drivers/oci8/oci8_utility.php
new file mode 100644 (file)
index 0000000..a3b6d81
--- /dev/null
@@ -0,0 +1,122 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Oracle Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_oci8_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be optimized\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return FALSE; // Is this supported in Oracle?\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be repaired\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return FALSE; // Is this supported in Oracle?\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Oracle Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+}\r
+\r
+/* End of file oci8_utility.php */\r
+/* Location: ./system/database/drivers/oci8/oci8_utility.php */
\ No newline at end of file
diff --git a/database/drivers/odbc/index.html b/database/drivers/odbc/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/odbc/odbc_driver.php b/database/drivers/odbc/odbc_driver.php
new file mode 100644 (file)
index 0000000..1f03771
--- /dev/null
@@ -0,0 +1,583 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * ODBC Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_odbc_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'odbc';\r
+       \r
+       // the character used to excape - not necessary for ODBC\r
+       var $_escape_char = '';\r
+\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(*) AS ";\r
+       var $_random_keyword;\r
+\r
+\r
+       function CI_DB_odbc_driver($params)\r
+       {\r
+               parent::CI_DB($params);\r
+               \r
+               $this->_random_keyword = ' RND('.time().')'; // database specific random keyword\r
+       }\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {\r
+               return @odbc_connect($this->hostname, $this->username, $this->password);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               return @odbc_pconnect($this->hostname, $this->username, $this->password);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               // Not needed for ODBC\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               // @todo - add support if needed\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _version()\r
+       {\r
+               return "SELECT version() AS ver";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);\r
+               return @odbc_exec($this->conn_id, $sql);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+\r
+               return odbc_autocommit($this->conn_id, FALSE);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $ret = odbc_commit($this->conn_id);\r
+               odbc_autocommit($this->conn_id, TRUE);\r
+               return $ret;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $ret = odbc_rollback($this->conn_id);\r
+               odbc_autocommit($this->conn_id, TRUE);\r
+               return $ret;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {\r
+               // Access the CI object\r
+               $CI =& get_instance();\r
+\r
+               // ODBC doesn't require escaping\r
+               return $CI->_remove_invisible_characters($str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @odbc_num_rows($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               return @odbc_insert_id($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+       \r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+       \r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SHOW TABLES FROM `".$this->database."`";\r
+\r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       //$sql .= " LIKE '".$this->dbprefix."%'";\r
+                       return FALSE; // not currently supported\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SHOW COLUMNS FROM ".$table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT TOP 1 FROM ".$table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               return odbc_errormsg($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               return odbc_error($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return '('.implode(', ', $tables).')';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return $this->_delete($table);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {\r
+               // Does ODBC doesn't use the LIMIT clause?\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @odbc_close($conn_id);\r
+       }\r
+\r
+       \r
+}\r
+\r
+\r
+\r
+/* End of file odbc_driver.php */\r
+/* Location: ./system/database/drivers/odbc/odbc_driver.php */
\ No newline at end of file
diff --git a/database/drivers/odbc/odbc_forge.php b/database/drivers/odbc/odbc_forge.php
new file mode 100644 (file)
index 0000000..099925c
--- /dev/null
@@ -0,0 +1,266 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * ODBC Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/database/\r
+ */\r
+class CI_DB_odbc_forge extends CI_DB_forge {\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database()\r
+       {\r
+               // ODBC has no "create database" command since it's\r
+               // designed to connect to an existing database\r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               // ODBC has no "drop database" command since it's\r
+               // designed to connect to an existing database          \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       array   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+               $current_field_count = 0;\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+                               \r
+                               $sql .=  ' '.$attributes['TYPE'];\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)\r
+                               {\r
+                                       $sql .= ' NULL';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $sql .= ' NOT NULL';                    \r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+               \r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key = array($this->db->_protect_identifiers($key));\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+               \r
+               $sql .= "\n)";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               // Not a supported ODBC feature \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       string  the table name\r
+        * @param       string  the column definition\r
+        * @param       string  the default value\r
+        * @param       boolean should 'NOT NULL' be added\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql;\r
+               }\r
+\r
+               $sql .= " $column_definition";\r
+\r
+               if ($default_value != '')\r
+               {\r
+                       $sql .= " DEFAULT \"$default_value\"";\r
+               }\r
+\r
+               if ($null === NULL)\r
+               {\r
+                       $sql .= ' NULL';\r
+               }\r
+               else\r
+               {\r
+                       $sql .= ' NOT NULL';\r
+               }\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+               \r
+       }\r
+\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+\r
+}\r
+\r
+/* End of file odbc_forge.php */\r
+/* Location: ./system/database/drivers/odbc/odbc_forge.php */
\ No newline at end of file
diff --git a/database/drivers/odbc/odbc_result.php b/database/drivers/odbc/odbc_result.php
new file mode 100644 (file)
index 0000000..6d6542e
--- /dev/null
@@ -0,0 +1,228 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * ODBC Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_odbc_result extends CI_DB_result {\r
+       \r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @odbc_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @odbc_num_fields($this->result_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $field_names[]  = odbc_field_name($this->result_id, $i);\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $F                              = new stdClass();\r
+                       $F->name                = odbc_field_name($this->result_id, $i);\r
+                       $F->type                = odbc_field_type($this->result_id, $i);\r
+                       $F->max_length  = odbc_field_len($this->result_id, $i);\r
+                       $F->primary_key = 0;\r
+                       $F->default             = '';\r
+\r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_resource($this->result_id))\r
+               {\r
+                       odbc_free_result($this->result_id);\r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               if (function_exists('odbc_fetch_object'))\r
+               {\r
+                       return odbc_fetch_array($this->result_id);\r
+               }\r
+               else\r
+               {\r
+                       return $this->_odbc_fetch_array($this->result_id);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               if (function_exists('odbc_fetch_object'))\r
+               {\r
+                       return odbc_fetch_object($this->result_id);\r
+               }\r
+               else\r
+               {\r
+                       return $this->_odbc_fetch_object($this->result_id);\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * subsititutes the odbc_fetch_object function when\r
+        * not available (odbc_fetch_object requires unixODBC)\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _odbc_fetch_object(& $odbc_result) {\r
+               $rs = array();\r
+               $rs_obj = false;\r
+               if (odbc_fetch_into($odbc_result, $rs)) {\r
+                       foreach ($rs as $k=>$v) {\r
+                               $field_name= odbc_field_name($odbc_result, $k+1);\r
+                               $rs_obj->$field_name = $v;\r
+                       }\r
+               }\r
+               return $rs_obj;\r
+       }\r
+\r
+\r
+       /**\r
+        * Result - array\r
+        *\r
+        * subsititutes the odbc_fetch_array function when\r
+        * not available (odbc_fetch_array requires unixODBC)\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _odbc_fetch_array(& $odbc_result) {\r
+               $rs = array();\r
+               $rs_assoc = false;\r
+               if (odbc_fetch_into($odbc_result, $rs)) {\r
+                       $rs_assoc=array();\r
+                       foreach ($rs as $k=>$v) {\r
+                               $field_name= odbc_field_name($odbc_result, $k+1);\r
+                               $rs_assoc[$field_name] = $v;\r
+                       }\r
+               }\r
+               return $rs_assoc;\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file odbc_result.php */\r
+/* Location: ./system/database/drivers/odbc/odbc_result.php */
\ No newline at end of file
diff --git a/database/drivers/odbc/odbc_utility.php b/database/drivers/odbc/odbc_utility.php
new file mode 100644 (file)
index 0000000..6f4376e
--- /dev/null
@@ -0,0 +1,148 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * ODBC Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/database/\r
+ */\r
+class CI_DB_odbc_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               // Not sure if ODBC lets you list all databases...      \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be optimized\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               // Not a supported ODBC feature \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be repaired\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               // Not a supported ODBC feature \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * ODBC Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+       \r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database()\r
+       {\r
+               // ODBC has no "create database" command since it's\r
+               // designed to connect to an existing database\r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               // ODBC has no "drop database" command since it's\r
+               // designed to connect to an existing database          \r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return FALSE;\r
+       }\r
+}\r
+\r
+/* End of file odbc_utility.php */\r
+/* Location: ./system/database/drivers/odbc/odbc_utility.php */
\ No newline at end of file
diff --git a/database/drivers/postgre/index.html b/database/drivers/postgre/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/postgre/postgre_driver.php b/database/drivers/postgre/postgre_driver.php
new file mode 100644 (file)
index 0000000..d94cce1
--- /dev/null
@@ -0,0 +1,625 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Postgre Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_postgre_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'postgre';\r
+       \r
+       var $_escape_char = '"';\r
+\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(*) AS ";\r
+       var $_random_keyword = ' RANDOM()'; // database specific random keyword\r
+\r
+       /**\r
+        * Connection String\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _connect_string()\r
+       {\r
+               $components = array(\r
+                                                               'hostname'      => 'host',\r
+                                                               'port'          => 'port',\r
+                                                               'database'      => 'dbname',\r
+                                                               'username'      => 'user',\r
+                                                               'password'      => 'password'\r
+                                                       );\r
+               \r
+               $connect_string = "";\r
+               foreach ($components as $key => $val)\r
+               {\r
+                       if (isset($this->$key) && $this->$key != '')\r
+                       {\r
+                               $connect_string .= " $val=".$this->$key;\r
+                       }\r
+               }\r
+               return trim($connect_string);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {               \r
+               return @pg_connect($this->_connect_string());\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               return @pg_pconnect($this->_connect_string());\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               // Not needed for Postgre so we'll return TRUE\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               // @todo - add support if needed\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _version()\r
+       {\r
+               return "SELECT version() AS ver";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);\r
+               return @pg_query($this->conn_id, $sql);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+\r
+               return @pg_exec($this->conn_id, "begin");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               return @pg_exec($this->conn_id, "commit");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               return @pg_exec($this->conn_id, "rollback");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {       \r
+               return pg_escape_string($str);\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return @pg_affected_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               $v = $this->_version();\r
+               $v = $v['server'];\r
+               \r
+               $table  = func_num_args() > 0 ? func_get_arg(0) : null;\r
+               $column = func_num_args() > 1 ? func_get_arg(1) : null;\r
+               \r
+               if ($table == null && $v >= '8.1')\r
+               {\r
+                       $sql='SELECT LASTVAL() as ins_id';\r
+               }\r
+               elseif ($table != null && $column != null && $v >= '8.0')\r
+               {\r
+                       $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);\r
+                       $query = $this->query($sql);\r
+                       $row = $query->row();\r
+                       $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);\r
+               }\r
+               elseif ($table != null)\r
+               {\r
+                       // seq_name passed in table parameter\r
+                       $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);\r
+               }\r
+               else\r
+               {\r
+                       return pg_last_oid($this->result_id);\r
+               }\r
+               $query = $this->query($sql);\r
+               $row = $query->row();\r
+               return $row->ins_id;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+\r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+                               \r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {       \r
+               $sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";        \r
+               \r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       $sql .= " AND table_name LIKE '".$this->dbprefix."%'";\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT * FROM ".$table." LIMIT 1";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               return pg_last_error($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               return '';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return implode(', ', $tables);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return "TRUNCATE ".$table;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {       \r
+               $sql .= "LIMIT ".$limit;\r
+       \r
+               if ($offset > 0)\r
+               {\r
+                       $sql .= " OFFSET ".$offset;\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @pg_close($conn_id);\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+/* End of file postgre_driver.php */\r
+/* Location: ./system/database/drivers/postgre/postgre_driver.php */
\ No newline at end of file
diff --git a/database/drivers/postgre/postgre_forge.php b/database/drivers/postgre/postgre_forge.php
new file mode 100644 (file)
index 0000000..5b4bcc2
--- /dev/null
@@ -0,0 +1,248 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Postgre Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_postgre_forge extends CI_DB_forge {\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       array   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               if ($if_not_exists === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)." (";\r
+               $current_field_count = 0;\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+                               \r
+                               $sql .=  ' '.$attributes['TYPE'];\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)\r
+                               {\r
+                                       $sql .= ' NULL';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $sql .= ' NOT NULL';                    \r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+               \r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key = array($this->db->_protect_identifiers($key));\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+\r
+               $sql .= "\n);";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               return "DROP TABLE ".$this->db->_escape_identifiers($table)." CASCADE";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       string  the table name\r
+        * @param       string  the column definition\r
+        * @param       string  the default value\r
+        * @param       boolean should 'NOT NULL' be added\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       return $sql;\r
+               }\r
+\r
+               $sql .= " $column_definition";\r
+\r
+               if ($default_value != '')\r
+               {\r
+                       $sql .= " DEFAULT \"$default_value\"";\r
+               }\r
+\r
+               if ($null === NULL)\r
+               {\r
+                       $sql .= ' NULL';\r
+               }\r
+               else\r
+               {\r
+                       $sql .= ' NOT NULL';\r
+               }\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+\r
+\r
+}\r
+\r
+/* End of file postgre_forge.php */\r
+/* Location: ./system/database/drivers/postgre/postgre_forge.php */
\ No newline at end of file
diff --git a/database/drivers/postgre/postgre_result.php b/database/drivers/postgre/postgre_result.php
new file mode 100644 (file)
index 0000000..78b9a60
--- /dev/null
@@ -0,0 +1,169 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Postgres Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_postgre_result extends CI_DB_result {\r
+\r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @pg_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @pg_num_fields($this->result_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $field_names[] = pg_field_name($this->result_id, $i);\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $F                              = new stdClass();\r
+                       $F->name                = pg_field_name($this->result_id, $i);\r
+                       $F->type                = pg_field_type($this->result_id, $i);\r
+                       $F->max_length  = pg_field_size($this->result_id, $i);\r
+                       $F->primary_key = 0;\r
+                       $F->default             = '';\r
+\r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               if (is_resource($this->result_id))\r
+               {\r
+                       pg_free_result($this->result_id);\r
+                       $this->result_id = FALSE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return pg_result_seek($this->result_id, $n);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               return pg_fetch_assoc($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               return pg_fetch_object($this->result_id);\r
+       }\r
+       \r
+}\r
+\r
+\r
+/* End of file postgre_result.php */\r
+/* Location: ./system/database/drivers/postgre/postgre_result.php */
\ No newline at end of file
diff --git a/database/drivers/postgre/postgre_utility.php b/database/drivers/postgre/postgre_utility.php
new file mode 100644 (file)
index 0000000..f9b0f22
--- /dev/null
@@ -0,0 +1,124 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Postgre Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_postgre_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               return "SELECT datname FROM pg_database";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Is table optimization supported in Postgre?\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Are table repairs supported in Postgre?\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Postgre Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database($name)\r
+       {\r
+               return "CREATE DATABASE ".$name;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               return "DROP DATABASE ".$name;\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+/* End of file postgre_utility.php */\r
+/* Location: ./system/database/drivers/postgre/postgre_utility.php */
\ No newline at end of file
diff --git a/database/drivers/sqlite/index.html b/database/drivers/sqlite/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/database/drivers/sqlite/sqlite_driver.php b/database/drivers/sqlite/sqlite_driver.php
new file mode 100644 (file)
index 0000000..0ba483f
--- /dev/null
@@ -0,0 +1,601 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+\r
+\r
+/**\r
+ * SQLite Database Adapter Class\r
+ *\r
+ * Note: _DB is an extender class that the app controller\r
+ * creates dynamically based on whether the active record\r
+ * class is being used or not.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Drivers\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_sqlite_driver extends CI_DB {\r
+\r
+       var $dbdriver = 'sqlite';\r
+       \r
+       // The character used to escape with - not needed for SQLite\r
+       var $_escape_char = '';\r
+\r
+       /**\r
+        * The syntax to count rows is slightly different across different\r
+        * database engines, so this string appears in each driver and is\r
+        * used for the count_all() and count_all_results() functions.\r
+        */\r
+       var $_count_string = "SELECT COUNT(*) AS ";\r
+       var $_random_keyword = ' Random()'; // database specific random keyword\r
+\r
+       /**\r
+        * Non-persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_connect()\r
+       {\r
+               if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))\r
+               {\r
+                       log_message('error', $error);\r
+                       \r
+                       if ($this->db_debug)\r
+                       {\r
+                               $this->display_error($error, '', TRUE);\r
+                       }\r
+                       \r
+                       return FALSE;\r
+               }\r
+               \r
+               return $conn_id;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Persistent database connection\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_pconnect()\r
+       {\r
+               if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))\r
+               {\r
+                       log_message('error', $error);\r
+                       \r
+                       if ($this->db_debug)\r
+                       {\r
+                               $this->display_error($error, '', TRUE);\r
+                       }\r
+                       \r
+                       return FALSE;\r
+               }\r
+               \r
+               return $conn_id;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Select the database\r
+        *\r
+        * @access      private called by the base class\r
+        * @return      resource\r
+        */     \r
+       function db_select()\r
+       {\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set client character set\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      resource\r
+        */\r
+       function db_set_charset($charset, $collation)\r
+       {\r
+               // @todo - add support if needed\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Version number query string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _version()\r
+       {\r
+               return sqlite_libversion();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Execute the query\r
+        *\r
+        * @access      private called by the base class\r
+        * @param       string  an SQL query\r
+        * @return      resource\r
+        */     \r
+       function _execute($sql)\r
+       {\r
+               $sql = $this->_prep_query($sql);\r
+               return @sqlite_query($this->conn_id, $sql);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Prep the query\r
+        *\r
+        * If needed, each database adapter can prep the query string\r
+        *\r
+        * @access      private called by execute()\r
+        * @param       string  an SQL query\r
+        * @return      string\r
+        */     \r
+       function _prep_query($sql)\r
+       {\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Begin Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_begin($test_mode = FALSE)\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Reset the transaction failure flag.\r
+               // If the $test_mode flag is set to TRUE transactions will be rolled back\r
+               // even if the queries produce a successful result.\r
+               $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
+\r
+               $this->simple_query('BEGIN TRANSACTION');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Commit Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_commit()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('COMMIT');\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rollback Transaction\r
+        *\r
+        * @access      public\r
+        * @return      bool            \r
+        */     \r
+       function trans_rollback()\r
+       {\r
+               if ( ! $this->trans_enabled)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // When transactions are nested we only begin/commit/rollback the outermost ones\r
+               if ($this->_trans_depth > 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               $this->simple_query('ROLLBACK');\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape String\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function escape_str($str)       \r
+       {\r
+               return sqlite_escape_string($str);\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Affected Rows\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function affected_rows()\r
+       {\r
+               return sqlite_changes($this->conn_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Insert ID\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function insert_id()\r
+       {\r
+               return @sqlite_last_insert_rowid($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * "Count All" query\r
+        *\r
+        * Generates a platform-specific query string that counts all records in\r
+        * the specified database\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function count_all($table = '')\r
+       {\r
+               if ($table == '')\r
+                       return '0';\r
+       \r
+               $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
+               \r
+               if ($query->num_rows() == 0)\r
+                       return '0';\r
+\r
+               $row = $query->row();\r
+               return $row->numrows;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * List table query\r
+        *\r
+        * Generates a platform-specific query string so that the table names can be fetched\r
+        *\r
+        * @access      private\r
+        * @param       boolean\r
+        * @return      string\r
+        */\r
+       function _list_tables($prefix_limit = FALSE)\r
+       {\r
+               $sql = "SELECT name from sqlite_master WHERE type='table'";\r
+\r
+               if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
+               {\r
+                       $sql .= " AND 'name' LIKE '".$this->dbprefix."%'";\r
+               }\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Show column query\r
+        *\r
+        * Generates a platform-specific query string so that the column names can be fetched\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */\r
+       function _list_columns($table = '')\r
+       {\r
+               // Not supported\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data query\r
+        *\r
+        * Generates a platform-specific query so that the column data can be retrieved\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _field_data($table)\r
+       {\r
+               return "SELECT * FROM ".$table." LIMIT 1";\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _error_message()\r
+       {\r
+               return sqlite_error_string(sqlite_last_error($this->conn_id));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * The error message number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */\r
+       function _error_number()\r
+       {\r
+               return sqlite_last_error($this->conn_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Escape the SQL Identifiers\r
+        *\r
+        * This function escapes column and table names\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _escape_identifiers($item)\r
+       {\r
+               if ($this->_escape_char == '')\r
+               {\r
+                       return $item;\r
+               }\r
+       \r
+               if (strpos($item, '.') !== FALSE)\r
+               {\r
+                       $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
+               }\r
+               else\r
+               {\r
+                       $str = $this->_escape_char.$item.$this->_escape_char;\r
+               }\r
+               \r
+               // remove duplicates if the user already included the escape\r
+               return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * From Tables\r
+        *\r
+        * This function implicitly groups FROM tables so there is no confusion\r
+        * about operator precedence in harmony with SQL standards\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _from_tables($tables)\r
+       {\r
+               if ( ! is_array($tables))\r
+               {\r
+                       $tables = array($tables);\r
+               }\r
+               \r
+               return '('.implode(', ', $tables).')';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert statement\r
+        *\r
+        * Generates a platform-specific insert string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the insert keys\r
+        * @param       array   the insert values\r
+        * @return      string\r
+        */\r
+       function _insert($table, $keys, $values)\r
+       {       \r
+               return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Update statement\r
+        *\r
+        * Generates a platform-specific update string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the update data\r
+        * @param       array   the where clause\r
+        * @param       array   the orderby clause\r
+        * @param       array   the limit clause\r
+        * @return      string\r
+        */\r
+       function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
+       {\r
+               foreach($values as $key => $val)\r
+               {\r
+                       $valstr[] = $key." = ".$val;\r
+               }\r
+               \r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+               \r
+               $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
+       \r
+               $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
+\r
+               $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
+\r
+               $sql .= $orderby.$limit;\r
+               \r
+               return $sql;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Truncate statement\r
+        *\r
+        * Generates a platform-specific truncate string from the supplied data\r
+        * If the database does not support the truncate() command\r
+        * This function maps to "DELETE FROM table"\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @return      string\r
+        */     \r
+       function _truncate($table)\r
+       {\r
+               return $this->_delete($table);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete statement\r
+        *\r
+        * Generates a platform-specific delete string from the supplied data\r
+        *\r
+        * @access      public\r
+        * @param       string  the table name\r
+        * @param       array   the where clause\r
+        * @param       string  the limit clause\r
+        * @return      string\r
+        */     \r
+       function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
+       {\r
+               $conditions = '';\r
+\r
+               if (count($where) > 0 OR count($like) > 0)\r
+               {\r
+                       $conditions = "\nWHERE ";\r
+                       $conditions .= implode("\n", $this->ar_where);\r
+\r
+                       if (count($where) > 0 && count($like) > 0)\r
+                       {\r
+                               $conditions .= " AND ";\r
+                       }\r
+                       $conditions .= implode("\n", $like);\r
+               }\r
+\r
+               $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
+       \r
+               return "DELETE FROM ".$table.$conditions.$limit;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Limit string\r
+        *\r
+        * Generates a platform-specific LIMIT clause\r
+        *\r
+        * @access      public\r
+        * @param       string  the sql query string\r
+        * @param       integer the number of rows to limit the query to\r
+        * @param       integer the offset value\r
+        * @return      string\r
+        */\r
+       function _limit($sql, $limit, $offset)\r
+       {       \r
+               if ($offset == 0)\r
+               {\r
+                       $offset = '';\r
+               }\r
+               else\r
+               {\r
+                       $offset .= ", ";\r
+               }\r
+               \r
+               return $sql."LIMIT ".$offset.$limit;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Close DB Connection\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */\r
+       function _close($conn_id)\r
+       {\r
+               @sqlite_close($conn_id);\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+/* End of file sqlite_driver.php */\r
+/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
\ No newline at end of file
diff --git a/database/drivers/sqlite/sqlite_forge.php b/database/drivers/sqlite/sqlite_forge.php
new file mode 100644 (file)
index 0000000..2039525
--- /dev/null
@@ -0,0 +1,265 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * SQLite Forge Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_sqlite_forge extends CI_DB_forge {\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database()\r
+       {\r
+               // In SQLite, a database is created when you connect to the database.\r
+               // We'll return TRUE so that an error isn't generated\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))\r
+               {\r
+                       if ($this->db->db_debug)\r
+                       {\r
+                               return $this->db->display_error('db_unable_to_drop');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               return TRUE;\r
+       }\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create Table\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @param       array   the fields\r
+        * @param       mixed   primary key(s)\r
+        * @param       mixed   key(s)\r
+        * @param       boolean should 'IF NOT EXISTS' be added to the SQL\r
+        * @return      bool\r
+        */\r
+       function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)\r
+       {\r
+               $sql = 'CREATE TABLE ';\r
+               \r
+               // IF NOT EXISTS added to SQLite in 3.3.0\r
+               if ($if_not_exists === TRUE && version_compare($this->_version(), '3.3.0', '>=') === TRUE)\r
+               {\r
+                       $sql .= 'IF NOT EXISTS ';\r
+               }\r
+               \r
+               $sql .= $this->db->_escape_identifiers($table)."(";\r
+               $current_field_count = 0;\r
+\r
+               foreach ($fields as $field=>$attributes)\r
+               {\r
+                       // Numeric field names aren't allowed in databases, so if the key is\r
+                       // numeric, we know it was assigned by PHP and the developer manually\r
+                       // entered the field information, so we'll simply add it to the list\r
+                       if (is_numeric($field))\r
+                       {\r
+                               $sql .= "\n\t$attributes";\r
+                       }\r
+                       else\r
+                       {\r
+                               $attributes = array_change_key_case($attributes, CASE_UPPER);\r
+                               \r
+                               $sql .= "\n\t".$this->db->_protect_identifiers($field);\r
+                               \r
+                               $sql .=  ' '.$attributes['TYPE'];\r
+       \r
+                               if (array_key_exists('CONSTRAINT', $attributes))\r
+                               {\r
+                                       $sql .= '('.$attributes['CONSTRAINT'].')';\r
+                               }\r
+       \r
+                               if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)\r
+                               {\r
+                                       $sql .= ' UNSIGNED';\r
+                               }\r
+       \r
+                               if (array_key_exists('DEFAULT', $attributes))\r
+                               {\r
+                                       $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';\r
+                               }\r
+       \r
+                               if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)\r
+                               {\r
+                                       $sql .= ' NULL';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $sql .= ' NOT NULL';                    \r
+                               }\r
+       \r
+                               if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)\r
+                               {\r
+                                       $sql .= ' AUTO_INCREMENT';\r
+                               }\r
+                       }\r
+                       \r
+                       // don't add a comma on the end of the last field\r
+                       if (++$current_field_count < count($fields))\r
+                       {\r
+                               $sql .= ',';\r
+                       }\r
+               }\r
+\r
+               if (count($primary_keys) > 0)\r
+               {\r
+                       $primary_keys = $this->db->_protect_identifiers($primary_keys);\r
+                       $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";\r
+               }\r
+\r
+               if (is_array($keys) && count($keys) > 0)\r
+               {\r
+                       foreach ($keys as $key)\r
+                       {\r
+                               if (is_array($key))\r
+                               {\r
+                                       $key = $this->db->_protect_identifiers($key);   \r
+                               }\r
+                               else\r
+                               {\r
+                                       $key = array($this->db->_protect_identifiers($key));\r
+                               }\r
+                               \r
+                               $sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";\r
+                       }\r
+               }\r
+\r
+               $sql .= "\n)";\r
+\r
+               return $sql;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop Table\r
+        *\r
+        *  Unsupported feature in SQLite\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _drop_table($table)\r
+       {\r
+               if ($this->db->db_debug)\r
+               {\r
+                       return $this->db->display_error('db_unsuported_feature');\r
+               }\r
+               return array();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Alter table query\r
+        *\r
+        * Generates a platform-specific query so that a table can be altered\r
+        * Called by add_column(), drop_column(), and column_alter(),\r
+        *\r
+        * @access      private\r
+        * @param       string  the ALTER type (ADD, DROP, CHANGE)\r
+        * @param       string  the column name\r
+        * @param       string  the table name\r
+        * @param       string  the column definition\r
+        * @param       string  the default value\r
+        * @param       boolean should 'NOT NULL' be added\r
+        * @param       string  the field after which we should add the new field\r
+        * @return      object\r
+        */\r
+       function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);\r
+\r
+               // DROP has everything it needs now.\r
+               if ($alter_type == 'DROP')\r
+               {\r
+                       // SQLite does not support dropping columns\r
+                       // http://www.sqlite.org/omitted.html\r
+                       // http://www.sqlite.org/faq.html#q11\r
+                       return FALSE;\r
+               }\r
+\r
+               $sql .= " $column_definition";\r
+\r
+               if ($default_value != '')\r
+               {\r
+                       $sql .= " DEFAULT \"$default_value\"";\r
+               }\r
+\r
+               if ($null === NULL)\r
+               {\r
+                       $sql .= ' NULL';\r
+               }\r
+               else\r
+               {\r
+                       $sql .= ' NOT NULL';\r
+               }\r
+\r
+               if ($after_field != '')\r
+               {\r
+                       $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);\r
+               }\r
+               \r
+               return $sql;\r
+               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename a table\r
+        *\r
+        * Generates a platform-specific query so that a table can be renamed\r
+        *\r
+        * @access      private\r
+        * @param       string  the old table name\r
+        * @param       string  the new table name\r
+        * @return      string\r
+        */\r
+       function _rename_table($table_name, $new_table_name)\r
+       {\r
+               $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);\r
+               return $sql;\r
+       }\r
+}\r
+\r
+/* End of file sqlite_forge.php */\r
+/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
\ No newline at end of file
diff --git a/database/drivers/sqlite/sqlite_result.php b/database/drivers/sqlite/sqlite_result.php
new file mode 100644 (file)
index 0000000..735a073
--- /dev/null
@@ -0,0 +1,179 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * SQLite Result Class\r
+ *\r
+ * This class extends the parent result class: CI_DB_result\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_sqlite_result extends CI_DB_result {\r
+       \r
+       /**\r
+        * Number of rows in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_rows()\r
+       {\r
+               return @sqlite_num_rows($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Number of fields in the result set\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function num_fields()\r
+       {\r
+               return @sqlite_num_fields($this->result_id);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch Field Names\r
+        *\r
+        * Generates an array of column names\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function list_fields()\r
+       {\r
+               $field_names = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $field_names[] = sqlite_field_name($this->result_id, $i);\r
+               }\r
+               \r
+               return $field_names;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Field data\r
+        *\r
+        * Generates an array of objects containing field meta-data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function field_data()\r
+       {\r
+               $retval = array();\r
+               for ($i = 0; $i < $this->num_fields(); $i++)\r
+               {\r
+                       $F                              = new stdClass();\r
+                       $F->name                = sqlite_field_name($this->result_id, $i);\r
+                       $F->type                = 'varchar';\r
+                       $F->max_length  = 0;\r
+                       $F->primary_key = 0;\r
+                       $F->default             = '';\r
+\r
+                       $retval[] = $F;\r
+               }\r
+               \r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Free the result\r
+        *\r
+        * @return      null\r
+        */             \r
+       function free_result()\r
+       {\r
+               // Not implemented in SQLite\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Data Seek\r
+        *\r
+        * Moves the internal pointer to the desired offset.  We call\r
+        * this internally before fetching results to make sure the\r
+        * result set starts at zero\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _data_seek($n = 0)\r
+       {\r
+               return sqlite_seek($this->result_id, $n);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - associative array\r
+        *\r
+        * Returns the result set as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _fetch_assoc()\r
+       {\r
+               return sqlite_fetch_array($this->result_id);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Result - object\r
+        *\r
+        * Returns the result set as an object\r
+        *\r
+        * @access      private\r
+        * @return      object\r
+        */\r
+       function _fetch_object()\r
+       {\r
+               if (function_exists('sqlite_fetch_object'))\r
+               {\r
+                       return sqlite_fetch_object($this->result_id);\r
+               }\r
+               else\r
+               {\r
+                       $arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);\r
+                       if (is_array($arr))\r
+                       {\r
+                               $obj = (object) $arr;\r
+                               return $obj;\r
+                       } else {\r
+                               return NULL;\r
+                       } \r
+               }\r
+       }\r
+\r
+}\r
+\r
+\r
+/* End of file sqlite_result.php */\r
+/* Location: ./system/database/drivers/sqlite/sqlite_result.php */
\ No newline at end of file
diff --git a/database/drivers/sqlite/sqlite_utility.php b/database/drivers/sqlite/sqlite_utility.php
new file mode 100644 (file)
index 0000000..3527b5b
--- /dev/null
@@ -0,0 +1,141 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * SQLite Utility Class\r
+ *\r
+ * @category   Database\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/database/\r
+ */\r
+class CI_DB_sqlite_utility extends CI_DB_utility {\r
+\r
+       /**\r
+        * List databases\r
+        *\r
+        * I don't believe you can do a database listing with SQLite\r
+        * since each database is its own file.  I suppose we could\r
+        * try reading a directory looking for SQLite files, but\r
+        * that doesn't seem like a terribly good idea\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _list_databases()\r
+       {\r
+               if ($this->db_debug)\r
+               {\r
+                       return $this->display_error('db_unsuported_feature');\r
+               }\r
+               return array();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Optimize table query\r
+        *\r
+        * Is optimization even supported in SQLite?\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _optimize_table($table)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Repair table query\r
+        *\r
+        * Are table repairs even supported in SQLite?\r
+        *\r
+        * @access      private\r
+        * @param       string  the table name\r
+        * @return      object\r
+        */\r
+       function _repair_table($table)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * SQLite Export\r
+        *\r
+        * @access      private\r
+        * @param       array   Preferences\r
+        * @return      mixed\r
+        */\r
+       function _backup($params = array())\r
+       {\r
+               // Currently unsupported\r
+               return $this->db->display_error('db_unsuported_feature');\r
+       }\r
+\r
+       /**\r
+        *\r
+        * The functions below have been deprecated as of 1.6, and are only here for backwards\r
+        * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation\r
+        * is STRONGLY discouraged in favour if using dbforge.\r
+        *\r
+        */\r
+\r
+       /**\r
+        * Create database\r
+        *\r
+        * @access      public\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _create_database()\r
+       {\r
+               // In SQLite, a database is created when you connect to the database.\r
+               // We'll return TRUE so that an error isn't generated\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Drop database\r
+        *\r
+        * @access      private\r
+        * @param       string  the database name\r
+        * @return      bool\r
+        */\r
+       function _drop_database($name)\r
+       {\r
+               if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))\r
+               {\r
+                       if ($this->db->db_debug)\r
+                       {\r
+                               return $this->db->display_error('db_unable_to_drop');\r
+                       }\r
+                       return FALSE;\r
+               }\r
+               return TRUE;\r
+       }\r
+\r
+}\r
+\r
+/* End of file sqlite_utility.php */\r
+/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
\ No newline at end of file
diff --git a/database/index.html b/database/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/fonts/index.html b/fonts/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/fonts/texb.ttf b/fonts/texb.ttf
new file mode 100644 (file)
index 0000000..a7aa646
Binary files /dev/null and b/fonts/texb.ttf differ
diff --git a/helpers/array_helper.php b/helpers/array_helper.php
new file mode 100644 (file)
index 0000000..4c8323b
--- /dev/null
@@ -0,0 +1,78 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Array Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/array_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Element\r
+ *\r
+ * Lets you determine whether an array index is set and whether it has a value.\r
+ * If the element is empty it returns FALSE (or whatever you specify as the default value.)\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      array\r
+ * @param      mixed\r
+ * @return     mixed   depends on what the array contains\r
+ */    \r
+if ( ! function_exists('element'))\r
+{\r
+       function element($item, $array, $default = FALSE)\r
+       {\r
+               if ( ! isset($array[$item]) OR $array[$item] == "")\r
+               {\r
+                       return $default;\r
+               }\r
+\r
+               return $array[$item];\r
+       }       \r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Random Element - Takes an array as input and returns a random element\r
+ *\r
+ * @access     public\r
+ * @param      array\r
+ * @return     mixed   depends on what the array contains\r
+ */    \r
+if ( ! function_exists('random_element'))\r
+{\r
+       function random_element($array)\r
+       {\r
+               if ( ! is_array($array))\r
+               {\r
+                       return $array;\r
+               }\r
+               return $array[array_rand($array)];\r
+       }       \r
+}\r
+\r
+\r
+/* End of file array_helper.php */\r
+/* Location: ./system/helpers/array_helper.php */
\ No newline at end of file
diff --git a/helpers/compatibility_helper.php b/helpers/compatibility_helper.php
new file mode 100644 (file)
index 0000000..3b37cea
--- /dev/null
@@ -0,0 +1,498 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package            CodeIgniter
+ * @author             ExpressionEngine Dev Team
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.
+ * @license            http://codeigniter.com/user_guide/license.html
+ * @link               http://codeigniter.com
+ * @since              Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Compatibility Helpers
+ *
+ * This helper contains some functions based on the PEAR PHP_Compat library
+ * http://pear.php.net/package/PHP_Compat
+ * 
+ * The PEAR compat library is a little bloated and the code doesn't harmonize
+ * well with CodeIgniter, so those functions have been refactored.
+ * We cheat a little and use CI's _exception_handler() to output our own PHP errors
+ * so that the behavior fully mimicks the PHP 5 counterparts.  -- Derek Jones
+ * 
+ * @package            CodeIgniter
+ * @subpackage Helpers
+ * @category   Helpers
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/helpers/compatibility_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+if ( ! defined('PHP_EOL'))
+{
+       define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
+} 
+
+// ------------------------------------------------------------------------
+
+/**
+ * file_put_contents()
+ *
+ * Writes a string to a file
+ * http://us.php.net/manual/en/function.file_put_contents.php
+ * argument 4, $context, not supported
+ *
+ * @access     public
+ * @param      string          file name
+ * @param      mixed           data to be written
+ * @param      int                     flags
+ * @return     int                     length of written string
+ */
+if ( ! function_exists('file_put_contents'))
+{
+       function file_put_contents($filename, $data, $flags = NULL)
+       {
+               if (is_scalar($data))
+               {
+                       settype($data, 'STRING');
+               }
+
+               if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+
+               // read stream if given a stream resource
+               if (is_resource($data))
+               {
+                       if (get_resource_type($data) !== 'stream')
+                       {
+                               $backtrace = debug_backtrace();
+                               _exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
+                               return FALSE;
+                       }
+
+                       $text = '';
+                       
+                       while ( ! feof($data))
+                       {
+                               $text .= fread($data, 4096);
+                       }
+                       
+                       $data = $text;
+                       unset($text);
+               }
+       
+               // strings only please!
+               if (is_array($data))
+               {
+                       $data = implode('', $data);
+               }
+
+               // Set the appropriate mode
+               if (($flags & 8) > 0) // 8 = FILE_APPEND flag
+               {
+                       $mode = FOPEN_WRITE_CREATE;
+               }
+               else
+               {
+                       $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
+               }
+       
+               // Check if we're using the include path
+               if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
+               {
+                       $use_include_path = TRUE;
+               }
+               else
+               {
+                       $use_include_path = FALSE;
+               }
+       
+               $fp = @fopen($filename, $mode, $use_include_path);
+       
+               if ($fp === FALSE)
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               if (($flags & LOCK_EX) > 0)
+               {
+                       if ( ! flock($fp, LOCK_EX))
+                       {
+                               $backtrace = debug_backtrace();
+                               _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
+                               return FALSE;
+                       }
+               }
+               
+               // write it
+               if (($written = @fwrite($fp, $data)) === FALSE)
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
+               }
+       
+               // Close the handle
+               @fclose($fp);
+       
+               // Return length
+               return $written;
+       }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * fputcsv()
+ *
+ * Format line as CSV and write to file pointer
+ * http://us.php.net/manual/en/function.fputcsv.php
+ *
+ * @access     public
+ * @param      resource        file pointer
+ * @param      array           data to be written
+ * @param      string          delimiter
+ * @param      string          enclosure
+ * @return     int                     length of written string
+ */
+if ( ! function_exists('fputcsv'))
+{
+       function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
+       {
+               // Checking for a handle resource
+               if ( ! is_resource($handle))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               // OK, it is a resource, but is it a stream?
+               if (get_resource_type($handle) !== 'stream')
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               // Checking for an array of fields
+               if ( ! is_array($fields))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               // validate delimiter
+               if (strlen($delimiter) > 1)
+               {
+                       $delimiter = substr($delimiter, 0, 1);
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+               }
+       
+               // validate enclosure
+               if (strlen($enclosure) > 1)
+               {
+                       $enclosure = substr($enclosure, 0, 1);
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+
+               }
+       
+               $out = '';
+       
+               foreach ($fields as $cell)
+               {
+                       $cell = str_replace($enclosure, $enclosure.$enclosure, $cell);
+
+                       if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)
+                       {
+                               $out .= $enclosure.$cell.$enclosure.$delimiter;
+                       }
+                       else
+                       {
+                               $out .= $cell.$delimiter;
+                       }
+               }
+       
+               $length = @fwrite($handle, substr($out, 0, -1)."\n");
+       
+               return $length;
+       }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * stripos()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.stripos.php
+ *
+ * @access     public
+ * @param      string          haystack
+ * @param      string          needle
+ * @param      int                     offset
+ * @return     int                     numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('stripos'))
+{
+       function stripos($haystack, $needle, $offset = NULL)
+       {
+               // Cast non string scalar values
+               if (is_scalar($haystack))
+               {
+                       settype($haystack, 'STRING');
+               }
+       
+               if ( ! is_string($haystack))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               if ( ! is_scalar($needle))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               if (is_float($offset))
+               {
+                       $offset = (int)$offset;
+               }
+       
+               if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return NULL;
+               }
+       
+               return strpos(strtolower($haystack), strtolower($needle), $offset);
+       }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * str_ireplace()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.str-ireplace.php
+ * (parameter 4, $count, is not supported as to do so in PHP 4 would make
+ * it a required parameter)
+ *
+ * @access     public
+ * @param      mixed           search
+ * @param      mixed           replace
+ * @param      mixed           subject
+ * @return     int                     numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('str_ireplace'))
+{
+       function str_ireplace($search, $replace, $subject)
+       {
+               // Nothing to do here
+               if ($search === NULL OR $subject === NULL)
+               {
+                       return $subject;
+               }
+       
+               // Crazy arguments
+               if (is_scalar($search) && is_array($replace))
+               {
+                       $backtrace = debug_backtrace();
+
+                       if (is_object($replace))
+                       {
+                               show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
+                       }
+                       else
+                       {
+                               _exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
+                       }
+               }
+       
+               // Searching for an array
+               if (is_array($search))
+               {
+                       // Replacing with an array
+                       if (is_array($replace))
+                       {
+                               $search = array_values($search);
+                               $replace = array_values($replace);
+
+                               if (count($search) >= count($replace))
+                               {
+                                       $replace = array_pad($replace, count($search), '');
+                               }
+                               else
+                               {
+                                       $replace = array_slice($replace, 0, count($search));
+                               }
+                       }
+                       else
+                       {
+                               // Replacing with a string all positions
+                               $replace = array_fill(0, count($search), $replace);
+                       }
+               }
+               else
+               {
+                       //Searching for a string and replacing with a string.
+                       $search  = array((string)$search);
+                       $replace = array((string)$replace);
+               }
+               
+               // Prepare the search array
+               foreach ($search as $search_key => $search_value)
+               {
+                       $search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
+               }
+               
+               // Prepare the replace array (escape backreferences)
+               foreach ($replace as $k => $v)
+               {
+                       $replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
+               }
+       
+               // do the replacement
+               $result = preg_replace($search, $replace, (array)$subject);
+       
+               // Check if subject was initially a string and return it as a string
+               if ( ! is_array($subject))
+               {
+                       return current($result);
+               }
+       
+               // Otherwise, just return the array
+               return $result;
+       }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * http_build_query()
+ *
+ * Generate URL-encoded query string
+ * http://us.php.net/manual/en/function.http-build-query.php
+ *
+ * @access     public
+ * @param      array           form data
+ * @param      string          numeric prefix
+ * @param      string          argument separator
+ * @return     string          URL-encoded string
+ */
+if ( ! function_exists('http_build_query'))
+{
+       function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
+       {
+               // Check the data
+               if ( ! is_array($formdata) && ! is_object($formdata))
+               {
+                       $backtrace = debug_backtrace();
+                       _exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
+                       return FALSE;
+               }
+       
+               // Cast it as array
+               if (is_object($formdata))
+               {
+                       $formdata = get_object_vars($formdata);
+               }
+       
+               // If the array is empty, return NULL
+               if (empty($formdata))
+               {
+                       return NULL;
+               }
+       
+               // Argument separator
+               if ($separator === NULL)
+               {
+                       $separator = ini_get('arg_separator.output');
+
+                       if (strlen($separator) == 0)
+                       {
+                               $separator = '&';
+                       }
+               }
+       
+               // Start building the query
+               $tmp = array();
+
+               foreach ($formdata as $key => $val)
+               {
+                       if ($val === NULL)
+                       {
+                               continue;
+                       }
+       
+                       if (is_integer($key) && $numeric_prefix != NULL)
+                       {
+                               $key = $numeric_prefix.$key;
+                       }
+       
+                       if (is_resource($val))
+                       {
+                               return NULL;
+                       }
+                       
+                       // hand it off to a recursive parser
+                       $tmp[] = _http_build_query_helper($key, $val, $separator);
+               }
+       
+               return implode($separator, $tmp);
+       }
+       
+       
+       // Helper helper.  Remind anyone of college?
+       // Required to handle recursion in nested arrays.
+       // 
+       // You could shave fractions of fractions of a second by moving where
+       // the urlencoding takes place, but it's much less intuitive, and if
+       // your application has 10,000 form fields, well, you have other problems ;)
+       function _http_build_query_helper($key, $val, $separator = '&')
+       {       
+               if (is_scalar($val))
+               {
+                       return urlencode($key).'='.urlencode($val);                     
+               }
+               else
+               {
+                       // arrays please
+                       if (is_object($val))
+                       {
+                               $val = get_object_vars($val);
+                       }
+                       
+                       foreach ($val as $k => $v)
+                       {
+                               $tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
+                       }
+               }
+                       
+               return implode($separator, $tmp);
+       }
+}
+
+
+/* End of file compatibility_helper.php */
+/* Location: ./system/helpers/compatibility_helper.php */
\ No newline at end of file
diff --git a/helpers/cookie_helper.php b/helpers/cookie_helper.php
new file mode 100644 (file)
index 0000000..61561b7
--- /dev/null
@@ -0,0 +1,136 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Cookie Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/cookie_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Set cookie\r
+ *\r
+ * Accepts six parameter, or you can submit an associative\r
+ * array in the first parameter containing all the values.\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string  the value of the cookie\r
+ * @param      string  the number of seconds until expiration\r
+ * @param      string  the cookie domain.  Usually:  .yourdomain.com\r
+ * @param      string  the cookie path\r
+ * @param      string  the cookie prefix\r
+ * @return     void\r
+ */\r
+if ( ! function_exists('set_cookie'))\r
+{\r
+       function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')\r
+       {\r
+               if (is_array($name))\r
+               {               \r
+                       foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'name') as $item)\r
+                       {\r
+                               if (isset($name[$item]))\r
+                               {\r
+                                       $$item = $name[$item];\r
+                               }\r
+                       }\r
+               }\r
+       \r
+               // Set the config file options\r
+               $CI =& get_instance();\r
+       \r
+               if ($prefix == '' AND $CI->config->item('cookie_prefix') != '')\r
+               {\r
+                       $prefix = $CI->config->item('cookie_prefix');\r
+               }\r
+               if ($domain == '' AND $CI->config->item('cookie_domain') != '')\r
+               {\r
+                       $domain = $CI->config->item('cookie_domain');\r
+               }\r
+               if ($path == '/' AND $CI->config->item('cookie_path') != '/')\r
+               {\r
+                       $path = $CI->config->item('cookie_path');\r
+               }\r
+               \r
+               if ( ! is_numeric($expire))\r
+               {\r
+                       $expire = time() - 86500;\r
+               }\r
+               else\r
+               {\r
+                       if ($expire > 0)\r
+                       {\r
+                               $expire = time() + $expire;\r
+                       }\r
+                       else\r
+                       {\r
+                               $expire = 0;\r
+                       }\r
+               }\r
+       \r
+               setcookie($prefix.$name, $value, $expire, $path, $domain, 0);\r
+       }\r
+}\r
+       \r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Fetch an item from the COOKIE array\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     mixed\r
+ */\r
+if ( ! function_exists('get_cookie'))\r
+{\r
+       function get_cookie($index = '', $xss_clean = FALSE)\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->input->cookie($index, $xss_clean);\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Delete a COOKIE\r
+ *\r
+ * @param      mixed\r
+ * @param      string  the cookie domain.  Usually:  .yourdomain.com\r
+ * @param      string  the cookie path\r
+ * @param      string  the cookie prefix\r
+ * @return     void\r
+ */\r
+if ( ! function_exists('delete_cookie'))\r
+{\r
+       function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')\r
+       {\r
+               set_cookie($name, '', '', $domain, $path, $prefix);\r
+       }\r
+}\r
+\r
+\r
+/* End of file cookie_helper.php */\r
+/* Location: ./system/helpers/cookie_helper.php */
\ No newline at end of file
diff --git a/helpers/date_helper.php b/helpers/date_helper.php
new file mode 100644 (file)
index 0000000..c9c8968
--- /dev/null
@@ -0,0 +1,611 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Date Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/date_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Get "now" time\r
+ *\r
+ * Returns time() or its GMT equivalent based on the config file preference\r
+ *\r
+ * @access     public\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('now'))\r
+{\r
+       function now()\r
+       {\r
+               $CI =& get_instance();\r
+       \r
+               if (strtolower($CI->config->item('time_reference')) == 'gmt')\r
+               {\r
+                       $now = time();\r
+                       $system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));\r
+       \r
+                       if (strlen($system_time) < 10)\r
+                       {\r
+                               $system_time = time();\r
+                               log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.');\r
+                       }\r
+       \r
+                       return $system_time;\r
+               }\r
+               else\r
+               {\r
+                       return time();\r
+               }\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Convert MySQL Style Datecodes\r
+ *\r
+ * This function is identical to PHPs date() function,\r
+ * except that it allows date codes to be formatted using\r
+ * the MySQL style, where each code letter is preceded\r
+ * with a percent sign:  %Y %m %d etc...\r
+ *\r
+ * The benefit of doing dates this way is that you don't\r
+ * have to worry about escaping your text letters that\r
+ * match the date codes.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      integer\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('mdate'))\r
+{\r
+       function mdate($datestr = '', $time = '')\r
+       {\r
+               if ($datestr == '')\r
+                       return '';\r
+       \r
+               if ($time == '')\r
+                       $time = now();\r
+               \r
+               $datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));\r
+               return date($datestr, $time);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Standard Date\r
+ *\r
+ * Returns a date formatted according to the submitted standard.\r
+ *\r
+ * @access     public\r
+ * @param      string  the chosen format\r
+ * @param      integer Unix timestamp\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('standard_date'))\r
+{\r
+       function standard_date($fmt = 'DATE_RFC822', $time = '')\r
+       {\r
+               $formats = array(\r
+                                               'DATE_ATOM'             =>      '%Y-%m-%dT%H:%i:%s%Q',\r
+                                               'DATE_COOKIE'   =>      '%l, %d-%M-%y %H:%i:%s UTC',\r
+                                               'DATE_ISO8601'  =>      '%Y-%m-%dT%H:%i:%s%O',\r
+                                               'DATE_RFC822'   =>      '%D, %d %M %y %H:%i:%s %O',\r
+                                               'DATE_RFC850'   =>      '%l, %d-%M-%y %H:%m:%i UTC',\r
+                                               'DATE_RFC1036'  =>      '%D, %d %M %y %H:%i:%s %O',\r
+                                               'DATE_RFC1123'  =>      '%D, %d %M %Y %H:%i:%s %O',\r
+                                               'DATE_RSS'              =>      '%D, %d %M %Y %H:%i:%s %O',\r
+                                               'DATE_W3C'              =>      '%Y-%m-%dT%H:%i:%s%Q'\r
+                                               );\r
+\r
+               if ( ! isset($formats[$fmt]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               return mdate($formats[$fmt], $time);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Timespan\r
+ *\r
+ * Returns a span of seconds in this format:\r
+ *     10 days 14 hours 36 minutes 47 seconds\r
+ *\r
+ * @access     public\r
+ * @param      integer a number of seconds\r
+ * @param      integer Unix timestamp\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('timespan'))\r
+{\r
+       function timespan($seconds = 1, $time = '')\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('date');\r
+\r
+               if ( ! is_numeric($seconds))\r
+               {\r
+                       $seconds = 1;\r
+               }\r
+       \r
+               if ( ! is_numeric($time))\r
+               {\r
+                       $time = time();\r
+               }\r
+       \r
+               if ($time <= $seconds)\r
+               {\r
+                       $seconds = 1;\r
+               }\r
+               else\r
+               {\r
+                       $seconds = $time - $seconds;\r
+               }\r
+               \r
+               $str = '';\r
+               $years = floor($seconds / 31536000);\r
+       \r
+               if ($years > 0)\r
+               {       \r
+                       $str .= $years.' '.$CI->lang->line((($years     > 1) ? 'date_years' : 'date_year')).', ';\r
+               }       \r
+       \r
+               $seconds -= $years * 31536000;\r
+               $months = floor($seconds / 2628000);\r
+       \r
+               if ($years > 0 OR $months > 0)\r
+               {\r
+                       if ($months > 0)\r
+                       {       \r
+                               $str .= $months.' '.$CI->lang->line((($months   > 1) ? 'date_months' : 'date_month')).', ';\r
+                       }       \r
+       \r
+                       $seconds -= $months * 2628000;\r
+               }\r
+\r
+               $weeks = floor($seconds / 604800);\r
+       \r
+               if ($years > 0 OR $months > 0 OR $weeks > 0)\r
+               {\r
+                       if ($weeks > 0)\r
+                       {       \r
+                               $str .= $weeks.' '.$CI->lang->line((($weeks     > 1) ? 'date_weeks' : 'date_week')).', ';\r
+                       }\r
+               \r
+                       $seconds -= $weeks * 604800;\r
+               }                       \r
+\r
+               $days = floor($seconds / 86400);\r
+       \r
+               if ($months > 0 OR $weeks > 0 OR $days > 0)\r
+               {\r
+                       if ($days > 0)\r
+                       {       \r
+                               $str .= $days.' '.$CI->lang->line((($days       > 1) ? 'date_days' : 'date_day')).', ';\r
+                       }\r
+       \r
+                       $seconds -= $days * 86400;\r
+               }\r
+       \r
+               $hours = floor($seconds / 3600);\r
+       \r
+               if ($days > 0 OR $hours > 0)\r
+               {\r
+                       if ($hours > 0)\r
+                       {\r
+                               $str .= $hours.' '.$CI->lang->line((($hours     > 1) ? 'date_hours' : 'date_hour')).', ';\r
+                       }\r
+               \r
+                       $seconds -= $hours * 3600;\r
+               }\r
+       \r
+               $minutes = floor($seconds / 60);\r
+       \r
+               if ($days > 0 OR $hours > 0 OR $minutes > 0)\r
+               {\r
+                       if ($minutes > 0)\r
+                       {       \r
+                               $str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', ';\r
+                       }\r
+               \r
+                       $seconds -= $minutes * 60;\r
+               }\r
+       \r
+               if ($str == '')\r
+               {\r
+                       $str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', ';\r
+               }\r
+                       \r
+               return substr(trim($str), 0, -1);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Number of days in a month\r
+ *\r
+ * Takes a month/year as input and returns the number of days\r
+ * for the given month/year. Takes leap years into consideration.\r
+ *\r
+ * @access     public\r
+ * @param      integer a numeric month\r
+ * @param      integer a numeric year\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('days_in_month'))\r
+{\r
+       function days_in_month($month = 0, $year = '')\r
+       {\r
+               if ($month < 1 OR $month > 12)\r
+               {\r
+                       return 0;\r
+               }\r
+       \r
+               if ( ! is_numeric($year) OR strlen($year) != 4)\r
+               {\r
+                       $year = date('Y');\r
+               }\r
+       \r
+               if ($month == 2)\r
+               {\r
+                       if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))\r
+                       {\r
+                               return 29;\r
+                       }\r
+               }\r
+\r
+               $days_in_month  = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);\r
+               return $days_in_month[$month - 1];\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Converts a local Unix timestamp to GMT\r
+ *\r
+ * @access     public\r
+ * @param      integer Unix timestamp\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('local_to_gmt'))\r
+{\r
+       function local_to_gmt($time = '')\r
+       {\r
+               if ($time == '')\r
+                       $time = time();\r
+       \r
+               return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time));\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Converts GMT time to a localized value\r
+ *\r
+ * Takes a Unix timestamp (in GMT) as input, and returns\r
+ * at the local value based on the timezone and DST setting\r
+ * submitted\r
+ *\r
+ * @access     public\r
+ * @param      integer Unix timestamp\r
+ * @param      string  timezone\r
+ * @param      bool    whether DST is active\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('gmt_to_local'))\r
+{\r
+       function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)\r
+       {                       \r
+               if ($time == '')\r
+               {\r
+                       return now();\r
+               }\r
+       \r
+               $time += timezones($timezone) * 3600;\r
+\r
+               if ($dst == TRUE)\r
+               {\r
+                       $time += 3600;\r
+               }\r
+       \r
+               return $time;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Converts a MySQL Timestamp to Unix\r
+ *\r
+ * @access     public\r
+ * @param      integer Unix timestamp\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('mysql_to_unix'))\r
+{\r
+       function mysql_to_unix($time = '')\r
+       {\r
+               // We'll remove certain characters for backward compatibility\r
+               // since the formatting changed with MySQL 4.1\r
+               // YYYY-MM-DD HH:MM:SS\r
+       \r
+               $time = str_replace('-', '', $time);\r
+               $time = str_replace(':', '', $time);\r
+               $time = str_replace(' ', '', $time);\r
+       \r
+               // YYYYMMDDHHMMSS\r
+               return  mktime(\r
+                                               substr($time, 8, 2),\r
+                                               substr($time, 10, 2),\r
+                                               substr($time, 12, 2),\r
+                                               substr($time, 4, 2),\r
+                                               substr($time, 6, 2),\r
+                                               substr($time, 0, 4)\r
+                                               );\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Unix to "Human"\r
+ *\r
+ * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM\r
+ *\r
+ * @access     public\r
+ * @param      integer Unix timestamp\r
+ * @param      bool    whether to show seconds\r
+ * @param      string  format: us or euro\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('unix_to_human'))\r
+{\r
+       function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')\r
+       {\r
+               $r  = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';\r
+               \r
+               if ($fmt == 'us')\r
+               {\r
+                       $r .= date('h', $time).':'.date('i', $time);\r
+               }\r
+               else\r
+               {\r
+                       $r .= date('H', $time).':'.date('i', $time);\r
+               }\r
+       \r
+               if ($seconds)\r
+               {\r
+                       $r .= ':'.date('s', $time);\r
+               }\r
+       \r
+               if ($fmt == 'us')\r
+               {\r
+                       $r .= ' '.date('A', $time);\r
+               }\r
+               \r
+               return $r;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Convert "human" date to GMT\r
+ *\r
+ * Reverses the above process\r
+ *\r
+ * @access     public\r
+ * @param      string  format: us or euro\r
+ * @return     integer\r
+ */    \r
+if ( ! function_exists('human_to_unix'))\r
+{\r
+       function human_to_unix($datestr = '')\r
+       {\r
+               if ($datestr == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               $datestr = trim($datestr);\r
+               $datestr = preg_replace("/\040+/", "\040", $datestr);\r
+\r
+               if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $split = preg_split("/\040/", $datestr);\r
+\r
+               $ex = explode("-", $split['0']);\r
+       \r
+               $year  = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];\r
+               $month = (strlen($ex['1']) == 1) ? '0'.$ex['1']  : $ex['1'];\r
+               $day   = (strlen($ex['2']) == 1) ? '0'.$ex['2']  : $ex['2'];\r
+\r
+               $ex = explode(":", $split['1']);\r
+       \r
+               $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];\r
+               $min  = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];\r
+\r
+               if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2']))\r
+               {\r
+                       $sec  = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];\r
+               }\r
+               else\r
+               {\r
+                       // Unless specified, seconds get set to zero.\r
+                       $sec = '00';\r
+               }\r
+       \r
+               if (isset($split['2']))\r
+               {\r
+                       $ampm = strtolower($split['2']);\r
+               \r
+                       if (substr($ampm, 0, 1) == 'p' AND $hour < 12)\r
+                               $hour = $hour + 12;\r
+                       \r
+                       if (substr($ampm, 0, 1) == 'a' AND $hour == 12)\r
+                               $hour =  '00';\r
+                       \r
+                       if (strlen($hour) == 1)\r
+                               $hour = '0'.$hour;\r
+               }\r
+                       \r
+               return mktime($hour, $min, $sec, $month, $day, $year);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Timezone Menu\r
+ *\r
+ * Generates a drop-down menu of timezones.\r
+ *\r
+ * @access     public\r
+ * @param      string  timezone\r
+ * @param      string  classname\r
+ * @param      string  menu name\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('timezone_menu'))\r
+{\r
+       function timezone_menu($default = 'UTC', $class = "", $name = 'timezones')\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('date');\r
+       \r
+               if ($default == 'GMT')\r
+                       $default = 'UTC';\r
+\r
+               $menu = '<select name="'.$name.'"';\r
+       \r
+               if ($class != '')\r
+               {\r
+                       $menu .= ' class="'.$class.'"';\r
+               }\r
+       \r
+               $menu .= ">\n";\r
+       \r
+               foreach (timezones() as $key => $val)\r
+               {\r
+                       $selected = ($default == $key) ? " selected='selected'" : '';\r
+                       $menu .= "<option value='{$key}'{$selected}>".$CI->lang->line($key)."</option>\n";\r
+               }\r
+\r
+               $menu .= "</select>";\r
+\r
+               return $menu;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Timezones\r
+ *\r
+ * Returns an array of timezones.  This is a helper function\r
+ * for various other ones in this library\r
+ *\r
+ * @access     public\r
+ * @param      string  timezone\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('timezones'))\r
+{\r
+       function timezones($tz = '')\r
+       {\r
+               // Note: Don't change the order of these even though\r
+               // some items appear to be in the wrong order\r
+               \r
+               $zones = array( \r
+                                               'UM12'          => -12,\r
+                                               'UM11'          => -11,\r
+                                               'UM10'          => -10,\r
+                                               'UM95'          => -9.5,\r
+                                               'UM9'           => -9,\r
+                                               'UM8'           => -8,\r
+                                               'UM7'           => -7,\r
+                                               'UM6'           => -6,\r
+                                               'UM5'           => -5,\r
+                                               'UM45'          => -4.5,\r
+                                               'UM4'           => -4,\r
+                                               'UM35'          => -3.5,\r
+                                               'UM3'           => -3,\r
+                                               'UM2'           => -2,\r
+                                               'UM1'           => -1,\r
+                                               'UTC'           => 0,\r
+                                               'UP1'           => +1,\r
+                                               'UP2'           => +2,\r
+                                               'UP3'           => +3,\r
+                                               'UP35'          => +3.5,\r
+                                               'UP4'           => +4,\r
+                                               'UP45'          => +4.5,\r
+                                               'UP5'           => +5,\r
+                                               'UP55'          => +5.5,\r
+                                               'UP575'         => +5.75,\r
+                                               'UP6'           => +6,\r
+                                               'UP65'          => +6.5,\r
+                                               'UP7'           => +7,\r
+                                               'UP8'           => +8,\r
+                                               'UP875'         => +8.75,\r
+                                               'UP9'           => +9,\r
+                                               'UP95'          => +9.5,\r
+                                               'UP10'          => +10,\r
+                                               'UP105'         => +10.5,\r
+                                               'UP11'          => +11,\r
+                                               'UP115'         => +11.5,\r
+                                               'UP12'          => +12,\r
+                                               'UP1275'        => +12.75,\r
+                                               'UP13'          => +13,\r
+                                               'UP14'          => +14\r
+                                       );\r
+                               \r
+               if ($tz == '')\r
+               {\r
+                       return $zones;\r
+               }\r
+       \r
+               if ($tz == 'GMT')\r
+                       $tz = 'UTC';\r
+       \r
+               return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];\r
+       }\r
+}\r
+\r
+\r
+/* End of file date_helper.php */\r
+/* Location: ./system/helpers/date_helper.php */
\ No newline at end of file
diff --git a/helpers/directory_helper.php b/helpers/directory_helper.php
new file mode 100644 (file)
index 0000000..8a1b999
--- /dev/null
@@ -0,0 +1,80 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Directory Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/directory_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Create a Directory Map\r
+ *\r
+ * Reads the specified directory and builds an array\r
+ * representation of it.  Sub-folders contained with the\r
+ * directory will be mapped as well.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to source\r
+ * @param      bool    whether to limit the result to the top level only\r
+ * @return     array\r
+ */    \r
+if ( ! function_exists('directory_map'))\r
+{\r
+       function directory_map($source_dir, $top_level_only = FALSE)\r
+       {       \r
+               if ($fp = @opendir($source_dir))\r
+               {\r
+                       $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;              \r
+                       $filedata = array();\r
+                       \r
+                       while (FALSE !== ($file = readdir($fp)))\r
+                       {\r
+                               if (strncmp($file, '.', 1) == 0)\r
+                               {\r
+                                       continue;\r
+                               }\r
+                               \r
+                               if ($top_level_only == FALSE && @is_dir($source_dir.$file))\r
+                               {\r
+                                       $temp_array = array();\r
+                               \r
+                                       $temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR);\r
+                               \r
+                                       $filedata[$file] = $temp_array;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $filedata[] = $file;\r
+                               }\r
+                       }\r
+                       \r
+                       closedir($fp);\r
+                       return $filedata;\r
+               }\r
+       }\r
+}\r
+\r
+\r
+/* End of file directory_helper.php */\r
+/* Location: ./system/helpers/directory_helper.php */
\ No newline at end of file
diff --git a/helpers/download_helper.php b/helpers/download_helper.php
new file mode 100644 (file)
index 0000000..2a555ae
--- /dev/null
@@ -0,0 +1,100 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Download Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/download_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Force Download\r
+ *\r
+ * Generates headers that force a download to happen\r
+ *\r
+ * @access     public\r
+ * @param      string  filename\r
+ * @param      mixed   the data to be downloaded\r
+ * @return     void\r
+ */    \r
+if ( ! function_exists('force_download'))\r
+{\r
+       function force_download($filename = '', $data = '')\r
+       {\r
+               if ($filename == '' OR $data == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // Try to determine if the filename includes a file extension.\r
+               // We need it in order to set the MIME type\r
+               if (FALSE === strpos($filename, '.'))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               // Grab the file extension\r
+               $x = explode('.', $filename);\r
+               $extension = end($x);\r
+\r
+               // Load the mime types\r
+               @include(APPPATH.'config/mimes'.EXT);\r
+       \r
+               // Set a default mime if we can't find it\r
+               if ( ! isset($mimes[$extension]))\r
+               {\r
+                       $mime = 'application/octet-stream';\r
+               }\r
+               else\r
+               {\r
+                       $mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];\r
+               }\r
+       \r
+               // Generate the server headers\r
+               if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))\r
+               {\r
+                       header('Content-Type: "'.$mime.'"');\r
+                       header('Content-Disposition: attachment; filename="'.$filename.'"');\r
+                       header('Expires: 0');\r
+                       header('Cache-Control: must-revalidate, post-check=0, pre-check=0');\r
+                       header("Content-Transfer-Encoding: binary");\r
+                       header('Pragma: public');\r
+                       header("Content-Length: ".strlen($data));\r
+               }\r
+               else\r
+               {\r
+                       header('Content-Type: "'.$mime.'"');\r
+                       header('Content-Disposition: attachment; filename="'.$filename.'"');\r
+                       header("Content-Transfer-Encoding: binary");\r
+                       header('Expires: 0');\r
+                       header('Pragma: no-cache');\r
+                       header("Content-Length: ".strlen($data));\r
+               }\r
+       \r
+               exit($data);\r
+       }\r
+}\r
+\r
+\r
+/* End of file download_helper.php */\r
+/* Location: ./system/helpers/download_helper.php */
\ No newline at end of file
diff --git a/helpers/email_helper.php b/helpers/email_helper.php
new file mode 100644 (file)
index 0000000..ab12b70
--- /dev/null
@@ -0,0 +1,62 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Email Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/email_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Validate email address\r
+ *\r
+ * @access     public\r
+ * @return     bool\r
+ */    \r
+if ( ! function_exists('valid_email'))\r
+{\r
+       function valid_email($address)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Send an email\r
+ *\r
+ * @access     public\r
+ * @return     bool\r
+ */    \r
+if ( ! function_exists('send_email'))\r
+{\r
+       function send_email($recipient, $subject = 'Test email', $message = 'Hello World')\r
+       {\r
+               return mail($recipient, $subject, $message);\r
+       }\r
+}\r
+\r
+\r
+/* End of file email_helper.php */\r
+/* Location: ./system/helpers/email_helper.php */
\ No newline at end of file
diff --git a/helpers/file_helper.php b/helpers/file_helper.php
new file mode 100644 (file)
index 0000000..6378784
--- /dev/null
@@ -0,0 +1,465 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter File Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/file_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Read File\r
+ *\r
+ * Opens the file specfied in the path and returns it as a string.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to file\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('read_file'))\r
+{\r
+       function read_file($file)\r
+       {\r
+               if ( ! file_exists($file))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               if (function_exists('file_get_contents'))\r
+               {\r
+                       return file_get_contents($file);                \r
+               }\r
+\r
+               if ( ! $fp = @fopen($file, FOPEN_READ))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               flock($fp, LOCK_SH);\r
+       \r
+               $data = '';\r
+               if (filesize($file) > 0)\r
+               {\r
+                       $data =& fread($fp, filesize($file));\r
+               }\r
+\r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);\r
+\r
+               return $data;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Write File\r
+ *\r
+ * Writes data to the file specified in the path.\r
+ * Creates a new file if non-existent.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to file\r
+ * @param      string  file data\r
+ * @return     bool\r
+ */    \r
+if ( ! function_exists('write_file'))\r
+{\r
+       function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)\r
+       {\r
+               if ( ! $fp = @fopen($path, $mode))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               flock($fp, LOCK_EX);\r
+               fwrite($fp, $data);\r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);    \r
+\r
+               return TRUE;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Delete Files\r
+ *\r
+ * Deletes all files contained in the supplied directory path.\r
+ * Files must be writable or owned by the system in order to be deleted.\r
+ * If the second parameter is set to TRUE, any directories contained\r
+ * within the supplied base directory will be nuked as well.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to file\r
+ * @param      bool    whether to delete any directories found in the path\r
+ * @return     bool\r
+ */    \r
+if ( ! function_exists('delete_files'))\r
+{\r
+       function delete_files($path, $del_dir = FALSE, $level = 0)\r
+       {       \r
+               // Trim the trailing slash\r
+               $path = preg_replace("|^(.+?)/*$|", "\\1", $path);\r
+               \r
+               if ( ! $current_dir = @opendir($path))\r
+                       return;\r
+       \r
+               while(FALSE !== ($filename = @readdir($current_dir)))\r
+               {\r
+                       if ($filename != "." and $filename != "..")\r
+                       {\r
+                               if (is_dir($path.'/'.$filename))\r
+                               {\r
+                                       // Ignore empty folders\r
+                                       if (substr($filename, 0, 1) != '.')\r
+                                       {\r
+                                               delete_files($path.'/'.$filename, $del_dir, $level + 1);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       unlink($path.'/'.$filename);\r
+                               }\r
+                       }\r
+               }\r
+               @closedir($current_dir);\r
+       \r
+               if ($del_dir == TRUE AND $level > 0)\r
+               {\r
+                       @rmdir($path);\r
+               }\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Get Filenames\r
+ *\r
+ * Reads the specified directory and builds an array containing the filenames.  \r
+ * Any sub-folders contained within the specified path are read as well.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to source\r
+ * @param      bool    whether to include the path as part of the filename\r
+ * @param      bool    internal variable to determine recursion status - do not use in calls\r
+ * @return     array\r
+ */    \r
+if ( ! function_exists('get_filenames'))\r
+{\r
+       function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)\r
+       {\r
+               static $_filedata = array();\r
+                               \r
+               if ($fp = @opendir($source_dir))\r
+               {\r
+                       // reset the array and make sure $source_dir has a trailing slash on the initial call\r
+                       if ($_recursion === FALSE)\r
+                       {\r
+                               $_filedata = array();\r
+                               $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;\r
+                       }\r
+                       \r
+                       while (FALSE !== ($file = readdir($fp)))\r
+                       {\r
+                               if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)\r
+                               {\r
+                                        get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);\r
+                               }\r
+                               elseif (strncmp($file, '.', 1) !== 0)\r
+                               {\r
+                       \r
+                                       $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;\r
+                               }\r
+                       }\r
+                       return $_filedata;\r
+               }\r
+               else\r
+               {\r
+                       return FALSE;\r
+               }\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Get Directory File Information\r
+ *\r
+ * Reads the specified directory and builds an array containing the filenames,  \r
+ * filesize, dates, and permissions\r
+ *\r
+ * Any sub-folders contained within the specified path are read as well.\r
+ *\r
+ * @access     public\r
+ * @param      string  path to source\r
+ * @param      bool    whether to include the path as part of the filename\r
+ * @param      bool    internal variable to determine recursion status - do not use in calls\r
+ * @return     array\r
+ */    \r
+if ( ! function_exists('get_dir_file_info'))\r
+{\r
+       function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE)\r
+       {\r
+               $_filedata = array();\r
+               $relative_path = $source_dir;\r
+                               \r
+               if ($fp = @opendir($source_dir))\r
+               {\r
+                       // reset the array and make sure $source_dir has a trailing slash on the initial call\r
+                       if ($_recursion === FALSE)\r
+                       {\r
+                               $_filedata = array();\r
+                               $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;\r
+                       }\r
+\r
+                       while (FALSE !== ($file = readdir($fp)))\r
+                       {\r
+                               if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)\r
+                               {\r
+                                        get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);\r
+                               }\r
+                               elseif (strncmp($file, '.', 1) !== 0)\r
+                               {\r
+                                       $_filedata[$file] = get_file_info($source_dir.$file);\r
+                                       $_filedata[$file]['relative_path'] = $relative_path;\r
+                               }\r
+                       }\r
+                       return $_filedata;\r
+               }\r
+               else\r
+               {\r
+                       return FALSE;\r
+               }\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+* Get File Info\r
+*\r
+* Given a file and path, returns the name, path, size, date modified\r
+* Second parameter allows you to explicitly declare what information you want returned\r
+* Options are: name, server_path, size, date, readable, writable, executable, fileperms\r
+* Returns FALSE if the file cannot be found.\r
+*\r
+* @access      public\r
+* @param       string          path to file\r
+* @param       mixed           array or comma separated string of information returned\r
+* @return      array\r
+*/\r
+if ( ! function_exists('get_file_info'))\r
+{\r
+       function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))\r
+       {\r
+\r
+               if ( ! file_exists($file))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (is_string($returned_values))\r
+               {\r
+                       $returned_values = explode(',', $returned_values);\r
+               }\r
+\r
+               foreach ($returned_values as $key)\r
+               {\r
+                       switch ($key)\r
+                       {\r
+                               case 'name':\r
+                                       $fileinfo['name'] = substr(strrchr($file, '/'), 1);\r
+                                       break;\r
+                               case 'server_path':\r
+                                       $fileinfo['server_path'] = $file;\r
+                                       break;\r
+                               case 'size':\r
+                                       $fileinfo['size'] = filesize($file);\r
+                                       break;\r
+                               case 'date':\r
+                                       $fileinfo['date'] = filectime($file);\r
+                                       break;\r
+                               case 'readable':\r
+                                       $fileinfo['readable'] = is_readable($file);\r
+                                       break;\r
+                               case 'writable':\r
+                                       // There are known problems using is_weritable on IIS.  It may not be reliable - consider fileperms()\r
+                                       $fileinfo['writable'] = is_writable($file);\r
+                                       break;\r
+                               case 'executable':\r
+                                       $fileinfo['executable'] = is_executable($file);\r
+                                       break;\r
+                               case 'fileperms':\r
+                                       $fileinfo['fileperms'] = fileperms($file);\r
+                                       break;\r
+                       }\r
+               }\r
+\r
+               return $fileinfo;\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Get Mime by Extension\r
+ *\r
+ * Translates a file extension into a mime type based on config/mimes.php. \r
+ * Returns FALSE if it can't determine the type, or open the mime config file\r
+ *\r
+ * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience\r
+ * It should NOT be trusted, and should certainly NOT be used for security\r
+ *\r
+ * @access     public\r
+ * @param      string  path to file\r
+ * @return     mixed\r
+ */    \r
+if ( ! function_exists('get_mime_by_extension'))\r
+{\r
+       function get_mime_by_extension($file)\r
+       {\r
+               $extension = substr(strrchr($file, '.'), 1);\r
+       \r
+               global $mimes;\r
+       \r
+               if ( ! is_array($mimes))\r
+               {\r
+                       if ( ! require_once(APPPATH.'config/mimes.php'))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               if (array_key_exists($extension, $mimes))\r
+               {\r
+                       if (is_array($mimes[$extension]))\r
+                       {\r
+                               // Multiple mime types, just give the first one\r
+                               return current($mimes[$extension]);\r
+                       }\r
+                       else\r
+                       {\r
+                               return $mimes[$extension];\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       return FALSE;\r
+               }\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Symbolic Permissions\r
+ *\r
+ * Takes a numeric value representing a file's permissions and returns\r
+ * standard symbolic notation representing that value\r
+ *\r
+ * @access     public\r
+ * @param      int\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('symbolic_permissions'))\r
+{\r
+       function symbolic_permissions($perms)\r
+       {       \r
+               if (($perms & 0xC000) == 0xC000)\r
+               {\r
+                       $symbolic = 's'; // Socket\r
+               }\r
+               elseif (($perms & 0xA000) == 0xA000)\r
+               {\r
+                       $symbolic = 'l'; // Symbolic Link\r
+               }\r
+               elseif (($perms & 0x8000) == 0x8000)\r
+               {\r
+                       $symbolic = '-'; // Regular\r
+               }\r
+               elseif (($perms & 0x6000) == 0x6000)\r
+               {\r
+                       $symbolic = 'b'; // Block special\r
+               }\r
+               elseif (($perms & 0x4000) == 0x4000)\r
+               {\r
+                       $symbolic = 'd'; // Directory\r
+               }\r
+               elseif (($perms & 0x2000) == 0x2000)\r
+               {\r
+                       $symbolic = 'c'; // Character special\r
+               }\r
+               elseif (($perms & 0x1000) == 0x1000)\r
+               {\r
+                       $symbolic = 'p'; // FIFO pipe\r
+               }\r
+               else\r
+               {\r
+                       $symbolic = 'u'; // Unknown\r
+               }\r
+\r
+               // Owner\r
+               $symbolic .= (($perms & 0x0100) ? 'r' : '-');\r
+               $symbolic .= (($perms & 0x0080) ? 'w' : '-');\r
+               $symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));\r
+\r
+               // Group\r
+               $symbolic .= (($perms & 0x0020) ? 'r' : '-');\r
+               $symbolic .= (($perms & 0x0010) ? 'w' : '-');\r
+               $symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));\r
+\r
+               // World\r
+               $symbolic .= (($perms & 0x0004) ? 'r' : '-');\r
+               $symbolic .= (($perms & 0x0002) ? 'w' : '-');\r
+               $symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));\r
+\r
+               return $symbolic;               \r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Octal Permissions\r
+ *\r
+ * Takes a numeric value representing a file's permissions and returns\r
+ * a three character string representing the file's octal permissions\r
+ *\r
+ * @access     public\r
+ * @param      int\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('octal_permissions'))\r
+{\r
+       function octal_permissions($perms)\r
+       {\r
+               return substr(sprintf('%o', $perms), -3);\r
+       }\r
+}\r
+\r
+\r
+/* End of file file_helper.php */\r
+/* Location: ./system/helpers/file_helper.php */
\ No newline at end of file
diff --git a/helpers/form_helper.php b/helpers/form_helper.php
new file mode 100644 (file)
index 0000000..109d8c1
--- /dev/null
@@ -0,0 +1,963 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Form Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/form_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Declaration\r
+ *\r
+ * Creates the opening portion of the form.\r
+ *\r
+ * @access     public\r
+ * @param      string  the URI segments of the form destination\r
+ * @param      array   a key/value pair of attributes\r
+ * @param      array   a key/value pair hidden data\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('form_open'))\r
+{\r
+       function form_open($action = '', $attributes = '', $hidden = array())\r
+       {\r
+               $CI =& get_instance();\r
+\r
+               if ($attributes == '')\r
+               {\r
+                       $attributes = 'method="post"';\r
+               }\r
+\r
+               $action = ( strpos($action, '://') === FALSE) ? $CI->config->site_url($action) : $action;\r
+\r
+               $form = '<form action="'.$action.'"';\r
+       \r
+               $form .= _attributes_to_string($attributes, TRUE);\r
+       \r
+               $form .= '>';\r
+\r
+               if (is_array($hidden) AND count($hidden) > 0)\r
+               {\r
+                       $form .= form_hidden($hidden);\r
+               }\r
+\r
+               return $form;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Declaration - Multipart type\r
+ *\r
+ * Creates the opening portion of the form, but with "multipart/form-data".\r
+ *\r
+ * @access     public\r
+ * @param      string  the URI segments of the form destination\r
+ * @param      array   a key/value pair of attributes\r
+ * @param      array   a key/value pair hidden data\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_open_multipart'))\r
+{\r
+       function form_open_multipart($action, $attributes = array(), $hidden = array())\r
+       {\r
+               $attributes['enctype'] = 'multipart/form-data';\r
+               return form_open($action, $attributes, $hidden);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Hidden Input Field\r
+ *\r
+ * Generates hidden fields.  You can pass a simple key/value string or an associative\r
+ * array with multiple values.\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_hidden'))\r
+{\r
+       function form_hidden($name, $value = '')\r
+       {\r
+               if ( ! is_array($name))\r
+               {\r
+                       return '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';\r
+               }\r
+\r
+               $form = '';\r
+\r
+               foreach ($name as $name => $value)\r
+               {\r
+                       $form .= "\n";\r
+                       $form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';\r
+               }\r
+\r
+               return $form;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Text Input Field\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_input'))\r
+{\r
+       function form_input($data = '', $value = '', $extra = '')\r
+       {\r
+               $defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);\r
+\r
+               return "<input "._parse_form_attributes($data, $defaults).$extra." />";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Password Field\r
+ *\r
+ * Identical to the input function but adds the "password" type\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_password'))\r
+{\r
+       function form_password($data = '', $value = '', $extra = '')\r
+       {\r
+               if ( ! is_array($data))\r
+               {\r
+                       $data = array('name' => $data);\r
+               }\r
+\r
+               $data['type'] = 'password';\r
+               return form_input($data, $value, $extra);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Upload Field\r
+ *\r
+ * Identical to the input function but adds the "file" type\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_upload'))\r
+{\r
+       function form_upload($data = '', $value = '', $extra = '')\r
+       {\r
+               if ( ! is_array($data))\r
+               {\r
+                       $data = array('name' => $data);\r
+               }\r
+\r
+               $data['type'] = 'file';\r
+               return form_input($data, $value, $extra);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Textarea field\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_textarea'))\r
+{\r
+       function form_textarea($data = '', $value = '', $extra = '')\r
+       {\r
+               $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12');\r
+\r
+               if ( ! is_array($data) OR ! isset($data['value']))\r
+               {\r
+                       $val = $value;\r
+               }\r
+               else\r
+               {\r
+                       $val = $data['value']; \r
+                       unset($data['value']); // textareas don't use the value attribute\r
+               }\r
+\r
+               return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".$val."</textarea>";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Drop-down Menu\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      array\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_dropdown'))\r
+{\r
+       function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')\r
+       {\r
+               if ( ! is_array($selected))\r
+               {\r
+                       $selected = array($selected);\r
+               }\r
+\r
+               // If no selected state was submitted we will attempt to set it automatically\r
+               if (count($selected) === 0)\r
+               {\r
+                       // If the form name appears in the $_POST array we have a winner!\r
+                       if (isset($_POST[$name]))\r
+                       {\r
+                               $selected = array($_POST[$name]);\r
+                       }\r
+               }\r
+\r
+               if ($extra != '') $extra = ' '.$extra;\r
+\r
+               $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';\r
+\r
+               $form = '<select name="'.$name.'"'.$extra.$multiple.">\n";\r
+       \r
+               foreach ($options as $key => $val)\r
+               {\r
+                       $key = (string) $key;\r
+                       $val = (string) $val;\r
+\r
+                       $sel = (in_array($key, $selected))?' selected="selected"':'';\r
+\r
+                       $form .= '<option value="'.$key.'"'.$sel.'>'.$val."</option>\n";\r
+               }\r
+\r
+               $form .= '</select>';\r
+\r
+               return $form;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Checkbox Field\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      bool\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_checkbox'))\r
+{\r
+       function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')\r
+       {\r
+               $defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);\r
+\r
+               if (is_array($data) AND array_key_exists('checked', $data))\r
+               {\r
+                       $checked = $data['checked'];\r
+\r
+                       if ($checked == FALSE)\r
+                       {\r
+                               unset($data['checked']);\r
+                       }\r
+                       else\r
+                       {\r
+                               $data['checked'] = 'checked';\r
+                       }\r
+               }\r
+\r
+               if ($checked == TRUE)\r
+               {\r
+                       $defaults['checked'] = 'checked';\r
+               }\r
+               else\r
+               {\r
+                       unset($defaults['checked']);\r
+               }\r
+\r
+               return "<input "._parse_form_attributes($data, $defaults).$extra." />";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Radio Button\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      bool\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_radio'))\r
+{\r
+       function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')\r
+       {\r
+               if ( ! is_array($data))\r
+               {       \r
+                       $data = array('name' => $data);\r
+               }\r
+\r
+               $data['type'] = 'radio';\r
+               return form_checkbox($data, $value, $checked, $extra);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Submit Button\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_submit'))\r
+{      \r
+       function form_submit($data = '', $value = '', $extra = '')\r
+       {\r
+               $defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);\r
+\r
+               return "<input "._parse_form_attributes($data, $defaults).$extra." />";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Reset Button\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_reset'))\r
+{\r
+       function form_reset($data = '', $value = '', $extra = '')\r
+       {\r
+               $defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);\r
+\r
+               return "<input "._parse_form_attributes($data, $defaults).$extra." />";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Button\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_button'))\r
+{\r
+       function form_button($data = '', $content = '', $extra = '')\r
+       {\r
+               $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'submit');\r
+\r
+               if ( is_array($data) AND isset($data['content']))\r
+               {\r
+                       $content = $data['content'];\r
+                       unset($data['content']); // content is not an attribute\r
+               }\r
+\r
+               return "<button "._parse_form_attributes($data, $defaults).$extra.">".$content."</button>";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Label Tag\r
+ *\r
+ * @access     public\r
+ * @param      string  The text to appear onscreen\r
+ * @param      string  The id the label applies to\r
+ * @param      string  Additional attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_label'))\r
+{\r
+       function form_label($label_text = '', $id = '', $attributes = array())\r
+       {\r
+\r
+               $label = '<label';\r
+\r
+               if ($id != '')\r
+               {\r
+                        $label .= " for=\"$id\"";\r
+               }\r
+\r
+               if (is_array($attributes) AND count($attributes) > 0)\r
+               {\r
+                       foreach ($attributes as $key => $val)\r
+                       {\r
+                               $label .= ' '.$key.'="'.$val.'"';\r
+                       }\r
+               }\r
+\r
+               $label .= ">$label_text</label>";\r
+\r
+               return $label;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+/**\r
+ * Fieldset Tag\r
+ *\r
+ * Used to produce <fieldset><legend>text</legend>.  To close fieldset\r
+ * use form_fieldset_close()\r
+ *\r
+ * @access     public\r
+ * @param      string  The legend text\r
+ * @param      string  Additional attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_fieldset'))\r
+{\r
+       function form_fieldset($legend_text = '', $attributes = array())\r
+       {\r
+               $fieldset = "<fieldset";\r
+\r
+               $fieldset .= _attributes_to_string($attributes, FALSE);\r
+\r
+               $fieldset .= ">\n";\r
+\r
+               if ($legend_text != '')\r
+               {\r
+                       $fieldset .= "<legend>$legend_text</legend>\n";\r
+               }\r
+\r
+               return $fieldset;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Fieldset Close Tag\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_fieldset_close'))\r
+{\r
+       function form_fieldset_close($extra = '')\r
+       {\r
+               return "</fieldset>".$extra;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Close Tag\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_close'))\r
+{\r
+       function form_close($extra = '')\r
+       {\r
+               return "</form>".$extra;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Prep\r
+ *\r
+ * Formats text so that it can be safely placed in a form field in the event it has HTML tags.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_prep'))\r
+{\r
+       function form_prep($str = '')\r
+       {\r
+               // if the field name is an array we do this recursively\r
+               if (is_array($str))\r
+               {\r
+                       foreach ($str as $key => $val)\r
+                       {\r
+                               $str[$key] = form_prep($val);\r
+                       }\r
+\r
+                       return $str;\r
+               }\r
+\r
+               if ($str === '')\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               $temp = '__TEMP_AMPERSANDS__';\r
+\r
+               // Replace entities to temporary markers so that \r
+               // htmlspecialchars won't mess them up\r
+               $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);\r
+               $str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);\r
+\r
+               $str = htmlspecialchars($str);\r
+\r
+               // In case htmlspecialchars misses these.\r
+               $str = str_replace(array("'", '"'), array("&#39;", "&quot;"), $str);\r
+\r
+               // Decode the temp markers back to entities\r
+               $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);\r
+               $str = preg_replace("/$temp(\w+);/","&\\1;",$str);\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Value\r
+ *\r
+ * Grabs a value from the POST array for the specified field so you can\r
+ * re-populate an input field or textarea.  If Form Validation\r
+ * is active it retrieves the info from the validation class\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     mixed\r
+ */\r
+if ( ! function_exists('set_value'))\r
+{\r
+       function set_value($field = '', $default = '')\r
+       {\r
+               if (FALSE === ($OBJ =& _get_validation_object()))\r
+               {\r
+                       if ( ! isset($_POST[$field]))\r
+                       {\r
+                               return $default;\r
+                       }\r
+\r
+                       return form_prep($_POST[$field]);\r
+               }\r
+\r
+               return form_prep($OBJ->set_value($field, $default));\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Set Select\r
+ *\r
+ * Let's you set the selected value of a <select> menu via data in the POST array.\r
+ * If Form Validation is active it retrieves the info from the validation class\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('set_select'))\r
+{\r
+       function set_select($field = '', $value = '', $default = FALSE)\r
+       {\r
+               $OBJ =& _get_validation_object();\r
+\r
+               if ($OBJ === FALSE)\r
+               {\r
+                       if ( ! isset($_POST[$field]))\r
+                       {\r
+                               if (count($_POST) === 0)\r
+                               {\r
+                                       return ' selected="selected"';\r
+                               }\r
+                               return '';\r
+                       }\r
+\r
+                       $field = $_POST[$field];\r
+\r
+                       if (is_array($field))\r
+                       {\r
+                               if ( ! in_array($value, $field))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if (($field == '' OR $value == '') OR ($field != $value))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+\r
+                       return ' selected="selected"';\r
+               }\r
+\r
+               return $OBJ->set_select($field, $value, $default);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Set Checkbox\r
+ *\r
+ * Let's you set the selected value of a checkbox via the value in the POST array.\r
+ * If Form Validation is active it retrieves the info from the validation class\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('set_checkbox'))\r
+{\r
+       function set_checkbox($field = '', $value = '', $default = FALSE)\r
+       {\r
+               $OBJ =& _get_validation_object();\r
+\r
+               if ($OBJ === FALSE)\r
+               { \r
+                       if ( ! isset($_POST[$field]))\r
+                       {\r
+                               if (count($_POST) === 0)\r
+                               {\r
+                                       return ' checked="checked"';\r
+                               }\r
+                               return '';\r
+                       }\r
+\r
+                       $field = $_POST[$field];\r
+                       \r
+                       if (is_array($field))\r
+                       {\r
+                               if ( ! in_array($value, $field))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if (($field == '' OR $value == '') OR ($field != $value))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+\r
+                       return ' checked="checked"';\r
+               }\r
+\r
+               return $OBJ->set_checkbox($field, $value, $default);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Set Radio\r
+ *\r
+ * Let's you set the selected value of a radio field via info in the POST array.\r
+ * If Form Validation is active it retrieves the info from the validation class\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('set_radio'))\r
+{\r
+       function set_radio($field = '', $value = '', $default = FALSE)\r
+       {\r
+               $OBJ =& _get_validation_object();\r
+\r
+               if ($OBJ === FALSE)\r
+               {\r
+                       if ( ! isset($_POST[$field]))\r
+                       {\r
+                               if (count($_POST) === 0)\r
+                               {\r
+                                       return ' checked="checked"';\r
+                               }\r
+                               return '';\r
+                       }\r
+\r
+                       $field = $_POST[$field];\r
+                       \r
+                       if (is_array($field))\r
+                       {\r
+                               if ( ! in_array($value, $field))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if (($field == '' OR $value == '') OR ($field != $value))\r
+                               {\r
+                                       return '';\r
+                               }\r
+                       }\r
+\r
+                       return ' checked="checked"';\r
+               }\r
+\r
+               return $OBJ->set_radio($field, $value, $default);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Error\r
+ *\r
+ * Returns the error for a specific form field.  This is a helper for the\r
+ * form validation class.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('form_error'))\r
+{\r
+       function form_error($field = '', $prefix = '', $suffix = '')\r
+       {\r
+               if (FALSE === ($OBJ =& _get_validation_object()))\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               return $OBJ->error($field, $prefix, $suffix);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Validation Error String\r
+ *\r
+ * Returns all the errors associated with a form submission.  This is a helper\r
+ * function for the form validation class.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('validation_errors'))\r
+{\r
+       function validation_errors($prefix = '', $suffix = '')\r
+       {\r
+               if (FALSE === ($OBJ =& _get_validation_object()))\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               return $OBJ->error_string($prefix, $suffix);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Parse the form attributes\r
+ *\r
+ * Helper function used by some of the form helpers\r
+ *\r
+ * @access     private\r
+ * @param      array\r
+ * @param      array\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('_parse_form_attributes'))\r
+{\r
+       function _parse_form_attributes($attributes, $default)\r
+       {\r
+               if (is_array($attributes))\r
+               {\r
+                       foreach ($default as $key => $val)\r
+                       {\r
+                               if (isset($attributes[$key]))\r
+                               {\r
+                                       $default[$key] = $attributes[$key];\r
+                                       unset($attributes[$key]);\r
+                               }\r
+                       }\r
+\r
+                       if (count($attributes) > 0)\r
+                       {\r
+                               $default = array_merge($default, $attributes);\r
+                       }\r
+               }\r
+\r
+               $att = '';\r
+\r
+               foreach ($default as $key => $val)\r
+               {\r
+                       if ($key == 'value')\r
+                       {\r
+                               $val = form_prep($val);\r
+                       }\r
+\r
+                       $att .= $key . '="' . $val . '" ';\r
+               }\r
+\r
+               return $att;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Attributes To String\r
+ *\r
+ * Helper function used by some of the form helpers\r
+ *\r
+ * @access     private\r
+ * @param      mixed\r
+ * @param      bool\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('_attributes_to_string'))\r
+{\r
+       function _attributes_to_string($attributes, $formtag = FALSE)\r
+       {\r
+               if (is_string($attributes) AND strlen($attributes) > 0)\r
+               {\r
+                       if ($formtag == TRUE AND strpos($attributes, 'method=') === FALSE)\r
+                       {\r
+                               $attributes .= ' method="post"';\r
+                       }\r
+\r
+               return ' '.$attributes;\r
+               }\r
+       \r
+               if (is_object($attributes) AND count($attributes) > 0)\r
+               {\r
+                       $attributes = (array)$attributes;\r
+               }\r
+\r
+               if (is_array($attributes) AND count($attributes) > 0)\r
+               {\r
+               $atts = '';\r
+\r
+               if ( ! isset($attributes['method']) AND $formtag === TRUE)\r
+               {\r
+                       $atts .= ' method="post"';\r
+               }\r
+\r
+               foreach ($attributes as $key => $val)\r
+               {\r
+                       $atts .= ' '.$key.'="'.$val.'"';\r
+               }\r
+\r
+               return $atts;\r
+               }\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Validation Object\r
+ *\r
+ * Determines what the form validation class was instantiated as, fetches\r
+ * the object and returns it.\r
+ *\r
+ * @access     private\r
+ * @return     mixed\r
+ */\r
+if ( ! function_exists('_get_validation_object'))\r
+{\r
+       function &_get_validation_object()\r
+       {\r
+               $CI =& get_instance();\r
+\r
+               // We set this as a variable since we're returning by reference\r
+               $return = FALSE;\r
+\r
+               if ( ! isset($CI->load->_ci_classes) OR  ! isset($CI->load->_ci_classes['form_validation']))\r
+               {\r
+                       return $return;\r
+               }\r
+\r
+               $object = $CI->load->_ci_classes['form_validation'];\r
+\r
+               if ( ! isset($CI->$object) OR ! is_object($CI->$object))\r
+               {\r
+                       return $return;\r
+               }\r
+\r
+               return $CI->$object;\r
+       }\r
+}\r
+\r
+\r
+/* End of file form_helper.php */\r
+/* Location: ./system/helpers/form_helper.php */
\ No newline at end of file
diff --git a/helpers/html_helper.php b/helpers/html_helper.php
new file mode 100644 (file)
index 0000000..ef5a84a
--- /dev/null
@@ -0,0 +1,376 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter HTML Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/html_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Heading\r
+ *\r
+ * Generates an HTML heading tag.  First param is the data.\r
+ * Second param is the size of the heading tag.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      integer\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('heading'))\r
+{\r
+       function heading($data = '', $h = '1')\r
+       {\r
+               return "<h".$h.">".$data."</h".$h.">";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Unordered List\r
+ *\r
+ * Generates an HTML unordered list from an single or multi-dimensional array.\r
+ *\r
+ * @access     public\r
+ * @param      array\r
+ * @param      mixed\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('ul'))\r
+{\r
+       function ul($list, $attributes = '')\r
+       {\r
+               return _list('ul', $list, $attributes);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Ordered List\r
+ *\r
+ * Generates an HTML ordered list from an single or multi-dimensional array.\r
+ *\r
+ * @access     public\r
+ * @param      array\r
+ * @param      mixed\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('ol'))\r
+{\r
+       function ol($list, $attributes = '')\r
+       {\r
+               return _list('ol', $list, $attributes);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Generates the list\r
+ *\r
+ * Generates an HTML ordered list from an single or multi-dimensional array.\r
+ *\r
+ * @access     private\r
+ * @param      string\r
+ * @param      mixed           \r
+ * @param      mixed           \r
+ * @param      intiger         \r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('_list'))\r
+{\r
+       function _list($type = 'ul', $list, $attributes = '', $depth = 0)\r
+       {\r
+               // If an array wasn't submitted there's nothing to do...\r
+               if ( ! is_array($list))\r
+               {\r
+                       return $list;\r
+               }\r
+       \r
+               // Set the indentation based on the depth\r
+               $out = str_repeat(" ", $depth);\r
+       \r
+               // Were any attributes submitted?  If so generate a string\r
+               if (is_array($attributes))\r
+               {\r
+                       $atts = '';\r
+                       foreach ($attributes as $key => $val)\r
+                       {\r
+                               $atts .= ' ' . $key . '="' . $val . '"';\r
+                       }\r
+                       $attributes = $atts;\r
+               }\r
+       \r
+               // Write the opening list tag\r
+               $out .= "<".$type.$attributes.">\n";\r
+\r
+               // Cycle through the list elements.  If an array is \r
+               // encountered we will recursively call _list()\r
+\r
+               static $_last_list_item = '';\r
+               foreach ($list as $key => $val)\r
+               {       \r
+                       $_last_list_item = $key;\r
+\r
+                       $out .= str_repeat(" ", $depth + 2);\r
+                       $out .= "<li>";\r
+               \r
+                       if ( ! is_array($val))\r
+                       {\r
+                               $out .= $val;\r
+                       }\r
+                       else\r
+                       {\r
+                               $out .= $_last_list_item."\n";\r
+                               $out .= _list($type, $val, '', $depth + 4);\r
+                               $out .= str_repeat(" ", $depth + 2);\r
+                       }\r
+\r
+                       $out .= "</li>\n";              \r
+               }\r
+\r
+               // Set the indentation for the closing tag\r
+               $out .= str_repeat(" ", $depth);\r
+       \r
+               // Write the closing list tag\r
+               $out .= "</".$type.">\n";\r
+\r
+               return $out;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Generates HTML BR tags based on number supplied\r
+ *\r
+ * @access     public\r
+ * @param      integer\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('br'))\r
+{\r
+       function br($num = 1)\r
+       {\r
+               return str_repeat("<br />", $num);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Image\r
+ *\r
+ * Generates an <img /> element\r
+ *\r
+ * @access     public\r
+ * @param      mixed\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('img'))\r
+{\r
+       function img($src = '', $index_page = FALSE)\r
+       {\r
+               if ( ! is_array($src) )\r
+               {\r
+                       $src = array('src' => $src);\r
+               }\r
+\r
+               $img = '<img';\r
+               \r
+               foreach ($src as $k=>$v)\r
+               {\r
+\r
+                       if ($k == 'src' AND strpos($v, '://') === FALSE)\r
+                       {\r
+                               $CI =& get_instance();\r
+\r
+                               if ($index_page === TRUE)\r
+                               {\r
+                                       $img .= ' src="'.$CI->config->site_url($v).'" ';\r
+                               }\r
+                               else\r
+                               {\r
+                                       $img .= ' src="'.$CI->config->slash_item('base_url').$v.'" ';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $img .= " $k=\"$v\" ";\r
+                       }\r
+               }\r
+\r
+               $img .= '/>';\r
+\r
+               return $img;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Link\r
+ *\r
+ * Generates link to a CSS file\r
+ *\r
+ * @access     public\r
+ * @param      mixed   stylesheet hrefs or an array\r
+ * @param      string  rel\r
+ * @param      string  type\r
+ * @param      string  title\r
+ * @param      string  media\r
+ * @param      boolean should index_page be added to the css path \r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('link_tag'))\r
+{\r
+       function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)\r
+       {\r
+               $CI =& get_instance();\r
+\r
+               $link = '<link ';\r
+\r
+               if (is_array($href))\r
+               {\r
+                       foreach ($href as $k=>$v)\r
+                       {\r
+                               if ($k == 'href' AND strpos($v, '://') === FALSE)\r
+                               {\r
+                                       if ($index_page === TRUE)\r
+                                       {\r
+                                               $link .= ' href="'.$CI->config->site_url($v).'" ';\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $link .= ' href="'.$CI->config->slash_item('base_url').$v.'" ';\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       $link .= "$k=\"$v\" ";\r
+                               }\r
+                       }\r
+                       \r
+                       $link .= "/>";\r
+               }\r
+               else\r
+               {\r
+                       if ( strpos($href, '://') !== FALSE)\r
+                       {\r
+                               $link .= ' href="'.$href.'" ';\r
+                       }\r
+                       elseif ($index_page === TRUE)\r
+                       {\r
+                               $link .= ' href="'.$CI->config->site_url($href).'" ';\r
+                       }\r
+                       else\r
+                       {\r
+                               $link .= ' href="'.$CI->config->slash_item('base_url').$href.'" ';\r
+                       }\r
+                               \r
+                       $link .= 'rel="'.$rel.'" type="'.$type.'" ';\r
+                       \r
+                       if ($media      != '')\r
+                       {\r
+                               $link .= 'media="'.$media.'" ';\r
+                       }\r
+\r
+                       if ($title      != '')\r
+                       {\r
+                               $link .= 'title="'.$title.'" ';\r
+                       }\r
+                       \r
+                       $link .= '/>';\r
+               }\r
+\r
+       \r
+               return $link;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Generates meta tags from an array of key/values\r
+ *\r
+ * @access     public\r
+ * @param      array\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('meta'))\r
+{\r
+       function meta($name = '', $content = '', $type = 'name', $newline = "\n")\r
+       {\r
+               // Since we allow the data to be passes as a string, a simple array\r
+               // or a multidimensional one, we need to do a little prepping.\r
+               if ( ! is_array($name))\r
+               {\r
+                       $name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));\r
+               }\r
+               else\r
+               {\r
+                       // Turn single array into multidimensional\r
+                       if (isset($name['name']))\r
+                       {\r
+                               $name = array($name);\r
+                       }\r
+               }\r
+       \r
+               $str = '';\r
+               foreach ($name as $meta)\r
+               {\r
+                       $type           = ( ! isset($meta['type']) OR $meta['type'] == 'name') ? 'name' : 'http-equiv';\r
+                       $name           = ( ! isset($meta['name']))     ? ''    : $meta['name'];\r
+                       $content        = ( ! isset($meta['content']))  ? ''    : $meta['content'];\r
+                       $newline        = ( ! isset($meta['newline']))  ? "\n"  : $meta['newline'];\r
+                       \r
+                       $str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Generates non-breaking space entities based on number supplied\r
+ *\r
+ * @access     public\r
+ * @param      integer\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('nbs'))\r
+{\r
+       function nbs($num = 1)\r
+       {\r
+               return str_repeat("&nbsp;", $num);\r
+       }\r
+}\r
+\r
+\r
+/* End of file html_helper.php */\r
+/* Location: ./system/helpers/html_helper.php */
\ No newline at end of file
diff --git a/helpers/index.html b/helpers/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/helpers/inflector_helper.php b/helpers/inflector_helper.php
new file mode 100644 (file)
index 0000000..8a87e50
--- /dev/null
@@ -0,0 +1,169 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Inflector Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/directory_helper.html\r
+ */\r
+\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Singular\r
+ *\r
+ * Takes a plural word and makes it singular\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     str\r
+ */    \r
+if ( ! function_exists('singular'))\r
+{      \r
+       function singular($str)\r
+       {\r
+               $str = strtolower(trim($str));\r
+               $end = substr($str, -3);\r
+       \r
+               if ($end == 'ies')\r
+               {\r
+                       $str = substr($str, 0, strlen($str)-3).'y';\r
+               }\r
+               elseif ($end == 'ses')\r
+               {\r
+                       $str = substr($str, 0, strlen($str)-2);\r
+               }\r
+               else\r
+               {\r
+                       $end = substr($str, -1);\r
+               \r
+                       if ($end == 's')\r
+                       {\r
+                               $str = substr($str, 0, strlen($str)-1);\r
+                       }\r
+               }\r
+       \r
+               return $str;\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Plural\r
+ *\r
+ * Takes a singular word and makes it plural\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     str\r
+ */    \r
+if ( ! function_exists('plural'))\r
+{      \r
+       function plural($str, $force = FALSE)\r
+       {\r
+               $str = strtolower(trim($str));\r
+               $end = substr($str, -1);\r
+\r
+               if ($end == 'y')\r
+               {\r
+                       $str = substr($str, 0, strlen($str)-1).'ies';\r
+               }\r
+               elseif ($end == 's')\r
+               {\r
+                       if ($force == TRUE)\r
+                       {\r
+                               $str .= 'es';\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $str .= 's';\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Camelize\r
+ *\r
+ * Takes multiple words separated by spaces or underscores and camelizes them\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     str\r
+ */    \r
+if ( ! function_exists('camelize'))\r
+{      \r
+       function camelize($str)\r
+       {               \r
+               $str = 'x'.strtolower(trim($str));\r
+               $str = ucwords(preg_replace('/[\s_]+/', ' ', $str));\r
+               return substr(str_replace(' ', '', $str), 1);\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Underscore\r
+ *\r
+ * Takes multiple words separated by spaces and underscores them\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     str\r
+ */    \r
+if ( ! function_exists('underscore'))\r
+{\r
+       function underscore($str)\r
+       {\r
+               return preg_replace('/[\s]+/', '_', strtolower(trim($str)));\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Humanize\r
+ *\r
+ * Takes multiple words separated by underscores and changes them to spaces\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     str\r
+ */    \r
+if ( ! function_exists('humanize'))\r
+{      \r
+       function humanize($str)\r
+       {\r
+               return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));\r
+       }\r
+}\r
+       \r
+\r
+/* End of file inflector_helper.php */\r
+/* Location: ./system/helpers/inflector_helper.php */
\ No newline at end of file
diff --git a/helpers/language_helper.php b/helpers/language_helper.php
new file mode 100644 (file)
index 0000000..2091fd4
--- /dev/null
@@ -0,0 +1,58 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package            CodeIgniter
+ * @author             ExpressionEngine Dev Team
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.
+ * @license            http://codeigniter.com/user_guide/license.html
+ * @link               http://codeigniter.com
+ * @since              Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Language Helpers
+ *
+ * @package            CodeIgniter
+ * @subpackage Helpers
+ * @category   Helpers
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/helpers/language_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Lang
+ *
+ * Fetches a language variable and optionally outputs a form label
+ *
+ * @access     public
+ * @param      string  the language line
+ * @param      string  the id of the form element
+ * @return     string
+ */    
+if ( ! function_exists('lang'))
+{
+       function lang($line, $id = '')
+       {
+               $CI =& get_instance();
+               $line = $CI->lang->line($line);
+
+               if ($id != '')
+               {
+                       $line = '<label for="'.$id.'">'.$line."</label>";
+               }
+
+               return $line;
+       }
+}
+
+// ------------------------------------------------------------------------
+/* End of file language_helper.php */
+/* Location: ./system/helpers/language_helper.php */
\ No newline at end of file
diff --git a/helpers/number_helper.php b/helpers/number_helper.php
new file mode 100644 (file)
index 0000000..5b3ea1f
--- /dev/null
@@ -0,0 +1,75 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Number Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/number_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Formats a numbers as bytes, based on size, and adds the appropriate suffix\r
+ *\r
+ * @access     public\r
+ * @param      mixed   // will be cast as int\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('byte_format'))\r
+{\r
+       function byte_format($num)\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('number');\r
+       \r
+               if ($num >= 1000000000000) \r
+               {\r
+                       $num = round($num / 1099511627776, 1);\r
+                       $unit = $CI->lang->line('terabyte_abbr');\r
+               }\r
+               elseif ($num >= 1000000000) \r
+               {\r
+                       $num = round($num / 1073741824, 1);\r
+                       $unit = $CI->lang->line('gigabyte_abbr');\r
+               }\r
+               elseif ($num >= 1000000) \r
+               {\r
+                       $num = round($num / 1048576, 1);\r
+                       $unit = $CI->lang->line('megabyte_abbr');\r
+               }\r
+               elseif ($num >= 1000) \r
+               {\r
+                       $num = round($num / 1024, 1);\r
+                       $unit = $CI->lang->line('kilobyte_abbr');\r
+               }\r
+               else\r
+               {\r
+                       $unit = $CI->lang->line('bytes');\r
+                       return number_format($num).' '.$unit;\r
+               }\r
+\r
+               return number_format($num, 1).' '.$unit;\r
+       }       \r
+}\r
+\r
+/* End of file number_helper.php */\r
+/* Location: ./system/helpers/number_helper.php */
\ No newline at end of file
diff --git a/helpers/path_helper.php b/helpers/path_helper.php
new file mode 100644 (file)
index 0000000..c5ee1fb
--- /dev/null
@@ -0,0 +1,72 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Path Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/xml_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Set Realpath\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      bool    checks to see if the path exists\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('set_realpath'))\r
+{\r
+       function set_realpath($path, $check_existance = FALSE)\r
+       {\r
+               // Security check to make sure the path is NOT a URL.  No remote file inclusion!\r
+               if (preg_match("#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i", $path))\r
+               {\r
+                       show_error('The path you submitted must be a local server path, not a URL');\r
+               }\r
+       \r
+               // Resolve the path\r
+               if (function_exists('realpath') AND @realpath($path) !== FALSE)\r
+               {\r
+                       $path = realpath($path).'/';\r
+               }\r
+       \r
+               // Add a trailing slash\r
+               $path = preg_replace("#([^/])/*$#", "\\1/", $path);\r
+       \r
+               // Make sure the path exists\r
+               if ($check_existance == TRUE)\r
+               {\r
+                       if ( ! is_dir($path))\r
+                       {\r
+                               show_error('Not a valid path: '.$path);\r
+                       }\r
+               }\r
+       \r
+               return $path;\r
+       }\r
+}\r
+\r
+\r
+/* End of file path_helper.php */\r
+/* Location: ./system/helpers/path_helper.php */
\ No newline at end of file
diff --git a/helpers/security_helper.php b/helpers/security_helper.php
new file mode 100644 (file)
index 0000000..f2c5bac
--- /dev/null
@@ -0,0 +1,126 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Security Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/security_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * XSS Filtering\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string  the character set of your data\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('xss_clean'))\r
+{\r
+       function xss_clean($str, $charset = 'ISO-8859-1')\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->input->xss_clean($str, $charset);\r
+       }\r
+}\r
+\r
+// --------------------------------------------------------------------\r
+\r
+/**\r
+ * Hash encode a string\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('dohash'))\r
+{      \r
+       function dohash($str, $type = 'sha1')\r
+       {\r
+               if ($type == 'sha1')\r
+               {\r
+                       if ( ! function_exists('sha1'))\r
+                       {\r
+                               if ( ! function_exists('mhash'))\r
+                               {       \r
+                                       require_once(BASEPATH.'libraries/Sha1'.EXT);\r
+                                       $SH = new CI_SHA;\r
+                                       return $SH->generate($str);\r
+                               }\r
+                               else\r
+                               {\r
+                                       return bin2hex(mhash(MHASH_SHA1, $str));\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               return sha1($str);\r
+                       }       \r
+               }\r
+               else\r
+               {\r
+                       return md5($str);\r
+               }\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Strip Image Tags\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('strip_image_tags'))\r
+{\r
+       function strip_image_tags($str)\r
+       {\r
+               $str = preg_replace("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "\\1", $str);\r
+               $str = preg_replace("#<img\s+.*?src\s*=\s*(.+?).*?\>#", "\\1", $str);\r
+                       \r
+               return $str;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Convert PHP tags to entities\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('encode_php_tags'))\r
+{\r
+       function encode_php_tags($str)\r
+       {\r
+               return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);\r
+       }\r
+}\r
+\r
+\r
+/* End of file security_helper.php */\r
+/* Location: ./system/helpers/security_helper.php */
\ No newline at end of file
diff --git a/helpers/smiley_helper.php b/helpers/smiley_helper.php
new file mode 100644 (file)
index 0000000..51c9dd0
--- /dev/null
@@ -0,0 +1,175 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Smiley Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/smiley_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * JS Insert Smiley\r
+ *\r
+ * Generates the javascrip function needed to insert smileys into a form field\r
+ *\r
+ * @access     public\r
+ * @param      string  form name\r
+ * @param      string  field name\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('js_insert_smiley'))\r
+{\r
+       function js_insert_smiley($form_name = '', $form_field = '')\r
+       {\r
+               return <<<EOF\r
+<script type="text/javascript">\r
+       function insert_smiley(smiley)\r
+       {\r
+               document.{$form_name}.{$form_field}.value += " " + smiley;\r
+       }\r
+</script>\r
+EOF;\r
+       }\r
+}\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Get Clickable Smileys\r
+ *\r
+ * Returns an array of image tag links that can be clicked to be inserted \r
+ * into a form field.  \r
+ *\r
+ * @access     public\r
+ * @param      string  the URL to the folder containing the smiley images\r
+ * @return     array\r
+ */\r
+if ( ! function_exists('get_clickable_smileys'))\r
+{\r
+       function get_clickable_smileys($image_url = '', $smileys = NULL)\r
+       {\r
+               if ( ! is_array($smileys))\r
+               {\r
+                       if (FALSE === ($smileys = _get_smiley_array()))\r
+                       {\r
+                               return $smileys;\r
+                       }\r
+               }\r
+\r
+               // Add a trailing slash to the file path if needed\r
+               $image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);\r
+\r
+               $used = array();\r
+               foreach ($smileys as $key => $val)\r
+               {\r
+                       // Keep duplicates from being used, which can happen if the\r
+                       // mapping array contains multiple identical replacements.  For example:\r
+                       // :-) and :) might be replaced with the same image so both smileys\r
+                       // will be in the array.\r
+                       if (isset($used[$smileys[$key][0]]))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       $link[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";\r
+\r
+                       $used[$smileys[$key][0]] = TRUE;\r
+               }\r
+\r
+               return $link;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Parse Smileys\r
+ *\r
+ * Takes a string as input and swaps any contained smileys for the actual image\r
+ *\r
+ * @access     public\r
+ * @param      string  the text to be parsed\r
+ * @param      string  the URL to the folder containing the smiley images\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('parse_smileys'))\r
+{\r
+       function parse_smileys($str = '', $image_url = '', $smileys = NULL)\r
+       {\r
+               if ($image_url == '')\r
+               {\r
+                       return $str;\r
+               }\r
+\r
+               if ( ! is_array($smileys))\r
+               {\r
+                       if (FALSE === ($smileys = _get_smiley_array()))\r
+                       {\r
+                               return $str;\r
+                       }\r
+               }\r
+\r
+               // Add a trailing slash to the file path if needed\r
+               $image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);\r
+\r
+               foreach ($smileys as $key => $val)\r
+               {\r
+                       $str = str_replace($key, "<img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" />", $str);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Get Smiley Array\r
+ *\r
+ * Fetches the config/smiley.php file\r
+ *\r
+ * @access     private\r
+ * @return     mixed\r
+ */\r
+if ( ! function_exists('_get_smiley_array'))\r
+{\r
+       function _get_smiley_array()\r
+       {\r
+               if ( ! file_exists(APPPATH.'config/smileys'.EXT))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               include(APPPATH.'config/smileys'.EXT);\r
+\r
+               if ( ! isset($smileys) OR ! is_array($smileys))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return $smileys;\r
+       }\r
+}\r
+\r
+\r
+/* End of file smiley_helper.php */\r
+/* Location: ./system/helpers/smiley_helper.php */
\ No newline at end of file
diff --git a/helpers/string_helper.php b/helpers/string_helper.php
new file mode 100644 (file)
index 0000000..4e376a8
--- /dev/null
@@ -0,0 +1,273 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter String Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/string_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Trim Slashes\r
+ *\r
+ * Removes any leading/traling slashes from a string:\r
+ *\r
+ * /this/that/theother/\r
+ *\r
+ * becomes:\r
+ *\r
+ * this/that/theother\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('trim_slashes'))\r
+{\r
+       function trim_slashes($str)\r
+       {\r
+               return trim($str, '/');\r
+       } \r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Strip Slashes\r
+ *\r
+ * Removes slashes contained in a string or in an array\r
+ *\r
+ * @access     public\r
+ * @param      mixed   string or array\r
+ * @return     mixed   string or array\r
+ */    \r
+if ( ! function_exists('strip_slashes'))\r
+{\r
+       function strip_slashes($str)\r
+       {\r
+               if (is_array($str))\r
+               {       \r
+                       foreach ($str as $key => $val)\r
+                       {\r
+                               $str[$key] = strip_slashes($val);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $str = stripslashes($str);\r
+               }\r
+       \r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Strip Quotes\r
+ *\r
+ * Removes single and double quotes from a string\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('strip_quotes'))\r
+{\r
+       function strip_quotes($str)\r
+       {\r
+               return str_replace(array('"', "'"), '', $str);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Quotes to Entities\r
+ *\r
+ * Converts single and double quotes to entities\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('quotes_to_entities'))\r
+{\r
+       function quotes_to_entities($str)\r
+       {       \r
+               return str_replace(array("\'","\"","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $str);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+/**\r
+ * Reduce Double Slashes\r
+ *\r
+ * Converts double slashes in a string to a single slash,\r
+ * except those found in http://\r
+ *\r
+ * http://www.some-site.com//index.php\r
+ *\r
+ * becomes:\r
+ *\r
+ * http://www.some-site.com/index.php\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('reduce_double_slashes'))\r
+{\r
+       function reduce_double_slashes($str)\r
+       {\r
+               return preg_replace("#([^:])//+#", "\\1/", $str);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Reduce Multiples\r
+ *\r
+ * Reduces multiple instances of a particular character.  Example:\r
+ *\r
+ * Fred, Bill,, Joe, Jimmy\r
+ *\r
+ * becomes:\r
+ *\r
+ * Fred, Bill, Joe, Jimmy\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      string  the character you wish to reduce\r
+ * @param      bool    TRUE/FALSE - whether to trim the character from the beginning/end\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('reduce_multiples'))\r
+{\r
+       function reduce_multiples($str, $character = ',', $trim = FALSE)\r
+       {\r
+               $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);\r
+\r
+               if ($trim === TRUE)\r
+               {\r
+                       $str = trim($str, $character);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Create a Random String\r
+ *\r
+ * Useful for generating passwords or hashes.\r
+ *\r
+ * @access     public\r
+ * @param      string  type of random string.  Options: alunum, numeric, nozero, unique\r
+ * @param      integer number of characters\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('random_string'))\r
+{      \r
+       function random_string($type = 'alnum', $len = 8)\r
+       {                                       \r
+               switch($type)\r
+               {\r
+                       case 'alnum'    :\r
+                       case 'numeric'  :\r
+                       case 'nozero'   :\r
+               \r
+                                       switch ($type)\r
+                                       {\r
+                                               case 'alnum'    :       $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\r
+                                                       break;\r
+                                               case 'numeric'  :       $pool = '0123456789';\r
+                                                       break;\r
+                                               case 'nozero'   :       $pool = '123456789';\r
+                                                       break;\r
+                                       }\r
+\r
+                                       $str = '';\r
+                                       for ($i=0; $i < $len; $i++)\r
+                                       {\r
+                                               $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);\r
+                                       }\r
+                                       return $str;\r
+                         break;\r
+                       case 'unique' : return md5(uniqid(mt_rand()));\r
+                         break;\r
+               }\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Alternator\r
+ *\r
+ * Allows strings to be alternated.  See docs...\r
+ *\r
+ * @access     public\r
+ * @param      string (as many parameters as needed)\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('alternator'))\r
+{\r
+       function alternator()\r
+       {\r
+               static $i;      \r
+\r
+               if (func_num_args() == 0)\r
+               {\r
+                       $i = 0;\r
+                       return '';\r
+               }\r
+               $args = func_get_args();\r
+               return $args[($i++ % count($args))];\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Repeater function\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      integer number of repeats\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('repeater'))\r
+{\r
+       function repeater($data, $num = 1)\r
+       {\r
+               return (($num > 0) ? str_repeat($data, $num) : '');\r
+       } \r
+}\r
+\r
+\r
+/* End of file string_helper.php */\r
+/* Location: ./system/helpers/string_helper.php */
\ No newline at end of file
diff --git a/helpers/text_helper.php b/helpers/text_helper.php
new file mode 100644 (file)
index 0000000..8a44608
--- /dev/null
@@ -0,0 +1,443 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Text Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/text_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Word Limiter\r
+ *\r
+ * Limits a string to X number of words.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      integer\r
+ * @param      string  the end character. Usually an ellipsis\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('word_limiter'))\r
+{\r
+       function word_limiter($str, $limit = 100, $end_char = '&#8230;')\r
+       {\r
+               if (trim($str) == '')\r
+               {\r
+                       return $str;\r
+               }\r
+       \r
+               preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);\r
+                       \r
+               if (strlen($str) == strlen($matches[0]))\r
+               {\r
+                       $end_char = '';\r
+               }\r
+               \r
+               return rtrim($matches[0]).$end_char;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Character Limiter\r
+ *\r
+ * Limits the string based on the character count.  Preserves complete words\r
+ * so the character count may not be exactly as specified.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      integer\r
+ * @param      string  the end character. Usually an ellipsis\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('character_limiter'))\r
+{\r
+       function character_limiter($str, $n = 500, $end_char = '&#8230;')\r
+       {\r
+               if (strlen($str) < $n)\r
+               {\r
+                       return $str;\r
+               }\r
+               \r
+               $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));\r
+\r
+               if (strlen($str) <= $n)\r
+               {\r
+                       return $str;\r
+               }\r
+                                                                       \r
+               $out = "";\r
+               foreach (explode(' ', trim($str)) as $val)\r
+               {\r
+                       $out .= $val.' ';                       \r
+                       if (strlen($out) >= $n)\r
+                       {\r
+                               return trim($out).$end_char;\r
+                       }               \r
+               }\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * High ASCII to Entities\r
+ *\r
+ * Converts High ascii text and MS Word special characters to character entities\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('ascii_to_entities'))\r
+{\r
+       function ascii_to_entities($str)\r
+       {\r
+          $count       = 1;\r
+          $out = '';\r
+          $temp        = array();\r
+       \r
+          for ($i = 0, $s = strlen($str); $i < $s; $i++)\r
+          {\r
+                  $ordinal = ord($str[$i]);\r
+       \r
+                  if ($ordinal < 128)\r
+                  {\r
+                          $out .= $str[$i];\r
+                  }\r
+                  else\r
+                  {\r
+                          if (count($temp) == 0)\r
+                          {\r
+                                  $count = ($ordinal < 224) ? 2 : 3;\r
+                          }\r
+               \r
+                          $temp[] = $ordinal;\r
+               \r
+                          if (count($temp) == $count)\r
+                          {\r
+                                  $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);\r
+\r
+                                  $out .= '&#'.$number.';';\r
+                                  $count = 1;\r
+                                  $temp = array();\r
+                          }\r
+                  }\r
+          }\r
+\r
+          return $out;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Entities to ASCII\r
+ *\r
+ * Converts character entities back to ASCII\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      bool\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('entities_to_ascii'))\r
+{\r
+       function entities_to_ascii($str, $all = TRUE)\r
+       {\r
+          if (preg_match_all('/\&#(\d+)\;/', $str, $matches))\r
+          {\r
+                  for ($i = 0, $s = count($matches['0']); $i < $s; $i++)\r
+                  {                            \r
+                          $digits = $matches['1'][$i];\r
+\r
+                          $out = '';\r
+\r
+                          if ($digits < 128)\r
+                          {\r
+                                  $out .= chr($digits);\r
+               \r
+                          }\r
+                          elseif ($digits < 2048)\r
+                          {\r
+                                  $out .= chr(192 + (($digits - ($digits % 64)) / 64));\r
+                                  $out .= chr(128 + ($digits % 64));\r
+                          }\r
+                          else\r
+                          {\r
+                                  $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));\r
+                                  $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));\r
+                                  $out .= chr(128 + ($digits % 64));\r
+                          }\r
+\r
+                          $str = str_replace($matches['0'][$i], $out, $str);                           \r
+                  }\r
+          }\r
+\r
+          if ($all)\r
+          {\r
+                  $str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),\r
+                                                         array("&","<",">","\"", "'", "-"),\r
+                                                         $str);\r
+          }\r
+\r
+          return $str;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Word Censoring Function\r
+ *\r
+ * Supply a string and an array of disallowed words and any\r
+ * matched words will be converted to #### or to the replacement\r
+ * word you've submitted.\r
+ *\r
+ * @access     public\r
+ * @param      string  the text string\r
+ * @param      string  the array of censoered words\r
+ * @param      string  the optional replacement value\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('word_censor'))\r
+{\r
+       function word_censor($str, $censored, $replacement = '')\r
+       {\r
+               if ( ! is_array($censored))\r
+               {\r
+                       return $str;\r
+               }\r
+\r
+               $str = ' '.$str.' ';\r
+               foreach ($censored as $badword)\r
+               {\r
+                       if ($replacement != '')\r
+                       {\r
+                               $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/i", $replacement, $str);\r
+                       }\r
+                       else\r
+                       {\r
+                               $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);\r
+                       }\r
+               }\r
+       \r
+               return trim($str);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Code Highlighter\r
+ *\r
+ * Colorizes code strings\r
+ *\r
+ * @access     public\r
+ * @param      string  the text string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('highlight_code'))\r
+{\r
+       function highlight_code($str)\r
+       {               \r
+               // The highlight string function encodes and highlights\r
+               // brackets so we need them to start raw\r
+               $str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);\r
+       \r
+               // Replace any existing PHP tags to temporary markers so they don't accidentally\r
+               // break the string out of PHP, and thus, thwart the highlighting.\r
+       \r
+               $str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'), \r
+                                                       array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);\r
+\r
+               // The highlight_string function requires that the text be surrounded\r
+               // by PHP tags, which we will remove later\r
+               $str = '<?php '.$str.' ?>'; // <?\r
+\r
+               // All the magic happens here, baby!    \r
+               $str = highlight_string($str, TRUE);\r
+\r
+               // Prior to PHP 5, the highligh function used icky <font> tags\r
+               // so we'll replace them with <span> tags.\r
+\r
+               if (abs(PHP_VERSION) < 5)\r
+               {\r
+                       $str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);\r
+                       $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);\r
+               }\r
+               \r
+               // Remove our artificially added PHP, and the syntax highlighting that came with it\r
+               $str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);\r
+               $str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);\r
+               $str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);\r
+                       \r
+               // Replace our markers back to PHP tags.\r
+               $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),\r
+                                                       array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);\r
+                                                                               \r
+               return $str;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Phrase Highlighter\r
+ *\r
+ * Highlights a phrase within a text string\r
+ *\r
+ * @access     public\r
+ * @param      string  the text string\r
+ * @param      string  the phrase you'd like to highlight\r
+ * @param      string  the openging tag to precede the phrase with\r
+ * @param      string  the closing tag to end the phrase with\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('highlight_phrase'))\r
+{\r
+       function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')\r
+       {\r
+               if ($str == '')\r
+               {\r
+                       return '';\r
+               }\r
+       \r
+               if ($phrase != '')\r
+               {\r
+                       return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Word Wrap\r
+ *\r
+ * Wraps text at the specified character.  Maintains the integrity of words.\r
+ * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor\r
+ * will URLs.\r
+ *\r
+ * @access     public\r
+ * @param      string  the text string\r
+ * @param      integer the number of characters to wrap at\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('word_wrap'))\r
+{\r
+       function word_wrap($str, $charlim = '76')\r
+       {\r
+               // Se the character limit\r
+               if ( ! is_numeric($charlim))\r
+                       $charlim = 76;\r
+       \r
+               // Reduce multiple spaces\r
+               $str = preg_replace("| +|", " ", $str);\r
+       \r
+               // Standardize newlines\r
+               if (strpos($str, "\r") !== FALSE)\r
+               {\r
+                       $str = str_replace(array("\r\n", "\r"), "\n", $str);                    \r
+               }\r
+       \r
+               // If the current word is surrounded by {unwrap} tags we'll \r
+               // strip the entire chunk and replace it with a marker.\r
+               $unwrap = array();\r
+               if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))\r
+               {\r
+                       for ($i = 0; $i < count($matches['0']); $i++)\r
+                       {\r
+                               $unwrap[] = $matches['1'][$i];                          \r
+                               $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);\r
+                       }\r
+               }\r
+       \r
+               // Use PHP's native function to do the initial wordwrap.  \r
+               // We set the cut flag to FALSE so that any individual words that are \r
+               // too long get left alone.  In the next step we'll deal with them.\r
+               $str = wordwrap($str, $charlim, "\n", FALSE);\r
+       \r
+               // Split the string into individual lines of text and cycle through them\r
+               $output = "";\r
+               foreach (explode("\n", $str) as $line) \r
+               {\r
+                       // Is the line within the allowed character count?\r
+                       // If so we'll join it to the output and continue\r
+                       if (strlen($line) <= $charlim)\r
+                       {\r
+                               $output .= $line."\n";                  \r
+                               continue;\r
+                       }\r
+                       \r
+                       $temp = '';\r
+                       while((strlen($line)) > $charlim) \r
+                       {\r
+                               // If the over-length word is a URL we won't wrap it\r
+                               if (preg_match("!\[url.+\]|://|wwww.!", $line))\r
+                               {\r
+                                       break;\r
+                               }\r
+\r
+                               // Trim the word down\r
+                               $temp .= substr($line, 0, $charlim-1);\r
+                               $line = substr($line, $charlim-1);\r
+                       }\r
+               \r
+                       // If $temp contains data it means we had to split up an over-length \r
+                       // word into smaller chunks so we'll add it back to our current line\r
+                       if ($temp != '')\r
+                       {\r
+                               $output .= $temp . "\n" . $line; \r
+                       }\r
+                       else\r
+                       {\r
+                               $output .= $line;\r
+                       }\r
+\r
+                       $output .= "\n";\r
+               }\r
+\r
+               // Put our markers back\r
+               if (count($unwrap) > 0)\r
+               {       \r
+                       foreach ($unwrap as $key => $val)\r
+                       {\r
+                               $output = str_replace("{{unwrapped".$key."}}", $val, $output);\r
+                       }\r
+               }\r
+\r
+               // Remove the unwrap tags\r
+               $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);\r
+\r
+               return $output; \r
+       }\r
+}\r
+\r
+\r
+/* End of file text_helper.php */\r
+/* Location: ./system/helpers/text_helper.php */
\ No newline at end of file
diff --git a/helpers/typography_helper.php b/helpers/typography_helper.php
new file mode 100644 (file)
index 0000000..f1bb25b
--- /dev/null
@@ -0,0 +1,72 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Typography Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/typography_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Convert newlines to HTML line breaks except within PRE tags\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('nl2br_except_pre'))\r
+{\r
+       function nl2br_except_pre($str)\r
+       {\r
+               $CI =& get_instance();\r
+       \r
+               $CI->load->library('typography');\r
+               \r
+               return $CI->typography->nl2br_except_pre($str);\r
+       }\r
+}\r
+       \r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Auto Typography Wrapper Function\r
+ *\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @param      bool    whether to allow javascript event handlers\r
+ * @param      bool    whether to reduce multiple instances of double newlines to two\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('auto_typography'))\r
+{\r
+       function auto_typography($str, $strip_js_event_handlers = TRUE, $reduce_linebreaks = FALSE)\r
+       {\r
+               $CI =& get_instance();  \r
+               $CI->load->library('typography');\r
+               return $CI->typography->auto_typography($str, $strip_js_event_handlers, $reduce_linebreaks);\r
+       }\r
+}\r
+\r
+/* End of file typography_helper.php */\r
+/* Location: ./system/helpers/typography_helper.php */
\ No newline at end of file
diff --git a/helpers/url_helper.php b/helpers/url_helper.php
new file mode 100644 (file)
index 0000000..744295f
--- /dev/null
@@ -0,0 +1,582 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter URL Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/url_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Site URL\r
+ *\r
+ * Create a local URL based on your basepath. Segments can be passed via the\r
+ * first parameter either as a string or an array.\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('site_url'))\r
+{\r
+       function site_url($uri = '')\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->config->site_url($uri);\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Base URL\r
+ *\r
+ * Returns the "base_url" item from your config file\r
+ *\r
+ * @access     public\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('base_url'))\r
+{\r
+       function base_url()\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->config->slash_item('base_url');\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Current URL\r
+ *\r
+ * Returns the full URL (including segments) of the page where this \r
+ * function is placed\r
+ *\r
+ * @access     public\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('current_url'))\r
+{\r
+       function current_url()\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->config->site_url($CI->uri->uri_string());\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+/**\r
+ * URL String\r
+ *\r
+ * Returns the URI segments.\r
+ *\r
+ * @access     public\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('uri_string'))\r
+{\r
+       function uri_string()\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->uri->uri_string();\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Index page\r
+ *\r
+ * Returns the "index_page" from your config file\r
+ *\r
+ * @access     public\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('index_page'))\r
+{\r
+       function index_page()\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->config->item('index_page');\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Anchor Link\r
+ *\r
+ * Creates an anchor based on the local URL.\r
+ *\r
+ * @access     public\r
+ * @param      string  the URL\r
+ * @param      string  the link title\r
+ * @param      mixed   any attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('anchor'))\r
+{\r
+       function anchor($uri = '', $title = '', $attributes = '')\r
+       {\r
+               $title = (string) $title;\r
+\r
+               if ( ! is_array($uri))\r
+               {\r
+                       $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;\r
+               }\r
+               else\r
+               {\r
+                       $site_url = site_url($uri);\r
+               }\r
+\r
+               if ($title == '')\r
+               {\r
+                       $title = $site_url;\r
+               }\r
+\r
+               if ($attributes != '')\r
+               {\r
+                       $attributes = _parse_attributes($attributes);\r
+               }\r
+\r
+               return '<a href="'.$site_url.'"'.$attributes.'>'.$title.'</a>';\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Anchor Link - Pop-up version\r
+ *\r
+ * Creates an anchor based on the local URL. The link\r
+ * opens a new window based on the attributes specified.\r
+ *\r
+ * @access     public\r
+ * @param      string  the URL\r
+ * @param      string  the link title\r
+ * @param      mixed   any attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('anchor_popup'))\r
+{\r
+       function anchor_popup($uri = '', $title = '', $attributes = FALSE)\r
+       {\r
+               $title = (string) $title;\r
+\r
+               $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;\r
+\r
+               if ($title == '')\r
+               {\r
+                       $title = $site_url;\r
+               }\r
+\r
+               if ($attributes === FALSE)\r
+               {\r
+                       return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title."</a>";\r
+               }\r
+\r
+               if ( ! is_array($attributes))\r
+               {\r
+                       $attributes = array();\r
+               }\r
+\r
+               foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)\r
+               {\r
+                       $atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];\r
+                       unset($attributes[$key]);\r
+               }\r
+\r
+               if ($attributes != '')\r
+               {\r
+                       $attributes = _parse_attributes($attributes);\r
+               }\r
+\r
+               return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"$attributes>".$title."</a>";\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Mailto Link\r
+ *\r
+ * @access     public\r
+ * @param      string  the email address\r
+ * @param      string  the link title\r
+ * @param      mixed   any attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('mailto'))\r
+{\r
+       function mailto($email, $title = '', $attributes = '')\r
+       {\r
+               $title = (string) $title;\r
+\r
+               if ($title == "")\r
+               {\r
+                       $title = $email;\r
+               }\r
+\r
+               $attributes = _parse_attributes($attributes);\r
+\r
+               return '<a href="mailto:'.$email.'"'.$attributes.'>'.$title.'</a>';\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Encoded Mailto Link\r
+ *\r
+ * Create a spam-protected mailto link written in Javascript\r
+ *\r
+ * @access     public\r
+ * @param      string  the email address\r
+ * @param      string  the link title\r
+ * @param      mixed   any attributes\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('safe_mailto'))\r
+{\r
+       function safe_mailto($email, $title = '', $attributes = '')\r
+       {\r
+               $title = (string) $title;\r
+\r
+               if ($title == "")\r
+               {\r
+                       $title = $email;\r
+               }\r
+\r
+               for ($i = 0; $i < 16; $i++)\r
+               {\r
+                       $x[] = substr('<a href="mailto:', $i, 1);\r
+               }\r
+\r
+               for ($i = 0; $i < strlen($email); $i++)\r
+               {\r
+                       $x[] = "|".ord(substr($email, $i, 1));\r
+               }\r
+\r
+               $x[] = '"';\r
+\r
+               if ($attributes != '')\r
+               {\r
+                       if (is_array($attributes))\r
+                       {\r
+                               foreach ($attributes as $key => $val)\r
+                               {\r
+                                       $x[] =  ' '.$key.'="';\r
+                                       for ($i = 0; $i < strlen($val); $i++)\r
+                                       {\r
+                                               $x[] = "|".ord(substr($val, $i, 1));\r
+                                       }\r
+                                       $x[] = '"';\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               for ($i = 0; $i < strlen($attributes); $i++)\r
+                               {\r
+                                       $x[] = substr($attributes, $i, 1);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               $x[] = '>';\r
+\r
+               $temp = array();\r
+               for ($i = 0; $i < strlen($title); $i++)\r
+               {\r
+                       $ordinal = ord($title[$i]);\r
+\r
+                       if ($ordinal < 128)\r
+                       {\r
+                               $x[] = "|".$ordinal;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (count($temp) == 0)\r
+                               {\r
+                                       $count = ($ordinal < 224) ? 2 : 3;\r
+                               }\r
+       \r
+                               $temp[] = $ordinal;\r
+                               if (count($temp) == $count)\r
+                               {\r
+                                       $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);\r
+                                       $x[] = "|".$number;\r
+                                       $count = 1;\r
+                                       $temp = array();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>';\r
+\r
+               $x = array_reverse($x);\r
+               ob_start();\r
+\r
+       ?><script type="text/javascript">\r
+       //<![CDATA[\r
+       var l=new Array();\r
+       <?php\r
+       $i = 0;\r
+       foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>\r
+\r
+       for (var i = l.length-1; i >= 0; i=i-1){\r
+       if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");\r
+       else document.write(unescape(l[i]));}\r
+       //]]>\r
+       </script><?php\r
+\r
+               $buffer = ob_get_contents();\r
+               ob_end_clean();\r
+               return $buffer;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Auto-linker\r
+ *\r
+ * Automatically links URL and Email addresses.\r
+ * Note: There's a bit of extra code here to deal with\r
+ * URLs or emails that end in a period.  We'll strip these\r
+ * off and add them after the link.\r
+ *\r
+ * @access     public\r
+ * @param      string  the string\r
+ * @param      string  the type: email, url, or both\r
+ * @param      bool    whether to create pop-up links\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('auto_link'))\r
+{\r
+       function auto_link($str, $type = 'both', $popup = FALSE)\r
+       {\r
+               if ($type != 'email')\r
+               {\r
+                       if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))\r
+                       {\r
+                               $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";\r
+       \r
+                               for ($i = 0; $i < sizeof($matches['0']); $i++)\r
+                               {\r
+                                       $period = '';\r
+                                       if (preg_match("|\.$|", $matches['6'][$i]))\r
+                                       {\r
+                                               $period = '.';\r
+                                               $matches['6'][$i] = substr($matches['6'][$i], 0, -1);\r
+                                       }\r
+               \r
+                                       $str = str_replace($matches['0'][$i],\r
+                                                                               $matches['1'][$i].'<a href="http'.\r
+                                                                               $matches['4'][$i].'://'.\r
+                                                                               $matches['5'][$i].\r
+                                                                               $matches['6'][$i].'"'.$pop.'>http'.\r
+                                                                               $matches['4'][$i].'://'.\r
+                                                                               $matches['5'][$i].\r
+                                                                               $matches['6'][$i].'</a>'.\r
+                                                                               $period, $str);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if ($type != 'url')\r
+               {\r
+                       if (preg_match_all("/([a-zA-Z0-9_\.\-\+Ã…]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))\r
+                       {\r
+                               for ($i = 0; $i < sizeof($matches['0']); $i++)\r
+                               {\r
+                                       $period = '';\r
+                                       if (preg_match("|\.$|", $matches['3'][$i]))\r
+                                       {\r
+                                               $period = '.';\r
+                                               $matches['3'][$i] = substr($matches['3'][$i], 0, -1);\r
+                                       }\r
+               \r
+                                       $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Prep URL\r
+ *\r
+ * Simply adds the http:// part if missing\r
+ *\r
+ * @access     public\r
+ * @param      string  the URL\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('prep_url'))\r
+{\r
+       function prep_url($str = '')\r
+       {\r
+               if ($str == 'http://' OR $str == '')\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')\r
+               {\r
+                       $str = 'http://'.$str;\r
+               }\r
+\r
+               return $str;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Create URL Title\r
+ *\r
+ * Takes a "title" string as input and creates a\r
+ * human-friendly URL string with either a dash\r
+ * or an underscore as the word separator.\r
+ *\r
+ * @access     public\r
+ * @param      string  the string\r
+ * @param      string  the separator: dash, or underscore\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('url_title'))\r
+{\r
+       function url_title($str, $separator = 'dash')\r
+       {\r
+               if ($separator == 'dash')\r
+               {\r
+                       $search         = '_';\r
+                       $replace        = '-';\r
+               }\r
+               else\r
+               {\r
+                       $search         = '-';\r
+                       $replace        = '_';\r
+               }\r
+\r
+               $trans = array(\r
+                                               '&\#\d+?;'                              => '',\r
+                                               '&\S+?;'                                => '',\r
+                                               '\s+'                                   => $replace,\r
+                                               '[^a-z0-9\-\._]'                => '',\r
+                                               $replace.'+'                    => $replace,\r
+                                               $replace.'$'                    => $replace,\r
+                                               '^'.$replace                    => $replace\r
+                                         );\r
+\r
+               $str = strip_tags($str);\r
+\r
+               foreach ($trans as $key => $val)\r
+               {\r
+                       $str = preg_replace("#".$key."#i", $val, $str);\r
+               }\r
+\r
+               return trim(stripslashes($str));\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Header Redirect\r
+ *\r
+ * Header redirect in two flavors\r
+ * For very fine grained control over headers, you could use the Output\r
+ * Library's set_header() function.\r
+ *\r
+ * @access     public\r
+ * @param      string  the URL\r
+ * @param      string  the method: location or redirect\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('redirect'))\r
+{\r
+       function redirect($uri = '', $method = 'location', $http_response_code = 302)\r
+       {\r
+               switch($method)\r
+               {\r
+                       case 'refresh'  : header("Refresh:0;url=".site_url($uri));\r
+                               break;\r
+                       default                 : header("Location: ".site_url($uri), TRUE, $http_response_code);\r
+                               break;\r
+               }\r
+               exit;\r
+       }\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Parse out the attributes\r
+ *\r
+ * Some of the functions use this\r
+ *\r
+ * @access     private\r
+ * @param      array\r
+ * @param      bool\r
+ * @return     string\r
+ */\r
+if ( ! function_exists('_parse_attributes'))\r
+{\r
+       function _parse_attributes($attributes, $javascript = FALSE)\r
+       {\r
+               if (is_string($attributes))\r
+               {\r
+                       return ($attributes != '') ? ' '.$attributes : '';\r
+               }\r
+\r
+               $att = '';\r
+               foreach ($attributes as $key => $val)\r
+               {\r
+                       if ($javascript == TRUE)\r
+                       {\r
+                               $att .= $key . '=' . $val . ',';\r
+                       }\r
+                       else\r
+                       {\r
+                               $att .= ' ' . $key . '="' . $val . '"';\r
+                       }\r
+               }\r
+\r
+               if ($javascript == TRUE AND $att != '')\r
+               {\r
+                       $att = substr($att, 0, -1);\r
+               }\r
+\r
+               return $att;\r
+       }\r
+}\r
+\r
+\r
+/* End of file url_helper.php */\r
+/* Location: ./system/helpers/url_helper.php */
\ No newline at end of file
diff --git a/helpers/xml_helper.php b/helpers/xml_helper.php
new file mode 100644 (file)
index 0000000..83e2bb3
--- /dev/null
@@ -0,0 +1,62 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter XML Helpers\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Helpers\r
+ * @category   Helpers\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/helpers/xml_helper.html\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Convert Reserved XML characters to Entities\r
+ *\r
+ * @access     public\r
+ * @param      string\r
+ * @return     string\r
+ */    \r
+if ( ! function_exists('xml_convert'))\r
+{\r
+       function xml_convert($str)\r
+       {\r
+               $temp = '__TEMP_AMPERSANDS__';\r
+\r
+               // Replace entities to temporary markers so that \r
+               // ampersands won't get messed up\r
+               $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);\r
+               $str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);\r
+       \r
+               $str = str_replace(array("&","<",">","\"", "'", "-"),\r
+                                                  array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),\r
+                                                  $str);\r
+\r
+               // Decode the temp markers back to entities             \r
+               $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);\r
+               $str = preg_replace("/$temp(\w+);/","&\\1;", $str);\r
+               \r
+               return $str;\r
+       }\r
+}\r
+\r
+\r
+/* End of file xml_helper.php */\r
+/* Location: ./system/helpers/xml_helper.php */
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..7ea14c4
--- /dev/null
+++ b/index.php
@@ -0,0 +1,118 @@
+<?php
+/*
+|---------------------------------------------------------------
+| PHP ERROR REPORTING LEVEL
+|---------------------------------------------------------------
+|
+| By default CI runs with error reporting set to ALL.  For security
+| reasons you are encouraged to change this when your site goes live.
+| For more info visit:  http://www.php.net/error_reporting
+|
+*/
+       error_reporting(E_ALL);
+
+/*
+|---------------------------------------------------------------
+| SYSTEM FOLDER NAME
+|---------------------------------------------------------------
+|
+| This variable must contain the name of your "system" folder.
+| Include the path if the folder is not in the same  directory
+| as this file.
+|
+| NO TRAILING SLASH!
+|
+*/
+       $system_folder = ".";
+
+/*
+|---------------------------------------------------------------
+| APPLICATION FOLDER NAME
+|---------------------------------------------------------------
+|
+| If you want this front controller to use a different "application"
+| folder then the default one you can set its name here. The folder 
+| can also be renamed or relocated anywhere on your server.
+| For more info please see the user guide:
+| http://codeigniter.com/user_guide/general/managing_apps.html
+|
+|
+| NO TRAILING SLASH!
+|
+*/
+       $application_folder = "application";
+
+/*
+|===============================================================
+| END OF USER CONFIGURABLE SETTINGS
+|===============================================================
+*/
+
+
+/*
+|---------------------------------------------------------------
+| SET THE SERVER PATH
+|---------------------------------------------------------------
+|
+| Let's attempt to determine the full-server path to the "system"
+| folder in order to reduce the possibility of path problems.
+| Note: We only attempt this if the user hasn't specified a 
+| full server path.
+|
+*/
+if (strpos($system_folder, '/') === FALSE)
+{
+       if (function_exists('realpath') AND @realpath(dirname(__FILE__)) !== FALSE)
+       {
+               $system_folder = realpath(dirname(__FILE__)).'/'.$system_folder;
+       }
+}
+else
+{
+       // Swap directory separators to Unix style for consistency
+       $system_folder = str_replace("\\", "/", $system_folder); 
+}
+
+/*
+|---------------------------------------------------------------
+| DEFINE APPLICATION CONSTANTS
+|---------------------------------------------------------------
+|
+| EXT          - The file extension.  Typically ".php"
+| FCPATH       - The full server path to THIS file
+| SELF         - The name of THIS file (typically "index.php")
+| BASEPATH     - The full server path to the "system" folder
+| APPPATH      - The full server path to the "application" folder
+|
+*/
+define('EXT', '.'.pathinfo(__FILE__, PATHINFO_EXTENSION));
+define('FCPATH', __FILE__);
+define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
+define('BASEPATH', $system_folder.'/');
+
+if (is_dir($application_folder))
+{
+       define('APPPATH', $application_folder.'/');
+}
+else
+{
+       if ($application_folder == '')
+       {
+               $application_folder = 'application';
+       }
+
+       define('APPPATH', BASEPATH.$application_folder.'/');
+}
+
+/*
+|---------------------------------------------------------------
+| LOAD THE FRONT CONTROLLER
+|---------------------------------------------------------------
+|
+| And away we go...
+|
+*/
+require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;
+
+/* End of file index.php */
+/* Location: ./index.php */
diff --git a/language/english/calendar_lang.php b/language/english/calendar_lang.php
new file mode 100644 (file)
index 0000000..107c0f7
--- /dev/null
@@ -0,0 +1,51 @@
+<?php\r
+\r
+$lang['cal_su']                        = "Su";\r
+$lang['cal_mo']                = "Mo";\r
+$lang['cal_tu']                = "Tu";\r
+$lang['cal_we']                = "We";\r
+$lang['cal_th']                = "Th";\r
+$lang['cal_fr']                = "Fr";\r
+$lang['cal_sa']                = "Sa";\r
+$lang['cal_sun']               = "Sun";\r
+$lang['cal_mon']               = "Mon";\r
+$lang['cal_tue']               = "Tue";\r
+$lang['cal_wed']               = "Wed";\r
+$lang['cal_thu']               = "Thu";\r
+$lang['cal_fri']               = "Fri";\r
+$lang['cal_sat']               = "Sat";\r
+$lang['cal_sunday']            = "Sunday";\r
+$lang['cal_monday']            = "Monday";\r
+$lang['cal_tuesday']   = "Tuesday";\r
+$lang['cal_wednesday'] = "Wednesday";\r
+$lang['cal_thursday']  = "Thursday";\r
+$lang['cal_friday']            = "Friday";\r
+$lang['cal_saturday']  = "Saturday";\r
+$lang['cal_jan']               = "Jan";\r
+$lang['cal_feb']               = "Feb";\r
+$lang['cal_mar']               = "Mar";\r
+$lang['cal_apr']               = "Apr";\r
+$lang['cal_may']               = "May";\r
+$lang['cal_jun']               = "Jun";\r
+$lang['cal_jul']               = "Jul";\r
+$lang['cal_aug']               = "Aug";\r
+$lang['cal_sep']               = "Sep";\r
+$lang['cal_oct']               = "Oct";\r
+$lang['cal_nov']               = "Nov";\r
+$lang['cal_dec']               = "Dec";\r
+$lang['cal_january']   = "January";\r
+$lang['cal_february']  = "February";\r
+$lang['cal_march']             = "March";\r
+$lang['cal_april']             = "April";\r
+$lang['cal_mayl']              = "May";\r
+$lang['cal_june']              = "June";\r
+$lang['cal_july']              = "July";\r
+$lang['cal_august']            = "August";\r
+$lang['cal_september'] = "September";\r
+$lang['cal_october']   = "October";\r
+$lang['cal_november']  = "November";\r
+$lang['cal_december']  = "December";\r
+\r
+
+/* End of file calendar_lang.php */
+/* Location: ./system/language/english/calendar_lang.php */
\ No newline at end of file
diff --git a/language/english/date_lang.php b/language/english/date_lang.php
new file mode 100644 (file)
index 0000000..29b00f5
--- /dev/null
@@ -0,0 +1,60 @@
+<?php\r
+\r
+$lang['date_year'] = "Year";\r
+$lang['date_years'] = "Years";\r
+$lang['date_month'] = "Month";\r
+$lang['date_months'] = "Months";\r
+$lang['date_week'] = "Week";\r
+$lang['date_weeks'] = "Weeks";\r
+$lang['date_day'] = "Day";\r
+$lang['date_days'] = "Days";\r
+$lang['date_hour'] = "Hour";\r
+$lang['date_hours'] = "Hours";\r
+$lang['date_minute'] = "Minute";\r
+$lang['date_minutes'] = "Minutes";\r
+$lang['date_second'] = "Second";\r
+$lang['date_seconds'] = "Seconds";\r
+\r
+$lang['UM12']  = '(UTC -12:00) Baker/Howland Island';\r
+$lang['UM11']  = '(UTC -11:00) Samoa Time Zone, Niue';\r
+$lang['UM10']  = '(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti';\r
+$lang['UM95']  = '(UTC -9:30) Marquesas Islands';\r
+$lang['UM9']   = '(UTC -9:00) Alaska Standard Time, Gambier Islands';\r
+$lang['UM8']   = '(UTC -8:00) Pacific Standard Time, Clipperton Island';\r
+$lang['UM7']   = '(UTC -7:00) Mountain Standard Time';\r
+$lang['UM6']   = '(UTC -6:00) Central Standard Time';\r
+$lang['UM5']   = '(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time';\r
+$lang['UM45']  = '(UTC -4:30) Venezuelan Standard Time';\r
+$lang['UM4']   = '(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time';\r
+$lang['UM35']  = '(UTC -3:30) Newfoundland Standard Time';\r
+$lang['UM3']   = '(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay';\r
+$lang['UM2']   = '(UTC -2:00) South Georgia/South Sandwich Islands';\r
+$lang['UM1']   = '(UTC -1:00) Azores, Cape Verde Islands';\r
+$lang['UTC']   = '(UTC) Greenwich Mean Time, Western European Time';\r
+$lang['UP1']   = '(UTC +1:00) Central European Time, West Africa Time';\r
+$lang['UP2']   = '(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time';\r
+$lang['UP3']   = '(UTC +3:00) Moscow Time, East Africa Time';\r
+$lang['UP35']  = '(UTC +3:30) Iran Standard Time';\r
+$lang['UP4']   = '(UTC +4:00) Azerbaijan Standard Time, Samara Time';\r
+$lang['UP45']  = '(UTC +4:30) Afghanistan';\r
+$lang['UP5']   = '(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time';\r
+$lang['UP55']  = '(UTC +5:30) Indian Standard Time, Sri Lanka Time';\r
+$lang['UP575'] = '(UTC +5:45) Nepal Time';\r
+$lang['UP6']   = '(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time';\r
+$lang['UP65']  = '(UTC +6:30) Cocos Islands, Myanmar';\r
+$lang['UP7']   = '(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam';\r
+$lang['UP8']   = '(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time';\r
+$lang['UP875'] = '(UTC +8:45) Australian Central Western Standard Time';\r
+$lang['UP9']   = '(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time';\r
+$lang['UP95']  = '(UTC +9:30) Australian Central Standard Time';\r
+$lang['UP10']  = '(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time';\r
+$lang['UP105'] = '(UTC +10:30) Lord Howe Island';\r
+$lang['UP11']  = '(UTC +11:00) Magadan Time, Solomon Islands, Vanuatu';\r
+$lang['UP115'] = '(UTC +11:30) Norfolk Island';\r
+$lang['UP12']  = '(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time';\r
+$lang['UP1275']        = '(UTC +12:45) Chatham Islands Standard Time';\r
+$lang['UP13']  = '(UTC +13:00) Phoenix Islands Time, Tonga';\r
+$lang['UP14']  = '(UTC +14:00) Line Islands';\r
+\r
+/* End of file date_lang.php */\r
+/* Location: ./system/language/english/date_lang.php */
\ No newline at end of file
diff --git a/language/english/db_lang.php b/language/english/db_lang.php
new file mode 100644 (file)
index 0000000..2f7ccb5
--- /dev/null
@@ -0,0 +1,28 @@
+<?php\r
+\r
+$lang['db_invalid_connection_str'] = 'Unable to determine the database settings based on the connection string you submitted.';\r
+$lang['db_unable_to_connect'] = 'Unable to connect to your database server using the provided settings.';\r
+$lang['db_unable_to_select'] = 'Unable to select the specified database: %s';\r
+$lang['db_unable_to_create'] = 'Unable to create the specified database: %s';\r
+$lang['db_invalid_query'] = 'The query you submitted is not valid.';\r
+$lang['db_must_set_table'] = 'You must set the database table to be used with your query.';\r
+$lang['db_must_set_database'] = 'You must set the database name in your database config file.';\r
+$lang['db_must_use_set'] = 'You must use the "set" method to update an entry.';\r
+$lang['db_must_use_where'] = 'Updates are not allowed unless they contain a "where" clause.';\r
+$lang['db_del_must_use_where'] = 'Deletes are not allowed unless they contain a "where" or "like" clause.';\r
+$lang['db_field_param_missing'] = 'To fetch fields requires the name of the table as a parameter.';\r
+$lang['db_unsupported_function'] = 'This feature is not available for the database you are using.';\r
+$lang['db_transaction_failure'] = 'Transaction failure: Rollback performed.';\r
+$lang['db_unable_to_drop'] = 'Unable to drop the specified database.';\r
+$lang['db_unsuported_feature'] = 'Unsupported feature of the database platform you are using.';\r
+$lang['db_unsuported_compression'] = 'The file compression format you chose is not supported by your server.';\r
+$lang['db_filepath_error'] = 'Unable to write data to the file path you have submitted.';\r
+$lang['db_invalid_cache_path'] = 'The cache path you submitted is not valid or writable.';\r
+$lang['db_table_name_required'] = 'A table name is required for that operation.';\r
+$lang['db_column_name_required'] = 'A column name is required for that operation.';\r
+$lang['db_column_definition_required'] = 'A column definition is required for that operation.';\r
+$lang['db_unable_to_set_charset'] = 'Unable to set client connection character set: %s';\r
+$lang['db_error_heading'] = 'A Database Error Occurred';\r
+\r
+/* End of file db_lang.php */\r
+/* Location: ./system/language/english/db_lang.php */
\ No newline at end of file
diff --git a/language/english/email_lang.php b/language/english/email_lang.php
new file mode 100644 (file)
index 0000000..3e94bf3
--- /dev/null
@@ -0,0 +1,23 @@
+<?php\r
+\r
+$lang['email_must_be_array'] = "The email validation method must be passed an array.";\r
+$lang['email_invalid_address'] = "Invalid email address: %s";\r
+$lang['email_attachment_missing'] = "Unable to locate the following email attachment: %s";\r
+$lang['email_attachment_unreadable'] = "Unable to open this attachment: %s";\r
+$lang['email_no_recipients'] = "You must include recipients: To, Cc, or Bcc";\r
+$lang['email_send_failure_phpmail'] = "Unable to send email using PHP mail().  Your server might not be configured to send mail using this method.";\r
+$lang['email_send_failure_sendmail'] = "Unable to send email using PHP Sendmail.  Your server might not be configured to send mail using this method.";\r
+$lang['email_send_failure_smtp'] = "Unable to send email using PHP SMTP.  Your server might not be configured to send mail using this method.";\r
+$lang['email_sent'] = "Your message has been successfully sent using the following protocol: %s";\r
+$lang['email_no_socket'] = "Unable to open a socket to Sendmail. Please check settings.";\r
+$lang['email_no_hostname'] = "You did not specify a SMTP hostname.";\r
+$lang['email_smtp_error'] = "The following SMTP error was encountered: %s";\r
+$lang['email_no_smtp_unpw'] = "Error: You must assign a SMTP username and password.";\r
+$lang['email_failed_smtp_login'] = "Failed to send AUTH LOGIN command. Error: %s";\r
+$lang['email_smtp_auth_un'] = "Failed to authenticate username. Error: %s";\r
+$lang['email_smtp_auth_pw'] = "Failed to authenticate password. Error: %s";\r
+$lang['email_smtp_data_failure'] = "Unable to send data: %s";\r
+\r
+
+/* End of file email_lang.php */
+/* Location: ./system/language/english/email_lang.php */
\ No newline at end of file
diff --git a/language/english/form_validation_lang.php b/language/english/form_validation_lang.php
new file mode 100644 (file)
index 0000000..c157fe4
--- /dev/null
@@ -0,0 +1,24 @@
+<?php\r
+\r
+$lang['required']                      = "The %s field is required.";\r
+$lang['isset']                         = "The %s field must have a value.";\r
+$lang['valid_email']           = "The %s field must contain a valid email address.";\r
+$lang['valid_emails']          = "The %s field must contain all valid email addresses.";\r
+$lang['valid_url']                     = "The %s field must contain a valid URL.";\r
+$lang['valid_ip']                      = "The %s field must contain a valid IP.";\r
+$lang['min_length']                    = "The %s field must be at least %s characters in length.";\r
+$lang['max_length']                    = "The %s field can not exceed %s characters in length.";\r
+$lang['exact_length']          = "The %s field must be exactly %s characters in length.";\r
+$lang['alpha']                         = "The %s field may only contain alphabetical characters.";\r
+$lang['alpha_numeric']         = "The %s field may only contain alpha-numeric characters.";\r
+$lang['alpha_dash']                    = "The %s field may only contain alpha-numeric characters, underscores, and dashes.";\r
+$lang['numeric']                       = "The %s field must contain only numbers.";\r
+$lang['is_numeric']                    = "The %s field must contain only numeric characters.";\r
+$lang['integer']                       = "The %s field must contain an integer.";\r
+$lang['matches']                       = "The %s field does not match the %s field.";\r
+$lang['is_natural']                    = "The %s field must contain only positive numbers.";\r
+$lang['is_natural_no_zero']    = "The %s field must contain a number greater than zero.";\r
+\r
+\r
+/* End of file form_validation_lang.php */\r
+/* Location: ./system/language/english/form_validation_lang.php */
\ No newline at end of file
diff --git a/language/english/ftp_lang.php b/language/english/ftp_lang.php
new file mode 100644 (file)
index 0000000..e014028
--- /dev/null
@@ -0,0 +1,17 @@
+<?php\r
+\r
+$lang['ftp_no_connection']                     = "Unable to locate a valid connection ID.  Please make sure you are connected before peforming any file routines.";\r
+$lang['ftp_unable_to_connect']         = "Unable to connect to your FTP server using the supplied hostname.";\r
+$lang['ftp_unable_to_login']           = "Unable to login to your FTP server.  Please check your username and password.";\r
+$lang['ftp_unable_to_makdir']          = "Unable to create the directory you have specified.";\r
+$lang['ftp_unable_to_changedir']       = "Unable to change directories.";\r
+$lang['ftp_unable_to_chmod']           = "Unable to set file permissions.  Please check your path.  Note: This feature is only available in PHP 5 or higher.";\r
+$lang['ftp_unable_to_upload']          = "Unable to upload the specified file.  Please check your path.";\r
+$lang['ftp_no_source_file']                    = "Unable to locate the source file.  Please check your path.";\r
+$lang['ftp_unable_to_rename']          = "Unable to rename the file.";\r
+$lang['ftp_unable_to_delete']          = "Unable to delete the file.";\r
+$lang['ftp_unable_to_move']                    = "Unable to move the file.  Please make sure the destination directory exists.";\r
+\r
+
+/* End of file ftp_lang.php */
+/* Location: ./system/language/english/ftp_lang.php */
\ No newline at end of file
diff --git a/language/english/imglib_lang.php b/language/english/imglib_lang.php
new file mode 100644 (file)
index 0000000..4baf971
--- /dev/null
@@ -0,0 +1,23 @@
+<?php\r
+\r
+$lang['imglib_source_image_required'] = "You must specify a source image in your preferences.";\r
+$lang['imglib_gd_required'] = "The GD image library is required for this feature.";\r
+$lang['imglib_gd_required_for_props'] = "Your server must support the GD image library in order to determine the image properties.";\r
+$lang['imglib_unsupported_imagecreate'] = "Your server does not support the GD function required to process this type of image.";\r
+$lang['imglib_gif_not_supported'] = "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.";\r
+$lang['imglib_jpg_not_supported'] = "JPG images are not supported.";\r
+$lang['imglib_png_not_supported'] = "PNG images are not supported.";\r
+$lang['imglib_jpg_or_png_required'] = "The image resize protocol specified in your preferences only works with JPEG or PNG image types.";\r
+$lang['imglib_copy_error'] = "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.";\r
+$lang['imglib_rotate_unsupported'] = "Image rotation does not appear to be supported by your server.";\r
+$lang['imglib_libpath_invalid'] = "The path to your image library is not correct.  Please set the correct path in your image preferences.";\r
+$lang['imglib_image_process_failed'] = "Image processing failed.  Please verify that your server supports the chosen protocol and that the path to your image library is correct.";\r
+$lang['imglib_rotation_angle_required'] = "An angle of rotation is required to rotate the image.";\r
+$lang['imglib_writing_failed_gif'] = "GIF image.";\r
+$lang['imglib_invalid_path'] = "The path to the image is not correct.";\r
+$lang['imglib_copy_failed'] = "The image copy routine failed.";\r
+$lang['imglib_missing_font'] = "Unable to find a font to use.";\r
+\r
+
+/* End of file imglib_lang.php */
+/* Location: ./system/language/english/imglib_lang.php */
\ No newline at end of file
diff --git a/language/english/index.html b/language/english/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/language/english/number_lang.php b/language/english/number_lang.php
new file mode 100644 (file)
index 0000000..f9b9166
--- /dev/null
@@ -0,0 +1,10 @@
+<?php\r
+\r
+$lang['terabyte_abbr'] = "TB";\r
+$lang['gigabyte_abbr'] = "GB";\r
+$lang['megabyte_abbr'] = "MB";\r
+$lang['kilobyte_abbr'] = "KB";\r
+$lang['bytes'] = "Bytes";\r
+\r
+/* End of file number_lang.php */\r
+/* Location: ./system/language/english/number_lang.php */
\ No newline at end of file
diff --git a/language/english/profiler_lang.php b/language/english/profiler_lang.php
new file mode 100644 (file)
index 0000000..7c40e3f
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+$lang['profiler_database']               = 'DATABASE';
+$lang['profiler_controller_info'] = 'CLASS/METHOD';
+$lang['profiler_benchmarks']   = 'BENCHMARKS';
+$lang['profiler_queries']              = 'QUERIES';
+$lang['profiler_get_data']             = 'GET DATA';
+$lang['profiler_post_data']            = 'POST DATA';
+$lang['profiler_uri_string']   = 'URI STRING';
+$lang['profiler_memory_usage'] = 'MEMORY USAGE';
+$lang['profiler_no_db']                        = 'Database driver is not currently loaded';
+$lang['profiler_no_queries']   = 'No queries were run';
+$lang['profiler_no_post']              = 'No POST data exists';
+$lang['profiler_no_get']               = 'No GET data exists';
+$lang['profiler_no_uri']               = 'No URI data exists';
+$lang['profiler_no_memory']            = 'Memory Usage Unavailable';
+
+/* End of file profiler_lang.php */
+/* Location: ./system/language/english/profiler_lang.php */
\ No newline at end of file
diff --git a/language/english/scaffolding_lang.php b/language/english/scaffolding_lang.php
new file mode 100644 (file)
index 0000000..c4d54d5
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+$lang['scaff_view_records']            = 'View Records';
+$lang['scaff_create_record']   = 'Create New Record';
+$lang['scaff_add']                             = 'Add Data';
+$lang['scaff_view']                            = 'View Data';
+$lang['scaff_edit']                            = 'Edit';
+$lang['scaff_delete']                  = 'Delete';
+$lang['scaff_view_all']                        = 'View All';
+$lang['scaff_yes']                             = 'Yes';
+$lang['scaff_no']                              = 'No';
+$lang['scaff_no_data']                 = 'No data exists for this table yet.';
+$lang['scaff_del_confirm']             = 'Are you sure you want to delete the following row:';
+
+
+/* End of file scaffolding_lang.php */
+/* Location: ./system/language/english/scaffolding_lang.php */
\ No newline at end of file
diff --git a/language/english/unit_test_lang.php b/language/english/unit_test_lang.php
new file mode 100644 (file)
index 0000000..7e1b616
--- /dev/null
@@ -0,0 +1,24 @@
+<?php\r
+\r
+$lang['ut_test_name']          = 'Test Name';\r
+$lang['ut_test_datatype']      = 'Test Datatype';\r
+$lang['ut_res_datatype']       = 'Expected Datatype';\r
+$lang['ut_result']                     = 'Result';\r
+$lang['ut_undefined']          = 'Undefined Test Name';\r
+$lang['ut_file']                       = 'File Name';\r
+$lang['ut_line']                       = 'Line Number';\r
+$lang['ut_passed']                     = 'Passed';\r
+$lang['ut_failed']                     = 'Failed';\r
+$lang['ut_boolean']                    = 'Boolean';\r
+$lang['ut_integer']                    = 'Integer';\r
+$lang['ut_float']                      = 'Float';\r
+$lang['ut_double']                     = 'Float'; // can be the same as float\r
+$lang['ut_string']                     = 'String';\r
+$lang['ut_array']                      = 'Array';\r
+$lang['ut_object']                     = 'Object';\r
+$lang['ut_resource']           = 'Resource';\r
+$lang['ut_null']                       = 'Null';\r
+\r
+\r
+/* End of file unit_test_lang.php */\r
+/* Location: ./system/language/english/unit_test_lang.php */
\ No newline at end of file
diff --git a/language/english/upload_lang.php b/language/english/upload_lang.php
new file mode 100644 (file)
index 0000000..5f7d449
--- /dev/null
@@ -0,0 +1,22 @@
+<?php\r
+\r
+$lang['upload_userfile_not_set'] = "Unable to find a post variable called userfile.";\r
+$lang['upload_file_exceeds_limit'] = "The uploaded file exceeds the maximum allowed size in your PHP configuration file.";\r
+$lang['upload_file_exceeds_form_limit'] = "The uploaded file exceeds the maximum size allowed by the submission form.";\r
+$lang['upload_file_partial'] = "The file was only partially uploaded.";\r
+$lang['upload_no_temp_directory'] = "The temporary folder is missing.";\r
+$lang['upload_unable_to_write_file'] = "The file could not be written to disk.";\r
+$lang['upload_stopped_by_extension'] = "The file upload was stopped by extension.";\r
+$lang['upload_no_file_selected'] = "You did not select a file to upload.";\r
+$lang['upload_invalid_filetype'] = "The filetype you are attempting to upload is not allowed.";\r
+$lang['upload_invalid_filesize'] = "The file you are attempting to upload is larger than the permitted size.";\r
+$lang['upload_invalid_dimensions'] = "The image you are attempting to upload exceedes the maximum height or width.";\r
+$lang['upload_destination_error'] = "A problem was encountered while attempting to move the uploaded file to the final destination.";\r
+$lang['upload_no_filepath'] = "The upload path does not appear to be valid.";\r
+$lang['upload_no_file_types'] = "You have not specified any allowed file types.";\r
+$lang['upload_bad_filename'] = "The file name you submitted already exists on the server.";\r
+$lang['upload_not_writable'] = "The upload destination folder does not appear to be writable.";\r
+\r
+
+/* End of file upload_lang.php */
+/* Location: ./system/language/english/upload_lang.php */
\ No newline at end of file
diff --git a/language/english/validation_lang.php b/language/english/validation_lang.php
new file mode 100644 (file)
index 0000000..7ca762d
--- /dev/null
@@ -0,0 +1,24 @@
+<?php\r
+\r
+$lang['required']                      = "The %s field is required.";\r
+$lang['isset']                         = "The %s field must have a value.";\r
+$lang['valid_email']           = "The %s field must contain a valid email address.";\r
+$lang['valid_emails']          = "The %s field must contain all valid email addresses.";\r
+$lang['valid_url']                     = "The %s field must contain a valid URL.";\r
+$lang['valid_ip']                      = "The %s field must contain a valid IP.";\r
+$lang['min_length']                    = "The %s field must be at least %s characters in length.";\r
+$lang['max_length']                    = "The %s field can not exceed %s characters in length.";\r
+$lang['exact_length']          = "The %s field must be exactly %s characters in length.";\r
+$lang['alpha']                         = "The %s field may only contain alphabetical characters.";\r
+$lang['alpha_numeric']         = "The %s field may only contain alpha-numeric characters.";\r
+$lang['alpha_dash']                    = "The %s field may only contain alpha-numeric characters, underscores, and dashes.";\r
+$lang['numeric']                       = "The %s field must contain a number.";\r
+$lang['is_numeric']                    = "The %s field must contain a number.";\r
+$lang['integer']                       = "The %s field must contain an integer.";\r
+$lang['matches']                       = "The %s field does not match the %s field.";\r
+$lang['is_natural']                    = "The %s field must contain a number.";\r
+$lang['is_natural_no_zero']    = "The %s field must contain a number greater than zero.";\r
+\r
+\r
+/* End of file validation_lang.php */\r
+/* Location: ./system/language/english/validation_lang.php */
\ No newline at end of file
diff --git a/language/index.html b/language/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/libraries/Benchmark.php b/libraries/Benchmark.php
new file mode 100644 (file)
index 0000000..4984bb1
--- /dev/null
@@ -0,0 +1,113 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Benchmark Class\r
+ *\r
+ * This class enables you to mark points and calculate the time difference\r
+ * between them.  Memory consumption can also be displayed.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/benchmark.html\r
+ */\r
+class CI_Benchmark {\r
+\r
+       var $marker = array();\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set a benchmark marker\r
+        *\r
+        * Multiple calls to this function can be made so that several\r
+        * execution points can be timed\r
+        *\r
+        * @access      public\r
+        * @param       string  $name   name of the marker\r
+        * @return      void\r
+        */\r
+       function mark($name)\r
+       {\r
+               $this->marker[$name] = microtime();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Calculates the time difference between two marked points.\r
+        *\r
+        * If the first parameter is empty this function instead returns the\r
+        * {elapsed_time} pseudo-variable. This permits the full system\r
+        * execution time to be shown in a template. The output class will\r
+        * swap the real value for this variable.\r
+        *\r
+        * @access      public\r
+        * @param       string  a particular marked point\r
+        * @param       string  a particular marked point\r
+        * @param       integer the number of decimal places\r
+        * @return      mixed\r
+        */\r
+       function elapsed_time($point1 = '', $point2 = '', $decimals = 4)\r
+       {\r
+               if ($point1 == '')\r
+               {\r
+                       return '{elapsed_time}';\r
+               }\r
+\r
+               if ( ! isset($this->marker[$point1]))\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               if ( ! isset($this->marker[$point2]))\r
+               {\r
+                       $this->marker[$point2] = microtime();\r
+               }\r
+       \r
+               list($sm, $ss) = explode(' ', $this->marker[$point1]);\r
+               list($em, $es) = explode(' ', $this->marker[$point2]);\r
+\r
+               return number_format(($em + $es) - ($sm + $ss), $decimals);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Memory Usage\r
+        *\r
+        * This function returns the {memory_usage} pseudo-variable.\r
+        * This permits it to be put it anywhere in a template\r
+        * without the memory being calculated until the end.\r
+        * The output class will swap the real value for this variable.\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function memory_usage()\r
+       {\r
+               return '{memory_usage}';\r
+       }\r
+\r
+}\r
+\r
+// END CI_Benchmark class\r
+\r
+/* End of file Benchmark.php */\r
+/* Location: ./system/libraries/Benchmark.php */
\ No newline at end of file
diff --git a/libraries/Calendar.php b/libraries/Calendar.php
new file mode 100644 (file)
index 0000000..dcf8a12
--- /dev/null
@@ -0,0 +1,477 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Calendar Class\r
+ *\r
+ * This class enables the creation of calendars\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/calendar.html\r
+ */\r
+class CI_Calendar {\r
+\r
+       var $CI;\r
+       var $lang;\r
+       var $local_time;\r
+       var $template           = '';\r
+       var $start_day          = 'sunday';\r
+       var $month_type         = 'long';\r
+       var $day_type           = 'abr';\r
+       var $show_next_prev     = FALSE;\r
+       var $next_prev_url      = '';\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Loads the calendar language file and sets the default time reference\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Calendar($config = array())\r
+       {               \r
+               $this->CI =& get_instance();\r
+               \r
+               if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE))\r
+               {\r
+                       $this->CI->lang->load('calendar');\r
+               }\r
+\r
+               $this->local_time = time();\r
+               \r
+               if (count($config) > 0)\r
+               {\r
+                       $this->initialize($config);\r
+               }\r
+               \r
+               log_message('debug', "Calendar Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Initialize the user preferences\r
+        *\r
+        * Accepts an associative array as input, containing display preferences\r
+        *\r
+        * @access      public\r
+        * @param       array   config preferences\r
+        * @return      void\r
+        */     \r
+       function initialize($config = array())\r
+       {\r
+               foreach ($config as $key => $val)\r
+               {\r
+                       if (isset($this->$key))\r
+                       {\r
+                               $this->$key = $val;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate the calendar\r
+        *\r
+        * @access      public\r
+        * @param       integer the year\r
+        * @param       integer the month\r
+        * @param       array   the data to be shown in the calendar cells\r
+        * @return      string\r
+        */\r
+       function generate($year = '', $month = '', $data = array())\r
+       {\r
+               // Set and validate the supplied month/year\r
+               if ($year == '')\r
+                       $year  = date("Y", $this->local_time);\r
+                       \r
+               if ($month == '')\r
+                       $month = date("m", $this->local_time);\r
+                       \r
+               if (strlen($year) == 1)\r
+                       $year = '200'.$year;\r
+               \r
+               if (strlen($year) == 2)\r
+                       $year = '20'.$year;\r
+\r
+               if (strlen($month) == 1)\r
+                       $month = '0'.$month;\r
+               \r
+               $adjusted_date = $this->adjust_date($month, $year);\r
+               \r
+               $month  = $adjusted_date['month'];\r
+               $year   = $adjusted_date['year'];\r
+               \r
+               // Determine the total days in the month\r
+               $total_days = $this->get_total_days($month, $year);\r
+                                               \r
+               // Set the starting day of the week\r
+               $start_days     = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);\r
+               $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];\r
+               \r
+               // Set the starting day number\r
+               $local_date = mktime(12, 0, 0, $month, 1, $year);\r
+               $date = getdate($local_date);\r
+               $day  = $start_day + 1 - $date["wday"];\r
+               \r
+               while ($day > 1)\r
+               {\r
+                       $day -= 7;\r
+               }\r
+               \r
+               // Set the current month/year/day\r
+               // We use this to determine the "today" date\r
+               $cur_year       = date("Y", $this->local_time);\r
+               $cur_month      = date("m", $this->local_time);\r
+               $cur_day        = date("j", $this->local_time);\r
+               \r
+               $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;\r
+       \r
+               // Generate the template data array\r
+               $this->parse_template();\r
+       \r
+               // Begin building the calendar output                                           \r
+               $out = $this->temp['table_open'];\r
+               $out .= "\n";   \r
+\r
+               $out .= "\n";           \r
+               $out .= $this->temp['heading_row_start'];\r
+               $out .= "\n";\r
+               \r
+               // "previous" month link\r
+               if ($this->show_next_prev == TRUE)\r
+               {\r
+                       // Add a trailing slash to the  URL if needed\r
+                       $this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->next_prev_url);\r
+               \r
+                       $adjusted_date = $this->adjust_date($month - 1, $year);\r
+                       $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);\r
+                       $out .= "\n";\r
+               }\r
+\r
+               // Heading containing the month/year\r
+               $colspan = ($this->show_next_prev == TRUE) ? 5 : 7;\r
+               \r
+               $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);\r
+               $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);\r
+               \r
+               $out .= $this->temp['heading_title_cell'];\r
+               $out .= "\n";\r
+\r
+               // "next" month link\r
+               if ($this->show_next_prev == TRUE)\r
+               {               \r
+                       $adjusted_date = $this->adjust_date($month + 1, $year);\r
+                       $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);\r
+               }\r
+\r
+               $out .= "\n";           \r
+               $out .= $this->temp['heading_row_end'];\r
+               $out .= "\n";\r
+\r
+               // Write the cells containing the days of the week\r
+               $out .= "\n";   \r
+               $out .= $this->temp['week_row_start'];\r
+               $out .= "\n";\r
+\r
+               $day_names = $this->get_day_names();\r
+\r
+               for ($i = 0; $i < 7; $i ++)\r
+               {\r
+                       $out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);\r
+               }\r
+\r
+               $out .= "\n";\r
+               $out .= $this->temp['week_row_end'];\r
+               $out .= "\n";\r
+\r
+               // Build the main body of the calendar\r
+               while ($day <= $total_days)\r
+               {\r
+                       $out .= "\n";\r
+                       $out .= $this->temp['cal_row_start'];\r
+                       $out .= "\n";\r
+\r
+                       for ($i = 0; $i < 7; $i++)\r
+                       {\r
+                               $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];\r
+                       \r
+                               if ($day > 0 AND $day <= $total_days)\r
+                               {                                       \r
+                                       if (isset($data[$day]))\r
+                                       {       \r
+                                               // Cells with content\r
+                                               $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];\r
+                                               $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // Cells with no content\r
+                                               $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];\r
+                                               $out .= str_replace('{day}', $day, $temp);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       // Blank cells\r
+                                       $out .= $this->temp['cal_cell_blank'];\r
+                               }\r
+                               \r
+                               $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];                                             \r
+                               $day++;\r
+                       }\r
+                       \r
+                       $out .= "\n";           \r
+                       $out .= $this->temp['cal_row_end'];\r
+                       $out .= "\n";           \r
+               }\r
+\r
+               $out .= "\n";           \r
+               $out .= $this->temp['table_close'];\r
+\r
+               return $out;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Month Name\r
+        *\r
+        * Generates a textual month name based on the numeric\r
+        * month provided.\r
+        *\r
+        * @access      public\r
+        * @param       integer the month\r
+        * @return      string\r
+        */\r
+       function get_month_name($month)\r
+       {\r
+               if ($this->month_type == 'short')\r
+               {\r
+                       $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');\r
+               }\r
+               else\r
+               {\r
+                       $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');\r
+               }\r
+               \r
+               $month = $month_names[$month];\r
+               \r
+               if ($this->CI->lang->line($month) === FALSE)\r
+               {\r
+                       return ucfirst(str_replace('cal_', '', $month));\r
+               }\r
+\r
+               return $this->CI->lang->line($month);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Day Names\r
+        *\r
+        * Returns an array of day names (Sunday, Monday, etc.) based\r
+        * on the type.  Options: long, short, abrev\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      array\r
+        */\r
+       function get_day_names($day_type = '')\r
+       {\r
+               if ($day_type != '')\r
+                       $this->day_type = $day_type;\r
+       \r
+               if ($this->day_type == 'long')\r
+               {\r
+                       $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');\r
+               }\r
+               elseif ($this->day_type == 'short')\r
+               {\r
+                       $day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');\r
+               }\r
+               else\r
+               {\r
+                       $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');\r
+               }\r
+       \r
+               $days = array();\r
+               foreach ($day_names as $val)\r
+               {                       \r
+                       $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);\r
+               }\r
+       \r
+               return $days;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Adjust Date\r
+        *\r
+        * This function makes sure that we have a valid month/year.\r
+        * For example, if you submit 13 as the month, the year will\r
+        * increment and the month will become January.\r
+        *\r
+        * @access      public\r
+        * @param       integer the month\r
+        * @param       integer the year\r
+        * @return      array\r
+        */\r
+       function adjust_date($month, $year)\r
+       {\r
+               $date = array();\r
+\r
+               $date['month']  = $month;\r
+               $date['year']   = $year;\r
+\r
+               while ($date['month'] > 12)\r
+               {\r
+                       $date['month'] -= 12;\r
+                       $date['year']++;\r
+               }\r
+\r
+               while ($date['month'] <= 0)\r
+               {\r
+                       $date['month'] += 12;\r
+                       $date['year']--;\r
+               }\r
+\r
+               if (strlen($date['month']) == 1)\r
+               {\r
+                       $date['month'] = '0'.$date['month'];\r
+               }\r
+\r
+               return $date;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Total days in a given month\r
+        *\r
+        * @access      public\r
+        * @param       integer the month\r
+        * @param       integer the year\r
+        * @return      integer\r
+        */\r
+       function get_total_days($month, $year)\r
+       {\r
+               $days_in_month  = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);\r
+\r
+               if ($month < 1 OR $month > 12)\r
+               {\r
+                       return 0;\r
+               }\r
+\r
+               // Is the year a leap year?\r
+               if ($month == 2)\r
+               {\r
+                       if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))\r
+                       {\r
+                               return 29;\r
+                       }\r
+               }\r
+\r
+               return $days_in_month[$month - 1];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Default Template Data\r
+        *\r
+        * This is used in the event that the user has not created their own template\r
+        *\r
+        * @access      public\r
+        * @return array\r
+        */\r
+       function default_template()\r
+       {\r
+               return  array (\r
+                                               'table_open'                            => '<table border="0" cellpadding="4" cellspacing="0">',\r
+                                               'heading_row_start'             => '<tr>',\r
+                                               'heading_previous_cell'         => '<th><a href="{previous_url}">&lt;&lt;</a></th>',\r
+                                               'heading_title_cell'            => '<th colspan="{colspan}">{heading}</th>',\r
+                                               'heading_next_cell'             => '<th><a href="{next_url}">&gt;&gt;</a></th>',\r
+                                               'heading_row_end'                       => '</tr>',\r
+                                               'week_row_start'                        => '<tr>',\r
+                                               'week_day_cell'                         => '<td>{week_day}</td>',\r
+                                               'week_row_end'                          => '</tr>',\r
+                                               'cal_row_start'                         => '<tr>',\r
+                                               'cal_cell_start'                        => '<td>',\r
+                                               'cal_cell_start_today'          => '<td>',\r
+                                               'cal_cell_content'                      => '<a href="{content}">{day}</a>',\r
+                                               'cal_cell_content_today'        => '<a href="{content}"><strong>{day}</strong></a>',\r
+                                               'cal_cell_no_content'           => '{day}',\r
+                                               'cal_cell_no_content_today'     => '<strong>{day}</strong>',\r
+                                               'cal_cell_blank'                        => '&nbsp;',\r
+                                               'cal_cell_end'                          => '</td>',\r
+                                               'cal_cell_end_today'            => '</td>',\r
+                                               'cal_row_end'                           => '</tr>',\r
+                                               'table_close'                           => '</table>'\r
+                                       );      \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Parse Template\r
+        *\r
+        * Harvests the data within the template {pseudo-variables}\r
+        * used to display the calendar\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function parse_template()\r
+       {\r
+               $this->temp = $this->default_template();\r
+       \r
+               if ($this->template == '')\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');\r
+               \r
+               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)\r
+               {\r
+                       if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))\r
+                       {\r
+                               $this->temp[$val] = $match['1'];\r
+                       }\r
+                       else\r
+                       {\r
+                               if (in_array($val, $today, TRUE))\r
+                               {\r
+                                       $this->temp[$val] = $this->temp[str_replace('_today', '', $val)];\r
+                               }\r
+                       }\r
+               }       \r
+       }\r
+\r
+}\r
+\r
+// END CI_Calendar class\r
+\r
+/* End of file Calendar.php */\r
+/* Location: ./system/libraries/Calendar.php */
\ No newline at end of file
diff --git a/libraries/Config.php b/libraries/Config.php
new file mode 100644 (file)
index 0000000..a9cf9f4
--- /dev/null
@@ -0,0 +1,244 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Config Class\r
+ *\r
+ * This class contains functions that enable config files to be managed\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/config.html\r
+ */\r
+class CI_Config {\r
+\r
+       var $config = array();\r
+       var $is_loaded = array();\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Sets the $config data from the primary config.php file as a class variable\r
+        *\r
+        * @access   public\r
+        * @param   string      the config file name\r
+        * @param   boolean  if configuration values should be loaded into their own section\r
+        * @param   boolean  true if errors should just return false, false if an error message should be displayed\r
+        * @return  boolean  if the file was successfully loaded or not\r
+        */\r
+       function CI_Config()\r
+       {\r
+               $this->config =& get_config();\r
+               log_message('debug', "Config Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Load Config File\r
+        *\r
+        * @access      public\r
+        * @param       string  the config file name\r
+        * @return      boolean if the file was loaded correctly\r
+        */     \r
+       function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)\r
+       {\r
+               $file = ($file == '') ? 'config' : str_replace(EXT, '', $file);\r
+       \r
+               if (in_array($file, $this->is_loaded, TRUE))\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               if ( ! file_exists(APPPATH.'config/'.$file.EXT))\r
+               {\r
+                       if ($fail_gracefully === TRUE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       show_error('The configuration file '.$file.EXT.' does not exist.');\r
+               }\r
+       \r
+               include(APPPATH.'config/'.$file.EXT);\r
+\r
+               if ( ! isset($config) OR ! is_array($config))\r
+               {\r
+                       if ($fail_gracefully === TRUE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.');\r
+               }\r
+\r
+               if ($use_sections === TRUE)\r
+               {\r
+                       if (isset($this->config[$file]))\r
+                       {\r
+                               $this->config[$file] = array_merge($this->config[$file], $config);\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->config[$file] = $config;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->config = array_merge($this->config, $config);\r
+               }\r
+\r
+               $this->is_loaded[] = $file;\r
+               unset($config);\r
+\r
+               log_message('debug', 'Config file loaded: config/'.$file.EXT);\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch a config file item\r
+        *\r
+        *\r
+        * @access      public\r
+        * @param       string  the config item name\r
+        * @param       string  the index name\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function item($item, $index = '')\r
+       {       \r
+               if ($index == '')\r
+               {       \r
+                       if ( ! isset($this->config[$item]))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+\r
+                       $pref = $this->config[$item];\r
+               }\r
+               else\r
+               {\r
+                       if ( ! isset($this->config[$index]))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+\r
+                       if ( ! isset($this->config[$index][$item]))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+\r
+                       $pref = $this->config[$index][$item];\r
+               }\r
+\r
+               return $pref;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch a config file item - adds slash after item\r
+        *\r
+        * The second parameter allows a slash to be added to the end of\r
+        * the item, in the case of a path.\r
+        *\r
+        * @access      public\r
+        * @param       string  the config item name\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function slash_item($item)\r
+       {\r
+               if ( ! isset($this->config[$item]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $pref = $this->config[$item];\r
+\r
+               if ($pref != '' && substr($pref, -1) != '/')\r
+               {       \r
+                       $pref .= '/';\r
+               }\r
+\r
+               return $pref;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Site URL\r
+        *\r
+        * @access      public\r
+        * @param       string  the URI string\r
+        * @return      string\r
+        */\r
+       function site_url($uri = '')\r
+       {\r
+               if (is_array($uri))\r
+               {\r
+                       $uri = implode('/', $uri);\r
+               }\r
+\r
+               if ($uri == '')\r
+               {\r
+                       return $this->slash_item('base_url').$this->item('index_page');\r
+               }\r
+               else\r
+               {\r
+                       $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');\r
+                       return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * System URL\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function system_url()\r
+       {\r
+               $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));\r
+               return $this->slash_item('base_url').end($x).'/';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set a config file item\r
+        *\r
+        * @access      public\r
+        * @param       string  the config item key\r
+        * @param       string  the config item value\r
+        * @return      void\r
+        */\r
+       function set_item($item, $value)\r
+       {\r
+               $this->config[$item] = $value;\r
+       }\r
+\r
+}\r
+\r
+// END CI_Config class\r
+\r
+/* End of file Config.php */\r
+/* Location: ./system/libraries/Config.php */
\ No newline at end of file
diff --git a/libraries/Controller.php b/libraries/Controller.php
new file mode 100644 (file)
index 0000000..95c0208
--- /dev/null
@@ -0,0 +1,127 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Application Controller Class\r
+ *\r
+ * This class object is the super class the every library in\r
+ * CodeIgniter will be assigned to.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/general/controllers.html\r
+ */\r
+class Controller extends CI_Base {\r
+\r
+       var $_ci_scaffolding    = FALSE;\r
+       var $_ci_scaff_table    = FALSE;\r
+       \r
+       /**\r
+        * Constructor\r
+        *\r
+        * Calls the initialize() function\r
+        */\r
+       function Controller()\r
+       {       \r
+               parent::CI_Base();\r
+               $this->_ci_initialize();\r
+               log_message('debug', "Controller Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize\r
+        *\r
+        * Assigns all the bases classes loaded by the front controller to\r
+        * variables in this class.  Also calls the autoload routine.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _ci_initialize()\r
+       {\r
+               // Assign all the class objects that were instantiated by the\r
+               // front controller to local class variables so that CI can be\r
+               // run as one big super object.\r
+               $classes = array(\r
+                                                       'config'        => 'Config',\r
+                                                       'input'         => 'Input',\r
+                                                       'benchmark'     => 'Benchmark',\r
+                                                       'uri'           => 'URI',\r
+                                                       'output'        => 'Output',\r
+                                                       'lang'          => 'Language',\r
+                                                       'router'        => 'Router'\r
+                                                       );\r
+               \r
+               foreach ($classes as $var => $class)\r
+               {\r
+                       $this->$var =& load_class($class);\r
+               }\r
+\r
+               // In PHP 5 the Loader class is run as a discreet\r
+               // class.  In PHP 4 it extends the Controller\r
+               if (floor(phpversion()) >= 5)\r
+               {\r
+                       $this->load =& load_class('Loader');\r
+                       $this->load->_ci_autoloader();\r
+               }\r
+               else\r
+               {\r
+                       $this->_ci_autoloader();\r
+                       \r
+                       // sync up the objects since PHP4 was working from a copy\r
+                       foreach (array_keys(get_object_vars($this)) as $attribute)\r
+                       {\r
+                               if (is_object($this->$attribute))\r
+                               {\r
+                                       $this->load->$attribute =& $this->$attribute;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Run Scaffolding\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _ci_scaffolding()\r
+       {\r
+               if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)\r
+               {\r
+                       show_404('Scaffolding unavailable');\r
+               }\r
+               \r
+               $method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3);\r
+               \r
+               require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);\r
+               $scaff = new Scaffolding($this->_ci_scaff_table);\r
+               $scaff->$method();\r
+       }\r
+\r
+\r
+}\r
+// END _Controller class\r
+\r
+/* End of file Controller.php */\r
+/* Location: ./system/libraries/Controller.php */
\ No newline at end of file
diff --git a/libraries/Email.php b/libraries/Email.php
new file mode 100644 (file)
index 0000000..e9a5344
--- /dev/null
@@ -0,0 +1,1953 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Email Class\r
+ *\r
+ * Permits email to be sent using Mail, Sendmail, or SMTP.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/email.html\r
+ */\r
+class CI_Email {\r
+\r
+       var     $useragent              = "CodeIgniter";\r
+       var     $mailpath               = "/usr/sbin/sendmail"; // Sendmail path\r
+       var     $protocol               = "mail";       // mail/sendmail/smtp\r
+       var     $smtp_host              = "";           // SMTP Server.  Example: mail.earthlink.net\r
+       var     $smtp_user              = "";           // SMTP Username\r
+       var     $smtp_pass              = "";           // SMTP Password\r
+       var     $smtp_port              = "25";         // SMTP Port\r
+       var     $smtp_timeout   = 5;            // SMTP Timeout in seconds\r
+       var     $wordwrap               = TRUE;         // TRUE/FALSE  Turns word-wrap on/off\r
+       var     $wrapchars              = "76";         // Number of characters to wrap at.\r
+       var     $mailtype               = "text";       // text/html  Defines email formatting\r
+       var     $charset                = "utf-8";      // Default char set: iso-8859-1 or us-ascii\r
+       var     $multipart              = "mixed";      // "mixed" (in the body) or "related" (separate)\r
+       var $alt_message        = '';           // Alternative message for HTML emails\r
+       var     $validate               = FALSE;        // TRUE/FALSE.  Enables email validation\r
+       var     $priority               = "3";          // Default priority (1 - 5)\r
+       var     $newline                = "\n";         // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)\r
+       var $crlf                       = "\n";         // The RFC 2045 compliant CRLF for quoted-printable is "\r\n".  Apparently some servers,\r
+                                                                       // even on the receiving end think they need to muck with CRLFs, so using "\n", while\r
+                                                                       // distasteful, is the only thing that seems to work for all environments.\r
+       var $send_multipart     = TRUE;         // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override.  Set to FALSE for Yahoo.     \r
+       var     $bcc_batch_mode = FALSE;        // TRUE/FALSE  Turns on/off Bcc batch feature\r
+       var     $bcc_batch_size = 200;          // If bcc_batch_mode = TRUE, sets max number of Bccs in each batch\r
+       var $_safe_mode         = FALSE;\r
+       var     $_subject               = "";\r
+       var     $_body                  = "";\r
+       var     $_finalbody             = "";\r
+       var     $_alt_boundary  = "";\r
+       var     $_atc_boundary  = "";\r
+       var     $_header_str    = "";\r
+       var     $_smtp_connect  = "";\r
+       var     $_encoding              = "8bit";\r
+       var $_IP                        = FALSE;\r
+       var     $_smtp_auth             = FALSE;\r
+       var $_replyto_flag      = FALSE;\r
+       var     $_debug_msg             = array();\r
+       var     $_recipients    = array();\r
+       var     $_cc_array              = array();\r
+       var     $_bcc_array             = array();\r
+       var     $_headers               = array();\r
+       var     $_attach_name   = array();\r
+       var     $_attach_type   = array();\r
+       var     $_attach_disp   = array();\r
+       var     $_protocols             = array('mail', 'sendmail', 'smtp');\r
+       var     $_base_charsets = array('us-ascii', 'iso-2022-');       // 7-bit charsets (excluding language suffix)\r
+       var     $_bit_depths    = array('7bit', '8bit');\r
+       var     $_priorities    = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');\r
+\r
+\r
+       /**\r
+        * Constructor - Sets Email Preferences\r
+        *\r
+        * The constructor can be passed an array of config values\r
+        */\r
+       function CI_Email($config = array())\r
+       {       \r
+               if (count($config) > 0)\r
+               {\r
+                       $this->initialize($config);\r
+               }       \r
+               else\r
+               {\r
+                       $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; \r
+                       $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;\r
+               }\r
+               \r
+               log_message('debug', "Email Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize preferences\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function initialize($config = array())\r
+       {\r
+               $this->clear();\r
+               foreach ($config as $key => $val)\r
+               {\r
+                       if (isset($this->$key))\r
+                       {\r
+                               $method = 'set_'.$key;\r
+\r
+                               if (method_exists($this, $method))\r
+                               {\r
+                                       $this->$method($val);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $this->$key = $val;\r
+                               }       \r
+                       }\r
+               }\r
+               \r
+               $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; \r
+               $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize the Email Data\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function clear($clear_attachments = FALSE)\r
+       {\r
+               $this->_subject         = "";\r
+               $this->_body            = "";\r
+               $this->_finalbody       = "";\r
+               $this->_header_str      = "";\r
+               $this->_replyto_flag = FALSE;\r
+               $this->_recipients      = array();\r
+               $this->_headers         = array();\r
+               $this->_debug_msg       = array();\r
+\r
+               $this->_set_header('User-Agent', $this->useragent);\r
+               $this->_set_header('Date', $this->_set_date());\r
+\r
+               if ($clear_attachments !== FALSE)\r
+               {\r
+                       $this->_attach_name = array();\r
+                       $this->_attach_type = array();\r
+                       $this->_attach_disp = array();\r
+               }   \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set FROM\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function from($from, $name = '')\r
+       {\r
+               if (preg_match( '/\<(.*)\>/', $from, $match))\r
+               {\r
+                       $from = $match['1'];\r
+               }\r
+\r
+               if ($this->validate)\r
+               {\r
+                       $this->validate_email($this->_str_to_array($from));\r
+               }\r
+       \r
+               if ($name != '' && strncmp($name, '"', 1) != 0)\r
+               {\r
+                       $name = '"'.$name.'"';\r
+               }\r
+       \r
+               $this->_set_header('From', $name.' <'.$from.'>');\r
+               $this->_set_header('Return-Path', '<'.$from.'>');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Reply-to\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function reply_to($replyto, $name = '')\r
+       {\r
+               if (preg_match( '/\<(.*)\>/', $replyto, $match))\r
+               {\r
+                       $replyto = $match['1'];\r
+               }\r
+\r
+               if ($this->validate)\r
+               {\r
+                       $this->validate_email($this->_str_to_array($replyto));  \r
+               }\r
+\r
+               if ($name == '')\r
+               {\r
+                       $name = $replyto;\r
+               }\r
+\r
+               if (strncmp($name, '"', 1) != 0)\r
+               {\r
+                       $name = '"'.$name.'"';\r
+               }\r
+\r
+               $this->_set_header('Reply-To', $name.' <'.$replyto.'>');\r
+               $this->_replyto_flag = TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Recipients\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function to($to)\r
+       {\r
+               $to = $this->_str_to_array($to);\r
+               $to = $this->clean_email($to);\r
+       \r
+               if ($this->validate)\r
+               {\r
+                       $this->validate_email($to);\r
+               }\r
+       \r
+               if ($this->_get_protocol() != 'mail')\r
+               {\r
+                       $this->_set_header('To', implode(", ", $to));\r
+               }\r
+\r
+               switch ($this->_get_protocol())\r
+               {\r
+                       case 'smtp'             : $this->_recipients = $to;\r
+                       break;\r
+                       case 'sendmail' : $this->_recipients = implode(", ", $to);\r
+                       break;\r
+                       case 'mail'             : $this->_recipients = implode(", ", $to);\r
+                       break;\r
+               }       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set CC\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function cc($cc)\r
+       {       \r
+               $cc = $this->_str_to_array($cc);\r
+               $cc = $this->clean_email($cc);\r
+\r
+               if ($this->validate)\r
+               {\r
+                       $this->validate_email($cc);\r
+               }\r
+\r
+               $this->_set_header('Cc', implode(", ", $cc));\r
+\r
+               if ($this->_get_protocol() == "smtp")\r
+               {\r
+                       $this->_cc_array = $cc;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set BCC\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function bcc($bcc, $limit = '')\r
+       {\r
+               if ($limit != '' && is_numeric($limit))\r
+               {\r
+                       $this->bcc_batch_mode = TRUE;\r
+                       $this->bcc_batch_size = $limit;\r
+               }\r
+\r
+               $bcc = $this->_str_to_array($bcc);\r
+               $bcc = $this->clean_email($bcc);\r
+\r
+               if ($this->validate)\r
+               {\r
+                       $this->validate_email($bcc);\r
+               }\r
+\r
+               if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))\r
+               {\r
+                       $this->_bcc_array = $bcc;\r
+               }\r
+               else\r
+               {\r
+                       $this->_set_header('Bcc', implode(", ", $bcc));\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Email Subject\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function subject($subject)\r
+       {\r
+               if (strpos($subject, "\r") !== FALSE OR strpos($subject, "\n") !== FALSE)\r
+               {\r
+                       $subject = str_replace(array("\r\n", "\r", "\n"), '', $subject);                        \r
+               }\r
+\r
+               if (strpos($subject, "\t"))\r
+               {\r
+                       $subject = str_replace("\t", ' ', $subject);\r
+               }\r
+\r
+               $this->_set_header('Subject', trim($subject));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Body\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function message($body)\r
+       {\r
+               $this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));       \r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Assign file attachments\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function attach($filename, $disposition = 'attachment')\r
+       {       \r
+               $this->_attach_name[] = $filename;\r
+               $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));\r
+               $this->_attach_disp[] = $disposition; // Can also be 'inline'  Not sure if it matters\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add a Header Item\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function _set_header($header, $value)\r
+       {\r
+               $this->_headers[$header] = $value;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Convert a String to an Array\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      array\r
+        */     \r
+       function _str_to_array($email)\r
+       {\r
+               if ( ! is_array($email))\r
+               {\r
+                       if (strpos($email, ',') !== FALSE)\r
+                       {\r
+                               $email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);\r
+                       }\r
+                       else\r
+                       {\r
+                               $email = trim($email);\r
+                               settype($email, "array");\r
+                       }\r
+               }\r
+               return $email;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Multipart Value\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_alt_message($str = '')\r
+       {\r
+               $this->alt_message = ($str == '') ? '' : $str;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Mailtype\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_mailtype($type = 'text')\r
+       {\r
+               $this->mailtype = ($type == 'html') ? 'html' : 'text';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Wordwrap\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_wordwrap($wordwrap = TRUE)\r
+       {\r
+               $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Protocol\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_protocol($protocol = 'mail')\r
+       {\r
+               $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Priority\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function set_priority($n = 3)\r
+       {\r
+               if ( ! is_numeric($n))\r
+               {\r
+                       $this->priority = 3;\r
+                       return;\r
+               }\r
+       \r
+               if ($n < 1 OR $n > 5)\r
+               {\r
+                       $this->priority = 3;\r
+                       return;\r
+               }\r
+       \r
+               $this->priority = $n;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Newline Character\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_newline($newline = "\n")\r
+       {\r
+               if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")\r
+               {\r
+                       $this->newline  = "\n"; \r
+                       return;\r
+               }\r
+       \r
+               $this->newline  = $newline;     \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set CRLF\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_crlf($crlf = "\n")\r
+       {\r
+               if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")\r
+               {\r
+                       $this->crlf     = "\n"; \r
+                       return;\r
+               }\r
+       \r
+               $this->crlf     = $crlf;        \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Message Boundary\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _set_boundaries()\r
+       {\r
+               $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative\r
+               $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get the Message ID\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _get_message_id()\r
+       {\r
+               $from = $this->_headers['Return-Path'];\r
+               $from = str_replace(">", "", $from);\r
+               $from = str_replace("<", "", $from);\r
+       \r
+               return  "<".uniqid('').strstr($from, '@').">";  \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Mail Protocol\r
+        *\r
+        * @access      private\r
+        * @param       bool\r
+        * @return      string\r
+        */     \r
+       function _get_protocol($return = TRUE)\r
+       {\r
+               $this->protocol = strtolower($this->protocol);\r
+               $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;\r
+\r
+               if ($return == TRUE)\r
+               {\r
+                       return $this->protocol;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Mail Encoding\r
+        *\r
+        * @access      private\r
+        * @param       bool\r
+        * @return      string\r
+        */     \r
+       function _get_encoding($return = TRUE)\r
+       {\r
+               $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;\r
+\r
+               foreach ($this->_base_charsets as $charset)\r
+               {\r
+                       if (strncmp($charset, $this->charset, strlen($charset)) == 0)\r
+                       {\r
+                               $this->_encoding = '7bit';\r
+                       }\r
+               }\r
+       \r
+               if ($return == TRUE)\r
+               {\r
+                       return $this->_encoding;        \r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get content type (text/html/attachment)\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _get_content_type()\r
+       {       \r
+               if      ($this->mailtype == 'html' &&  count($this->_attach_name) == 0)\r
+               {\r
+                       return 'html';\r
+               }\r
+               elseif  ($this->mailtype == 'html' &&  count($this->_attach_name)  > 0)\r
+               {\r
+                       return 'html-attach';\r
+               }\r
+               elseif  ($this->mailtype == 'text' &&  count($this->_attach_name)  > 0)\r
+               {\r
+                       return 'plain-attach';\r
+               }\r
+               else\r
+               {\r
+                       return 'plain';\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set RFC 822 Date\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _set_date()\r
+       {\r
+               $timezone = date("Z");\r
+               $operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';\r
+               $timezone = abs($timezone);\r
+               $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;\r
+\r
+               return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Mime message\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _get_mime_message()\r
+       {\r
+               return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Validate Email Address\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function validate_email($email)\r
+       {       \r
+               if ( ! is_array($email))\r
+               {\r
+                       $this->_set_error_message('email_must_be_array');\r
+                       return FALSE;\r
+               }\r
+\r
+               foreach ($email as $val)\r
+               {\r
+                       if ( ! $this->valid_email($val))\r
+                       {\r
+                               $this->_set_error_message('email_invalid_address', $val);\r
+                               return FALSE;\r
+                       }\r
+               }\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Email Validation\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function valid_email($address)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Clean Extended Email Address: Joe Smith <joe@smith.com>\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function clean_email($email)\r
+       {\r
+               if ( ! is_array($email))\r
+               {\r
+                       if (preg_match('/\<(.*)\>/', $email, $match))\r
+                       {\r
+                               return $match['1'];\r
+                       }\r
+                       else\r
+                       {\r
+                               return $email;\r
+                       }\r
+               }\r
+       \r
+               $clean_email = array();\r
+\r
+               foreach ($email as $addy)\r
+               {\r
+                       if (preg_match( '/\<(.*)\>/', $addy, $match))\r
+                       {\r
+                               $clean_email[] = $match['1'];\r
+                       }\r
+                       else\r
+                       {\r
+                               $clean_email[] = $addy; \r
+                       }\r
+               }\r
+\r
+               return $clean_email;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Build alternative plain text message\r
+        *\r
+        * This function provides the raw message for use\r
+        * in plain-text headers of HTML-formatted emails.\r
+        * If the user hasn't specified his own alternative message\r
+        * it creates one by stripping the HTML\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _get_alt_message()\r
+       {\r
+               if ($this->alt_message != "")\r
+               {\r
+                       return $this->word_wrap($this->alt_message, '76');\r
+               }\r
+\r
+               if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))\r
+               {\r
+                       $body = $match['1'];\r
+               }\r
+               else\r
+               {\r
+                       $body = $this->_body;\r
+               }\r
+\r
+               $body = trim(strip_tags($body));\r
+               $body = preg_replace( '#<!--(.*)--\>#', "", $body);\r
+               $body = str_replace("\t", "", $body);\r
+\r
+               for ($i = 20; $i >= 3; $i--)\r
+               {\r
+                       $n = "";\r
+       \r
+                       for ($x = 1; $x <= $i; $x ++)\r
+                       {\r
+                                $n .= "\n";\r
+                       }\r
+\r
+                       $body = str_replace($n, "\n\n", $body); \r
+               }\r
+\r
+               return $this->word_wrap($body, '76');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Word Wrap\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       integer\r
+        * @return      string\r
+        */     \r
+       function word_wrap($str, $charlim = '')\r
+       {\r
+               // Se the character limit\r
+               if ($charlim == '')\r
+               {\r
+                       $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;\r
+               }\r
+\r
+               // Reduce multiple spaces\r
+               $str = preg_replace("| +|", " ", $str);\r
+\r
+               // Standardize newlines\r
+               if (strpos($str, "\r") !== FALSE)\r
+               {\r
+                       $str = str_replace(array("\r\n", "\r"), "\n", $str);                    \r
+               }\r
+\r
+               // If the current word is surrounded by {unwrap} tags we'll \r
+               // strip the entire chunk and replace it with a marker.\r
+               $unwrap = array();\r
+               if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))\r
+               {\r
+                       for ($i = 0; $i < count($matches['0']); $i++)\r
+                       {\r
+                               $unwrap[] = $matches['1'][$i];\r
+                               $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);\r
+                       }\r
+               }\r
+\r
+               // Use PHP's native function to do the initial wordwrap.  \r
+               // We set the cut flag to FALSE so that any individual words that are \r
+               // too long get left alone.  In the next step we'll deal with them.\r
+               $str = wordwrap($str, $charlim, "\n", FALSE);\r
+\r
+               // Split the string into individual lines of text and cycle through them\r
+               $output = "";\r
+               foreach (explode("\n", $str) as $line) \r
+               {\r
+                       // Is the line within the allowed character count?\r
+                       // If so we'll join it to the output and continue\r
+                       if (strlen($line) <= $charlim)\r
+                       {\r
+                               $output .= $line.$this->newline;        \r
+                               continue;\r
+                       }\r
+\r
+                       $temp = '';\r
+                       while((strlen($line)) > $charlim) \r
+                       {\r
+                               // If the over-length word is a URL we won't wrap it\r
+                               if (preg_match("!\[url.+\]|://|wwww.!", $line))\r
+                               {\r
+                                       break;\r
+                               }\r
+\r
+                               // Trim the word down\r
+                               $temp .= substr($line, 0, $charlim-1);\r
+                               $line = substr($line, $charlim-1);\r
+                       }\r
+       \r
+                       // If $temp contains data it means we had to split up an over-length \r
+                       // word into smaller chunks so we'll add it back to our current line\r
+                       if ($temp != '')\r
+                       {\r
+                               $output .= $temp.$this->newline.$line;\r
+                       }\r
+                       else\r
+                       {\r
+                               $output .= $line;\r
+                       }\r
+\r
+                       $output .= $this->newline;\r
+               }\r
+\r
+               // Put our markers back\r
+               if (count($unwrap) > 0)\r
+               {       \r
+                       foreach ($unwrap as $key => $val)\r
+                       {\r
+                               $output = str_replace("{{unwrapped".$key."}}", $val, $output);\r
+                       }\r
+               }\r
+\r
+               return $output; \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Build final headers\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _build_headers()\r
+       {\r
+               $this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));\r
+               $this->_set_header('X-Mailer', $this->useragent);\r
+               $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);\r
+               $this->_set_header('Message-ID', $this->_get_message_id());\r
+               $this->_set_header('Mime-Version', '1.0');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Write Headers as a string\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _write_headers()\r
+       {\r
+               if ($this->protocol == 'mail')\r
+               {\r
+                       $this->_subject = $this->_headers['Subject'];\r
+                       unset($this->_headers['Subject']);\r
+               }       \r
+\r
+               reset($this->_headers);\r
+               $this->_header_str = "";\r
+\r
+               foreach($this->_headers as $key => $val)\r
+               {\r
+                       $val = trim($val);\r
+\r
+                       if ($val != "")\r
+                       {\r
+                               $this->_header_str .= $key.": ".$val.$this->newline;\r
+                       }\r
+               }\r
+\r
+               if ($this->_get_protocol() == 'mail')\r
+               {\r
+                       $this->_header_str = substr($this->_header_str, 0, -1);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Build Final Body and attachments\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _build_message()\r
+       {\r
+               if ($this->wordwrap === TRUE  AND  $this->mailtype != 'html')\r
+               {\r
+                       $this->_body = $this->word_wrap($this->_body);\r
+               }\r
+       \r
+               $this->_set_boundaries();\r
+               $this->_write_headers();\r
+\r
+               $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';\r
+       \r
+               switch ($this->_get_content_type())\r
+               {\r
+                       case 'plain' :\r
+       \r
+                               $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;\r
+                               $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();\r
+\r
+                               if ($this->_get_protocol() == 'mail')\r
+                               {\r
+                                       $this->_header_str .= $hdr;\r
+                                       $this->_finalbody = $this->_body;\r
+       \r
+                                       return;\r
+                               }\r
+\r
+                               $hdr .= $this->newline . $this->newline . $this->_body;\r
+\r
+                               $this->_finalbody = $hdr;\r
+                               return;\r
+       \r
+                       break;\r
+                       case 'html' :\r
+       \r
+                               if ($this->send_multipart === FALSE)\r
+                               {\r
+                                       $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;\r
+                                       $hdr .= "Content-Transfer-Encoding: quoted-printable";\r
+                               }\r
+                               else\r
+                               {       \r
+                                       $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;\r
+                                       $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;\r
+                                       $hdr .= "--" . $this->_alt_boundary . $this->newline;\r
+       \r
+                                       $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;\r
+                                       $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;\r
+                                       $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;\r
+\r
+                                       $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;\r
+                                       $hdr .= "Content-Transfer-Encoding: quoted-printable";\r
+                               }\r
+\r
+                               $this->_body = $this->_prep_quoted_printable($this->_body);\r
+\r
+                               if ($this->_get_protocol() == 'mail')\r
+                               {\r
+                                       $this->_header_str .= $hdr;\r
+                                       $this->_finalbody = $this->_body . $this->newline . $this->newline;\r
+       \r
+                                       if ($this->send_multipart !== FALSE)\r
+                                       {\r
+                                               $this->_finalbody .= "--" . $this->_alt_boundary . "--";\r
+                                       }\r
+       \r
+                                       return;\r
+                               }\r
+\r
+                               $hdr .= $this->newline . $this->newline;\r
+                               $hdr .= $this->_body . $this->newline . $this->newline;\r
+\r
+                               if ($this->send_multipart !== FALSE)\r
+                               {\r
+                                       $hdr .= "--" . $this->_alt_boundary . "--";\r
+                               }\r
+\r
+                               $this->_finalbody = $hdr;\r
+                               return;\r
+\r
+                       break;\r
+                       case 'plain-attach' :\r
+       \r
+                               $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;\r
+                               $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;\r
+                               $hdr .= "--" . $this->_atc_boundary . $this->newline;\r
+       \r
+                               $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;\r
+                               $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();\r
+\r
+                               if ($this->_get_protocol() == 'mail')\r
+                               {\r
+                                       $this->_header_str .= $hdr;\r
+       \r
+                                       $body  = $this->_body . $this->newline . $this->newline;\r
+                               }\r
+\r
+                               $hdr .= $this->newline . $this->newline;\r
+                               $hdr .= $this->_body . $this->newline . $this->newline;\r
+\r
+                       break;\r
+                       case 'html-attach' :\r
+       \r
+                               $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;\r
+                               $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;\r
+                               $hdr .= "--" . $this->_atc_boundary . $this->newline;\r
+       \r
+                               $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;\r
+                               $hdr .= "--" . $this->_alt_boundary . $this->newline;\r
+\r
+                               $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;\r
+                               $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;\r
+                               $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;\r
+       \r
+                               $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;\r
+                               $hdr .= "Content-Transfer-Encoding: quoted-printable";\r
+\r
+                               $this->_body = $this->_prep_quoted_printable($this->_body);\r
+\r
+                               if ($this->_get_protocol() == 'mail')\r
+                               {\r
+                                       $this->_header_str .= $hdr;     \r
+       \r
+                                       $body  = $this->_body . $this->newline . $this->newline;\r
+                                       $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;\r
+                               }\r
+\r
+                               $hdr .= $this->newline . $this->newline;\r
+                               $hdr .= $this->_body . $this->newline . $this->newline;\r
+                               $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;\r
+\r
+                       break;\r
+               }\r
+\r
+               $attachment = array();\r
+\r
+               $z = 0;\r
+\r
+               for ($i=0; $i < count($this->_attach_name); $i++)\r
+               {\r
+                       $filename = $this->_attach_name[$i];\r
+                       $basename = basename($filename);\r
+                       $ctype = $this->_attach_type[$i];\r
+\r
+                       if ( ! file_exists($filename))\r
+                       {\r
+                               $this->_set_error_message('email_attachment_missing', $filename);\r
+                               return FALSE;\r
+                       }       \r
+\r
+                       $h  = "--".$this->_atc_boundary.$this->newline;\r
+                       $h .= "Content-type: ".$ctype."; ";\r
+                       $h .= "name=\"".$basename."\"".$this->newline;\r
+                       $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;\r
+                       $h .= "Content-Transfer-Encoding: base64".$this->newline;\r
+\r
+                       $attachment[$z++] = $h;\r
+                       $file = filesize($filename) +1;\r
+       \r
+                       if ( ! $fp = fopen($filename, FOPEN_READ))\r
+                       {\r
+                               $this->_set_error_message('email_attachment_unreadable', $filename);\r
+                               return FALSE;\r
+                       }\r
+       \r
+                       $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));\r
+                       fclose($fp);\r
+               }\r
+\r
+               if ($this->_get_protocol() == 'mail')\r
+               {\r
+                       $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; \r
+       \r
+                       return;\r
+               }\r
+\r
+               $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";    \r
+\r
+               return; \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep Quoted Printable\r
+        *\r
+        * Prepares string for Quoted-Printable Content-Transfer-Encoding\r
+        * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       integer\r
+        * @return      string\r
+        */\r
+       function _prep_quoted_printable($str, $charlim = '')\r
+       {\r
+               // Set the character limit\r
+               // Don't allow over 76, as that will make servers and MUAs barf\r
+               // all over quoted-printable data\r
+               if ($charlim == '' OR $charlim > '76')\r
+               {\r
+                       $charlim = '76';\r
+               }\r
+\r
+               // Reduce multiple spaces\r
+               $str = preg_replace("| +|", " ", $str);\r
+\r
+               // kill nulls\r
+               $str = preg_replace('/\x00+/', '', $str);\r
+               \r
+               // Standardize newlines\r
+               if (strpos($str, "\r") !== FALSE)\r
+               {\r
+                       $str = str_replace(array("\r\n", "\r"), "\n", $str);\r
+               }\r
+\r
+               // We are intentionally wrapping so mail servers will encode characters\r
+               // properly and MUAs will behave, so {unwrap} must go!\r
+               $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);\r
+\r
+               // Break into an array of lines\r
+               $lines = explode("\n", $str);\r
+\r
+               $escape = '=';\r
+               $output = '';\r
+\r
+               foreach ($lines as $line)\r
+               {\r
+                       $length = strlen($line);\r
+                       $temp = '';\r
+\r
+                       // Loop through each character in the line to add soft-wrap\r
+                       // characters at the end of a line " =\r\n" and add the newly\r
+                       // processed line(s) to the output (see comment on $crlf class property)\r
+                       for ($i = 0; $i < $length; $i++)\r
+                       {\r
+                               // Grab the next character\r
+                               $char = substr($line, $i, 1);\r
+                               $ascii = ord($char);\r
+\r
+                               // Convert spaces and tabs but only if it's the end of the line\r
+                               if ($i == ($length - 1))\r
+                               {\r
+                                       $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;\r
+                               }\r
+\r
+                               // encode = signs\r
+                               if ($ascii == '61')\r
+                               {\r
+                                       $char = $escape.strtoupper(sprintf('%02s', dechex($ascii)));  // =3D\r
+                               }\r
+\r
+                               // If we're at the character limit, add the line to the output,\r
+                               // reset our temp variable, and keep on chuggin'\r
+                               if ((strlen($temp) + strlen($char)) >= $charlim)\r
+                               {\r
+                                       $output .= $temp.$escape.$this->crlf;\r
+                                       $temp = '';\r
+                               }\r
+\r
+                               // Add the character to our temporary line\r
+                               $temp .= $char;\r
+                       }\r
+\r
+                       // Add our completed line to the output\r
+                       $output .= $temp.$this->crlf;\r
+               }\r
+\r
+               // get rid of extra CRLF tacked onto the end\r
+               $output = substr($output, 0, strlen($this->crlf) * -1);\r
+\r
+               return $output;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Send Email\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function send()\r
+       {       \r
+               if ($this->_replyto_flag == FALSE)\r
+               {\r
+                       $this->reply_to($this->_headers['From']);\r
+               }\r
+       \r
+               if (( ! isset($this->_recipients) AND ! isset($this->_headers['To']))  AND\r
+                       ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND\r
+                       ( ! isset($this->_headers['Cc'])))\r
+               {\r
+                       $this->_set_error_message('email_no_recipients');\r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_build_headers();\r
+\r
+               if ($this->bcc_batch_mode  AND  count($this->_bcc_array) > 0)\r
+               {\r
+                       if (count($this->_bcc_array) > $this->bcc_batch_size)\r
+                               return $this->batch_bcc_send();\r
+               }\r
+\r
+               $this->_build_message();\r
+\r
+               if ( ! $this->_spool_email())\r
+               {\r
+                       return FALSE;\r
+               }\r
+               else\r
+               {\r
+                       return TRUE;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Batch Bcc Send.  Sends groups of BCCs in batches\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function batch_bcc_send()\r
+       {\r
+               $float = $this->bcc_batch_size -1;\r
+\r
+               $set = "";\r
+\r
+               $chunk = array();\r
+\r
+               for ($i = 0; $i < count($this->_bcc_array); $i++)\r
+               {\r
+                       if (isset($this->_bcc_array[$i]))\r
+                       {\r
+                               $set .= ", ".$this->_bcc_array[$i];\r
+                       }\r
+\r
+                       if ($i == $float)\r
+                       {       \r
+                               $chunk[] = substr($set, 1);\r
+                               $float = $float + $this->bcc_batch_size;\r
+                               $set = "";\r
+                       }\r
+       \r
+                       if ($i == count($this->_bcc_array)-1)\r
+                       {\r
+                               $chunk[] = substr($set, 1);\r
+                       }\r
+               }\r
+\r
+               for ($i = 0; $i < count($chunk); $i++)\r
+               {\r
+                       unset($this->_headers['Bcc']);\r
+                       unset($bcc);\r
+\r
+                       $bcc = $this->_str_to_array($chunk[$i]);\r
+                       $bcc = $this->clean_email($bcc);\r
+       \r
+                       if ($this->protocol != 'smtp')\r
+                       {\r
+                               $this->_set_header('Bcc', implode(", ", $bcc));\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->_bcc_array = $bcc;\r
+                       }\r
+       \r
+                       $this->_build_message();\r
+                       $this->_spool_email();\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Unwrap special elements\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _unwrap_specials()\r
+       {\r
+               $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Strip line-breaks via callback\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _remove_nl_callback($matches)\r
+       {\r
+               if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)\r
+               {\r
+                       $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);\r
+               }\r
+               \r
+               return $matches[1];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Spool mail to the mail server\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _spool_email()\r
+       {\r
+               $this->_unwrap_specials();\r
+\r
+               switch ($this->_get_protocol())\r
+               {\r
+                       case 'mail'     :\r
+       \r
+                                       if ( ! $this->_send_with_mail())\r
+                                       {\r
+                                               $this->_set_error_message('email_send_failure_phpmail');        \r
+                                               return FALSE;\r
+                                       }\r
+                       break;\r
+                       case 'sendmail' :\r
+               \r
+                                       if ( ! $this->_send_with_sendmail())\r
+                                       {\r
+                                               $this->_set_error_message('email_send_failure_sendmail');       \r
+                                               return FALSE;\r
+                                       }\r
+                       break;\r
+                       case 'smtp'     :\r
+               \r
+                                       if ( ! $this->_send_with_smtp())\r
+                                       {\r
+                                               $this->_set_error_message('email_send_failure_smtp');   \r
+                                               return FALSE;\r
+                                       }\r
+                       break;\r
+\r
+               }\r
+\r
+               $this->_set_error_message('email_sent', $this->_get_protocol());\r
+               return TRUE;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Send using mail()\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _send_with_mail()\r
+       {       \r
+               if ($this->_safe_mode == TRUE)\r
+               {\r
+                       if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       else\r
+                       {\r
+                               return TRUE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // most documentation of sendmail using the "-f" flag lacks a space after it, however\r
+                       // we've encountered servers that seem to require it to be in place.\r
+                       if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       else\r
+                       {\r
+                               return TRUE;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Send using Sendmail\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _send_with_sendmail()\r
+       {\r
+               $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');\r
+\r
+               if ( ! is_resource($fp))\r
+               {               \r
+                       $this->_set_error_message('email_no_socket');\r
+                       return FALSE;\r
+               }\r
+\r
+               fputs($fp, $this->_header_str);\r
+               fputs($fp, $this->_finalbody);\r
+               pclose($fp) >> 8 & 0xFF;\r
+\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Send using SMTP\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _send_with_smtp()\r
+       {       \r
+               if ($this->smtp_host == '')\r
+               {       \r
+                       $this->_set_error_message('email_no_hostname');\r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_smtp_connect();\r
+               $this->_smtp_authenticate();\r
+\r
+               $this->_send_command('from', $this->clean_email($this->_headers['From']));\r
+\r
+               foreach($this->_recipients as $val)\r
+               {\r
+                       $this->_send_command('to', $val);\r
+               }\r
+       \r
+               if (count($this->_cc_array) > 0)\r
+               {\r
+                       foreach($this->_cc_array as $val)\r
+                       {\r
+                               if ($val != "")\r
+                               {\r
+                                       $this->_send_command('to', $val);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (count($this->_bcc_array) > 0)\r
+               {\r
+                       foreach($this->_bcc_array as $val)\r
+                       {\r
+                               if ($val != "")\r
+                               {\r
+                                       $this->_send_command('to', $val);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               $this->_send_command('data');\r
+\r
+               // perform dot transformation on any lines that begin with a dot\r
+               $this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));\r
+\r
+               $this->_send_data('.');\r
+\r
+               $reply = $this->_get_smtp_data();\r
+\r
+               $this->_set_error_message($reply);      \r
+\r
+               if (strncmp($reply, '250', 3) != 0)\r
+               {\r
+                       $this->_set_error_message('email_smtp_error', $reply);  \r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_send_command('quit');\r
+               return TRUE;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * SMTP Connect\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _smtp_connect()\r
+       {\r
+               $this->_smtp_connect = fsockopen($this->smtp_host,\r
+                                                                               $this->smtp_port,\r
+                                                                               $errno,\r
+                                                                               $errstr,\r
+                                                                               $this->smtp_timeout);\r
+\r
+               if( ! is_resource($this->_smtp_connect))\r
+               {               \r
+                       $this->_set_error_message('email_smtp_error', $errno." ".$errstr);\r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_set_error_message($this->_get_smtp_data());\r
+               return $this->_send_command('hello');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Send SMTP command\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _send_command($cmd, $data = '')\r
+       {\r
+               switch ($cmd)\r
+               {\r
+                       case 'hello' :\r
+\r
+                                       if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')\r
+                                               $this->_send_data('EHLO '.$this->_get_hostname());\r
+                                       else\r
+                                               $this->_send_data('HELO '.$this->_get_hostname());\r
+\r
+                                               $resp = 250;\r
+                       break;\r
+                       case 'from' :\r
+       \r
+                                               $this->_send_data('MAIL FROM:<'.$data.'>');\r
+\r
+                                               $resp = 250;\r
+                       break;\r
+                       case 'to'       :\r
+       \r
+                                               $this->_send_data('RCPT TO:<'.$data.'>');\r
+\r
+                                               $resp = 250;    \r
+                       break;\r
+                       case 'data'     :\r
+       \r
+                                               $this->_send_data('DATA');\r
+\r
+                                               $resp = 354;    \r
+                       break;\r
+                       case 'quit'     :\r
+\r
+                                               $this->_send_data('QUIT');\r
+\r
+                                               $resp = 221;\r
+                       break;\r
+               }\r
+\r
+               $reply = $this->_get_smtp_data();       \r
+\r
+               $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";\r
+\r
+               if (substr($reply, 0, 3) != $resp)\r
+               {\r
+                       $this->_set_error_message('email_smtp_error', $reply);\r
+                       return FALSE;\r
+               }\r
+       \r
+               if ($cmd == 'quit')\r
+               {\r
+                       fclose($this->_smtp_connect);\r
+               }\r
+       \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        *  SMTP Authenticate\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _smtp_authenticate()\r
+       {       \r
+               if ( ! $this->_smtp_auth)\r
+               {\r
+                       return TRUE;\r
+               }\r
+       \r
+               if ($this->smtp_user == ""  AND  $this->smtp_pass == "")\r
+               {\r
+                       $this->_set_error_message('email_no_smtp_unpw');\r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_send_data('AUTH LOGIN');\r
+\r
+               $reply = $this->_get_smtp_data();       \r
+\r
+               if (strncmp($reply, '334', 3) != 0)\r
+               {\r
+                       $this->_set_error_message('email_failed_smtp_login', $reply);   \r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_send_data(base64_encode($this->smtp_user));\r
+\r
+               $reply = $this->_get_smtp_data();       \r
+\r
+               if (strncmp($reply, '334', 3) != 0)\r
+               {\r
+                       $this->_set_error_message('email_smtp_auth_un', $reply);        \r
+                       return FALSE;\r
+               }\r
+\r
+               $this->_send_data(base64_encode($this->smtp_pass));\r
+\r
+               $reply = $this->_get_smtp_data();       \r
+\r
+               if (strncmp($reply, '235', 3) != 0)\r
+               {\r
+                       $this->_set_error_message('email_smtp_auth_pw', $reply);        \r
+                       return FALSE;\r
+               }\r
+       \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Send SMTP data\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _send_data($data)\r
+       {\r
+               if ( ! fwrite($this->_smtp_connect, $data . $this->newline))\r
+               {\r
+                       $this->_set_error_message('email_smtp_data_failure', $data);    \r
+                       return FALSE;\r
+               }\r
+               else\r
+               {\r
+                       return TRUE;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get SMTP data\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _get_smtp_data()\r
+       {\r
+               $data = "";\r
+\r
+               while ($str = fgets($this->_smtp_connect, 512))\r
+               {\r
+                       $data .= $str;\r
+       \r
+                       if (substr($str, 3, 1) == " ")\r
+                       {\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return $data;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Hostname\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _get_hostname()\r
+       {       \r
+               return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';    \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get IP\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _get_ip()\r
+       {\r
+               if ($this->_IP !== FALSE)\r
+               {\r
+                       return $this->_IP;\r
+               }\r
+       \r
+               $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;\r
+               $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;\r
+               $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;\r
+       \r
+               if ($cip && $rip)       $this->_IP = $cip;      \r
+               elseif ($rip)           $this->_IP = $rip;\r
+               elseif ($cip)           $this->_IP = $cip;\r
+               elseif ($fip)           $this->_IP = $fip;\r
+\r
+               if (strstr($this->_IP, ','))\r
+               {\r
+                       $x = explode(',', $this->_IP);\r
+                       $this->_IP = end($x);\r
+               }\r
+\r
+               if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))\r
+               {\r
+                       $this->_IP = '0.0.0.0';\r
+               }\r
+\r
+               unset($cip);\r
+               unset($rip);\r
+               unset($fip);\r
+\r
+               return $this->_IP;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Debug Message\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function print_debugger()\r
+       {\r
+               $msg = '';\r
+\r
+               if (count($this->_debug_msg) > 0)\r
+               {\r
+                       foreach ($this->_debug_msg as $val)\r
+                       {\r
+                               $msg .= $val;\r
+                       }\r
+               }\r
+\r
+               $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';    \r
+               return $msg;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Message\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _set_error_message($msg, $val = '')\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('email');\r
+       \r
+               if (FALSE === ($line = $CI->lang->line($msg)))\r
+               {       \r
+                       $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";\r
+               }       \r
+               else\r
+               {\r
+                       $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";\r
+               }       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Mime Types\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _mime_types($ext = "")\r
+       {\r
+               $mimes = array( 'hqx'   =>      'application/mac-binhex40',\r
+                                               'cpt'   =>      'application/mac-compactpro',\r
+                                               'doc'   =>      'application/msword',\r
+                                               'bin'   =>      'application/macbinary',\r
+                                               'dms'   =>      'application/octet-stream',\r
+                                               'lha'   =>      'application/octet-stream',\r
+                                               'lzh'   =>      'application/octet-stream',\r
+                                               'exe'   =>      'application/octet-stream',\r
+                                               'class' =>      'application/octet-stream',\r
+                                               'psd'   =>      'application/octet-stream',\r
+                                               'so'    =>      'application/octet-stream',\r
+                                               'sea'   =>      'application/octet-stream',\r
+                                               'dll'   =>      'application/octet-stream',\r
+                                               'oda'   =>      'application/oda',\r
+                                               'pdf'   =>      'application/pdf',\r
+                                               'ai'    =>      'application/postscript',\r
+                                               'eps'   =>      'application/postscript',\r
+                                               'ps'    =>      'application/postscript',\r
+                                               'smi'   =>      'application/smil',\r
+                                               'smil'  =>      'application/smil',\r
+                                               'mif'   =>      'application/vnd.mif',\r
+                                               'xls'   =>      'application/vnd.ms-excel',\r
+                                               'ppt'   =>      'application/vnd.ms-powerpoint',\r
+                                               'wbxml' =>      'application/vnd.wap.wbxml',\r
+                                               'wmlc'  =>      'application/vnd.wap.wmlc',\r
+                                               'dcr'   =>      'application/x-director',\r
+                                               'dir'   =>      'application/x-director',\r
+                                               'dxr'   =>      'application/x-director',\r
+                                               'dvi'   =>      'application/x-dvi',\r
+                                               'gtar'  =>      'application/x-gtar',\r
+                                               'php'   =>      'application/x-httpd-php',\r
+                                               'php4'  =>      'application/x-httpd-php',\r
+                                               'php3'  =>      'application/x-httpd-php',\r
+                                               'phtml' =>      'application/x-httpd-php',\r
+                                               'phps'  =>      'application/x-httpd-php-source',\r
+                                               'js'    =>      'application/x-javascript',\r
+                                               'swf'   =>      'application/x-shockwave-flash',\r
+                                               'sit'   =>      'application/x-stuffit',\r
+                                               'tar'   =>      'application/x-tar',\r
+                                               'tgz'   =>      'application/x-tar',\r
+                                               'xhtml' =>      'application/xhtml+xml',\r
+                                               'xht'   =>      'application/xhtml+xml',\r
+                                               'zip'   =>      'application/zip',\r
+                                               'mid'   =>      'audio/midi',\r
+                                               'midi'  =>      'audio/midi',\r
+                                               'mpga'  =>      'audio/mpeg',\r
+                                               'mp2'   =>      'audio/mpeg',\r
+                                               'mp3'   =>      'audio/mpeg',\r
+                                               'aif'   =>      'audio/x-aiff',\r
+                                               'aiff'  =>      'audio/x-aiff',\r
+                                               'aifc'  =>      'audio/x-aiff',\r
+                                               'ram'   =>      'audio/x-pn-realaudio',\r
+                                               'rm'    =>      'audio/x-pn-realaudio',\r
+                                               'rpm'   =>      'audio/x-pn-realaudio-plugin',\r
+                                               'ra'    =>      'audio/x-realaudio',\r
+                                               'rv'    =>      'video/vnd.rn-realvideo',\r
+                                               'wav'   =>      'audio/x-wav',\r
+                                               'bmp'   =>      'image/bmp',\r
+                                               'gif'   =>      'image/gif',\r
+                                               'jpeg'  =>      'image/jpeg',\r
+                                               'jpg'   =>      'image/jpeg',\r
+                                               'jpe'   =>      'image/jpeg',\r
+                                               'png'   =>      'image/png',\r
+                                               'tiff'  =>      'image/tiff',\r
+                                               'tif'   =>      'image/tiff',\r
+                                               'css'   =>      'text/css',\r
+                                               'html'  =>      'text/html',\r
+                                               'htm'   =>      'text/html',\r
+                                               'shtml' =>      'text/html',\r
+                                               'txt'   =>      'text/plain',\r
+                                               'text'  =>      'text/plain',\r
+                                               'log'   =>      'text/plain',\r
+                                               'rtx'   =>      'text/richtext',\r
+                                               'rtf'   =>      'text/rtf',\r
+                                               'xml'   =>      'text/xml',\r
+                                               'xsl'   =>      'text/xml',\r
+                                               'mpeg'  =>      'video/mpeg',\r
+                                               'mpg'   =>      'video/mpeg',\r
+                                               'mpe'   =>      'video/mpeg',\r
+                                               'qt'    =>      'video/quicktime',\r
+                                               'mov'   =>      'video/quicktime',\r
+                                               'avi'   =>      'video/x-msvideo',\r
+                                               'movie' =>      'video/x-sgi-movie',\r
+                                               'doc'   =>      'application/msword',\r
+                                               'word'  =>      'application/msword',\r
+                                               'xl'    =>      'application/excel',\r
+                                               'eml'   =>      'message/rfc822'\r
+                                       );\r
+\r
+               return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];\r
+       }\r
+\r
+}\r
+// END CI_Email class\r
+\r
+/* End of file Email.php */\r
+/* Location: ./system/libraries/Email.php */
\ No newline at end of file
diff --git a/libraries/Encrypt.php b/libraries/Encrypt.php
new file mode 100644 (file)
index 0000000..035ce8f
--- /dev/null
@@ -0,0 +1,484 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Encryption Class\r
+ *\r
+ * Provides two-way keyed encoding using XOR Hashing and Mcrypt\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/encryption.html\r
+ */\r
+class CI_Encrypt {\r
+\r
+       var $CI;\r
+       var $encryption_key     = '';\r
+       var $_hash_type = 'sha1';\r
+       var $_mcrypt_exists = FALSE;\r
+       var $_mcrypt_cipher;\r
+       var $_mcrypt_mode;\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Simply determines whether the mcrypt library exists.\r
+        *\r
+        */\r
+       function CI_Encrypt()\r
+       {\r
+               $this->CI =& get_instance();\r
+               $this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;\r
+               log_message('debug', "Encrypt Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch the encryption key\r
+        *\r
+        * Returns it as MD5 in order to have an exact-length 128 bit key.\r
+        * Mcrypt is sensitive to keys that are not the correct length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function get_key($key = '')\r
+       {\r
+               if ($key == '')\r
+               {\r
+                       if ($this->encryption_key != '')\r
+                       {\r
+                               return $this->encryption_key;\r
+                       }\r
+\r
+                       $CI =& get_instance();\r
+                       $key = $CI->config->item('encryption_key');\r
+\r
+                       if ($key === FALSE)\r
+                       {\r
+                               show_error('In order to use the encryption class requires that you set an encryption key in your config file.');\r
+                       }\r
+               }\r
+\r
+               return md5($key);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set the encryption key\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_key($key = '')\r
+       {\r
+               $this->encryption_key = $key;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Encode\r
+        *\r
+        * Encodes the message string using bitwise XOR encoding.\r
+        * The key is combined with a random hash, and then it\r
+        * too gets converted using XOR. The whole thing is then run\r
+        * through mcrypt (if supported) using the randomized key.\r
+        * The end result is a double-encrypted message string\r
+        * that is randomized with each call to this function,\r
+        * even if the supplied message and key are the same.\r
+        *\r
+        * @access      public\r
+        * @param       string  the string to encode\r
+        * @param       string  the key\r
+        * @return      string\r
+        */\r
+       function encode($string, $key = '')\r
+       {\r
+               $key = $this->get_key($key);\r
+               $enc = $this->_xor_encode($string, $key);\r
+               \r
+               if ($this->_mcrypt_exists === TRUE)\r
+               {\r
+                       $enc = $this->mcrypt_encode($enc, $key);\r
+               }\r
+               return base64_encode($enc);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Decode\r
+        *\r
+        * Reverses the above process\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function decode($string, $key = '')\r
+       {\r
+               $key = $this->get_key($key);\r
+               \r
+               if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $dec = base64_decode($string);\r
+\r
+               if ($this->_mcrypt_exists === TRUE)\r
+               {\r
+                       if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               return $this->_xor_decode($dec, $key);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * XOR Encode\r
+        *\r
+        * Takes a plain-text string and key as input and generates an\r
+        * encoded bit-string using XOR\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _xor_encode($string, $key)\r
+       {\r
+               $rand = '';\r
+               while (strlen($rand) < 32)\r
+               {\r
+                       $rand .= mt_rand(0, mt_getrandmax());\r
+               }\r
+\r
+               $rand = $this->hash($rand);\r
+\r
+               $enc = '';\r
+               for ($i = 0; $i < strlen($string); $i++)\r
+               {                       \r
+                       $enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));\r
+               }\r
+\r
+               return $this->_xor_merge($enc, $key);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * XOR Decode\r
+        *\r
+        * Takes an encoded string and key as input and generates the\r
+        * plain-text original message\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _xor_decode($string, $key)\r
+       {\r
+               $string = $this->_xor_merge($string, $key);\r
+\r
+               $dec = '';\r
+               for ($i = 0; $i < strlen($string); $i++)\r
+               {\r
+                       $dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));\r
+               }\r
+\r
+               return $dec;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * XOR key + string Combiner\r
+        *\r
+        * Takes a string and key as input and computes the difference using XOR\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _xor_merge($string, $key)\r
+       {\r
+               $hash = $this->hash($key);\r
+               $str = '';\r
+               for ($i = 0; $i < strlen($string); $i++)\r
+               {\r
+                       $str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Encrypt using Mcrypt\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function mcrypt_encode($data, $key)\r
+       {\r
+               $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());\r
+               $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);\r
+               return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Decrypt using Mcrypt\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function mcrypt_decode($data, $key)\r
+       {\r
+               $data = $this->_remove_cipher_noise($data, $key);\r
+               $init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());\r
+\r
+               if ($init_size > strlen($data))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $init_vect = substr($data, 0, $init_size);\r
+               $data = substr($data, $init_size);\r
+               return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Adds permuted noise to the IV + encrypted data to protect\r
+        * against Man-in-the-middle attacks on CBC mode ciphers\r
+        * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV\r
+        *\r
+        * Function description\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _add_cipher_noise($data, $key)\r
+       {\r
+               $keyhash = $this->hash($key);\r
+               $keylen = strlen($keyhash);\r
+               $str = '';\r
+\r
+               for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)\r
+               {\r
+                       if ($j >= $keylen)\r
+                       {\r
+                               $j = 0;\r
+                       }\r
+\r
+                       $str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Removes permuted noise from the IV + encrypted data, reversing\r
+        * _add_cipher_noise()\r
+        *\r
+        * Function description\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _remove_cipher_noise($data, $key)\r
+       {\r
+               $keyhash = $this->hash($key);\r
+               $keylen = strlen($keyhash);\r
+               $str = '';\r
+\r
+               for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)\r
+               {\r
+                       if ($j >= $keylen)\r
+                       {\r
+                               $j = 0;\r
+                       }\r
+\r
+                       $temp = ord($data[$i]) - ord($keyhash[$j]);\r
+\r
+                       if ($temp < 0)\r
+                       {\r
+                               $temp = $temp + 256;\r
+                       }\r
+                       \r
+                       $str .= chr($temp);\r
+               }\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Mcrypt Cipher\r
+        *\r
+        * @access      public\r
+        * @param       constant\r
+        * @return      string\r
+        */\r
+       function set_cipher($cipher)\r
+       {\r
+               $this->_mcrypt_cipher = $cipher;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set the Mcrypt Mode\r
+        *\r
+        * @access      public\r
+        * @param       constant\r
+        * @return      string\r
+        */\r
+       function set_mode($mode)\r
+       {\r
+               $this->_mcrypt_mode = $mode;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Mcrypt cipher Value\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _get_cipher()\r
+       {\r
+               if ($this->_mcrypt_cipher == '')\r
+               {\r
+                       $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;\r
+               }\r
+\r
+               return $this->_mcrypt_cipher;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get Mcrypt Mode Value\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _get_mode()\r
+       {\r
+               if ($this->_mcrypt_mode == '')\r
+               {\r
+                       $this->_mcrypt_mode = MCRYPT_MODE_ECB;\r
+               }\r
+               \r
+               return $this->_mcrypt_mode;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set the Hash type\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function set_hash($type = 'sha1')\r
+       {\r
+               $this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Hash encode a string\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function hash($str)\r
+       {\r
+               return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate an SHA1 Hash\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function sha1($str)\r
+       {\r
+               if ( ! function_exists('sha1'))\r
+               {\r
+                       if ( ! function_exists('mhash'))\r
+                       {\r
+                               require_once(BASEPATH.'libraries/Sha1'.EXT);\r
+                               $SH = new CI_SHA;\r
+                               return $SH->generate($str);\r
+                       }\r
+                       else\r
+                       {\r
+                               return bin2hex(mhash(MHASH_SHA1, $str));\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       return sha1($str);\r
+               }\r
+       }\r
+\r
+}\r
+\r
+// END CI_Encrypt class\r
+\r
+/* End of file Encrypt.php */\r
+/* Location: ./system/libraries/Encrypt.php */
\ No newline at end of file
diff --git a/libraries/Exceptions.php b/libraries/Exceptions.php
new file mode 100644 (file)
index 0000000..5858266
--- /dev/null
@@ -0,0 +1,172 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Exceptions Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Exceptions\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/exceptions.html\r
+ */\r
+class CI_Exceptions {\r
+       var $action;\r
+       var $severity;\r
+       var $message;\r
+       var $filename;\r
+       var $line;\r
+       var $ob_level;\r
+\r
+       var $levels = array(\r
+                                               E_ERROR                         =>      'Error',\r
+                                               E_WARNING                       =>      'Warning',\r
+                                               E_PARSE                         =>      'Parsing Error',\r
+                                               E_NOTICE                        =>      'Notice',\r
+                                               E_CORE_ERROR            =>      'Core Error',\r
+                                               E_CORE_WARNING          =>      'Core Warning',\r
+                                               E_COMPILE_ERROR         =>      'Compile Error',\r
+                                               E_COMPILE_WARNING       =>      'Compile Warning',\r
+                                               E_USER_ERROR            =>      'User Error',\r
+                                               E_USER_WARNING          =>      'User Warning',\r
+                                               E_USER_NOTICE           =>      'User Notice',\r
+                                               E_STRICT                        =>      'Runtime Notice'\r
+                                       );\r
+\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        */     \r
+       function CI_Exceptions()\r
+       {\r
+               $this->ob_level = ob_get_level();\r
+               // Note:  Do not log messages from this constructor.\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Exception Logger\r
+        *\r
+        * This function logs PHP generated error messages\r
+        *\r
+        * @access      private\r
+        * @param       string  the error severity\r
+        * @param       string  the error string\r
+        * @param       string  the error filepath\r
+        * @param       string  the error line number\r
+        * @return      string\r
+        */\r
+       function log_exception($severity, $message, $filepath, $line)\r
+       {       \r
+               $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];\r
+               \r
+               log_message('error', 'Severity: '.$severity.'  --> '.$message. ' '.$filepath.' '.$line, TRUE);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * 404 Page Not Found Handler\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function show_404($page = '')\r
+       {       \r
+               $heading = "404 Page Not Found";\r
+               $message = "The page you requested was not found.";\r
+\r
+               log_message('error', '404 Page Not Found --> '.$page);\r
+               echo $this->show_error($heading, $message, 'error_404');\r
+               exit;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * General Error Page\r
+        *\r
+        * This function takes an error message as input\r
+        * (either as a string or an array) and displays\r
+        * it using the specified template.\r
+        *\r
+        * @access      private\r
+        * @param       string  the heading\r
+        * @param       string  the message\r
+        * @param       string  the template name\r
+        * @return      string\r
+        */\r
+       function show_error($heading, $message, $template = 'error_general')\r
+       {\r
+               $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';\r
+\r
+               if (ob_get_level() > $this->ob_level + 1)\r
+               {\r
+                       ob_end_flush(); \r
+               }\r
+               ob_start();\r
+               include(APPPATH.'errors/'.$template.EXT);\r
+               $buffer = ob_get_contents();\r
+               ob_end_clean();\r
+               return $buffer;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Native PHP error handler\r
+        *\r
+        * @access      private\r
+        * @param       string  the error severity\r
+        * @param       string  the error string\r
+        * @param       string  the error filepath\r
+        * @param       string  the error line number\r
+        * @return      string\r
+        */\r
+       function show_php_error($severity, $message, $filepath, $line)\r
+       {       \r
+               $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];\r
+       \r
+               $filepath = str_replace("\\", "/", $filepath);\r
+               \r
+               // For safety reasons we do not show the full file path\r
+               if (FALSE !== strpos($filepath, '/'))\r
+               {\r
+                       $x = explode('/', $filepath);\r
+                       $filepath = $x[count($x)-2].'/'.end($x);\r
+               }\r
+               \r
+               if (ob_get_level() > $this->ob_level + 1)\r
+               {\r
+                       ob_end_flush(); \r
+               }\r
+               ob_start();\r
+               include(APPPATH.'errors/error_php'.EXT);\r
+               $buffer = ob_get_contents();\r
+               ob_end_clean();\r
+               echo $buffer;\r
+       }\r
+\r
+\r
+}\r
+// END Exceptions Class\r
+\r
+/* End of file Exceptions.php */\r
+/* Location: ./system/libraries/Exceptions.php */
\ No newline at end of file
diff --git a/libraries/Form_validation.php b/libraries/Form_validation.php
new file mode 100644 (file)
index 0000000..1215e13
--- /dev/null
@@ -0,0 +1,1280 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Form Validation Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Validation\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/form_validation.html\r
+ */\r
+class CI_Form_validation {\r
+       \r
+       var $CI;\r
+       var $_field_data                        = array();      \r
+       var $_config_rules                      = array();\r
+       var $_error_array                       = array();\r
+       var $_error_messages            = array();      \r
+       var $_error_prefix                      = '<p>';\r
+       var $_error_suffix                      = '</p>';\r
+       var $error_string                       = '';\r
+       var $_safe_form_data            = FALSE;\r
+\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        */     \r
+       function CI_Form_validation($rules = array())\r
+       {       \r
+               $this->CI =& get_instance();\r
+               \r
+               // Validation rules can be stored in a config file.\r
+               $this->_config_rules = $rules;\r
+               \r
+               // Automatically load the form helper\r
+               $this->CI->load->helper('form');\r
+\r
+               // Set the character encoding in MB.\r
+               if (function_exists('mb_internal_encoding'))\r
+               {\r
+                       mb_internal_encoding($this->CI->config->item('charset'));\r
+               }\r
+       \r
+               log_message('debug', "Validation Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Rules\r
+        *\r
+        * This function takes an array of field names and validation\r
+        * rules as input, validates the info, and stores it\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_rules($field, $label = '', $rules = '')\r
+       {\r
+               // No reason to set rules if we have no POST data\r
+               if (count($_POST) == 0)\r
+               {\r
+                       return;\r
+               }\r
+       \r
+               // If an array was passed via the first parameter instead of indidual string\r
+               // values we cycle through it and recursively call this function.\r
+               if (is_array($field))\r
+               {\r
+                       foreach ($field as $row)\r
+                       {\r
+                               // Houston, we have a problem...\r
+                               if ( ! isset($row['field']) OR ! isset($row['rules']))\r
+                               {\r
+                                       continue;\r
+                               }\r
+\r
+                               // If the field label wasn't passed we use the field name\r
+                               $label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];\r
+\r
+                               // Here we go!\r
+                               $this->set_rules($row['field'], $label, $row['rules']);\r
+                       }\r
+                       return;\r
+               }\r
+               \r
+               // No fields? Nothing to do...\r
+               if ( ! is_string($field) OR  ! is_string($rules) OR $field == '')\r
+               {\r
+                       return;\r
+               }\r
+\r
+               // If the field label wasn't passed we use the field name\r
+               $label = ($label == '') ? $field : $label;\r
+\r
+               // Is the field name an array?  We test for the existence of a bracket "[" in\r
+               // the field name to determine this.  If it is an array, we break it apart\r
+               // into its components so that we can fetch the corresponding POST data later           \r
+               if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))\r
+               {       \r
+                       // Note: Due to a bug in current() that affects some versions\r
+                       // of PHP we can not pass function call directly into it\r
+                       $x = explode('[', $field);\r
+                       $indexes[] = current($x);\r
+\r
+                       for ($i = 0; $i < count($matches['0']); $i++)\r
+                       {\r
+                               if ($matches['1'][$i] != '')\r
+                               {\r
+                                       $indexes[] = $matches['1'][$i];\r
+                               }\r
+                       }\r
+                       \r
+                       $is_array = TRUE;\r
+               }\r
+               else\r
+               {\r
+                       $indexes        = array();\r
+                       $is_array       = FALSE;                \r
+               }\r
+               \r
+               // Build our master array               \r
+               $this->_field_data[$field] = array(\r
+                                                                                       'field'                         => $field, \r
+                                                                                       'label'                         => $label, \r
+                                                                                       'rules'                         => $rules,\r
+                                                                                       'is_array'                      => $is_array,\r
+                                                                                       'keys'                          => $indexes,\r
+                                                                                       'postdata'                      => NULL,\r
+                                                                                       'error'                         => ''\r
+                                                                                       );\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Error Message\r
+        *\r
+        * Lets users set their own error messages on the fly.  Note:  The key\r
+        * name has to match the  function name that it corresponds to.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function set_message($lang, $val = '')\r
+       {\r
+               if ( ! is_array($lang))\r
+               {\r
+                       $lang = array($lang => $val);\r
+               }\r
+       \r
+               $this->_error_messages = array_merge($this->_error_messages, $lang);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set The Error Delimiter\r
+        *\r
+        * Permits a prefix/suffix to be added to each error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_error_delimiters($prefix = '<p>', $suffix = '</p>')\r
+       {\r
+               $this->_error_prefix = $prefix;\r
+               $this->_error_suffix = $suffix;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get Error Message\r
+        *\r
+        * Gets the error message associated with a particular field\r
+        *\r
+        * @access      public\r
+        * @param       string  the field name\r
+        * @return      void\r
+        */     \r
+       function error($field = '', $prefix = '', $suffix = '')\r
+       {       \r
+               if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               if ($prefix == '')\r
+               {\r
+                       $prefix = $this->_error_prefix;\r
+               }\r
+\r
+               if ($suffix == '')\r
+               {\r
+                       $suffix = $this->_error_suffix;\r
+               }\r
+\r
+               return $prefix.$this->_field_data[$field]['error'].$suffix;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Error String\r
+        *\r
+        * Returns the error messages as a string, wrapped in the error delimiters\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      str\r
+        */     \r
+       function error_string($prefix = '', $suffix = '')\r
+       {\r
+               // No errrors, validation passes!\r
+               if (count($this->_error_array) === 0)\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               if ($prefix == '')\r
+               {\r
+                       $prefix = $this->_error_prefix;\r
+               }\r
+\r
+               if ($suffix == '')\r
+               {\r
+                       $suffix = $this->_error_suffix;\r
+               }\r
+               \r
+               // Generate the error string\r
+               $str = '';\r
+               foreach ($this->_error_array as $val)\r
+               {\r
+                       if ($val != '')\r
+                       {\r
+                               $str .= $prefix.$val.$suffix."\n";\r
+                       }\r
+               }\r
+               \r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Run the Validator\r
+        *\r
+        * This function does all the work.\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function run($group = '')\r
+       {\r
+               // Do we even have any data to process?  Mm?\r
+               if (count($_POST) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Does the _field_data array containing the validation rules exist?\r
+               // If not, we look to see if they were assigned via a config file\r
+               if (count($this->_field_data) == 0)\r
+               {\r
+                       // No validation rules?  We're done...\r
+                       if (count($this->_config_rules) == 0)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       // Is there a validation rule for the particular URI being accessed?\r
+                       $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;\r
+                       \r
+                       if ($uri != '' AND isset($this->_config_rules[$uri]))\r
+                       {\r
+                               $this->set_rules($this->_config_rules[$uri]);\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->set_rules($this->_config_rules);\r
+                       }\r
+       \r
+                       // We're we able to set the rules correctly?\r
+                       if (count($this->_field_data) == 0)\r
+                       {\r
+                               log_message('debug', "Unable to find validation rules");\r
+                               return FALSE;\r
+                       }\r
+               }\r
+       \r
+               // Load the language file containing error messages\r
+               $this->CI->lang->load('form_validation');\r
+                                                       \r
+               // Cycle through the rules for each field, match the \r
+               // corresponding $_POST item and test for errors\r
+               foreach ($this->_field_data as $field => $row)\r
+               {               \r
+                       // Fetch the data from the corresponding $_POST array and cache it in the _field_data array.\r
+                       // Depending on whether the field name is an array or a string will determine where we get it from.\r
+                       \r
+                       if ($row['is_array'] == TRUE)\r
+                       {\r
+                               $this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);\r
+                       }\r
+                       else\r
+                       {\r
+                               if (isset($_POST[$field]) AND $_POST[$field] != "")\r
+                               {\r
+                                       $this->_field_data[$field]['postdata'] = $_POST[$field];\r
+                               }\r
+                       }\r
+               \r
+                       $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);             \r
+               }\r
+\r
+               // Did we end up with any errors?\r
+               $total_errors = count($this->_error_array);\r
+\r
+               if ($total_errors > 0)\r
+               {\r
+                       $this->_safe_form_data = TRUE;\r
+               }\r
+\r
+               // Now we need to re-set the POST data with the new, processed data\r
+               $this->_reset_post_array();\r
+               \r
+               // No errors, validation passes!\r
+               if ($total_errors == 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               // Validation fails\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Traverse a multidimensional $_POST array index until the data is found\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @param       array\r
+        * @param       integer\r
+        * @return      mixed\r
+        */             \r
+       function _reduce_array($array, $keys, $i = 0)\r
+       {\r
+               if (is_array($array))\r
+               {\r
+                       if (isset($keys[$i]))\r
+                       {\r
+                               if (isset($array[$keys[$i]]))\r
+                               {\r
+                                       $array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));\r
+                               }\r
+                               else\r
+                               {\r
+                                       return NULL;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               return $array;\r
+                       }\r
+               }\r
+       \r
+               return $array;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Re-populate the _POST array with our finalized and processed data\r
+        *\r
+        * @access      private\r
+        * @return      null\r
+        */             \r
+       function _reset_post_array()\r
+       {\r
+               foreach ($this->_field_data as $field => $row)\r
+               {\r
+                       if ( ! is_null($row['postdata']))\r
+                       {\r
+                               if ($row['is_array'] == FALSE)\r
+                               {\r
+                                       if (isset($_POST[$row['field']]))\r
+                                       {\r
+                                               $_POST[$row['field']] = $this->prep_for_form($row['postdata']);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       $post = '$_POST["';\r
+                                       \r
+                                       if (count($row['keys']) == 1)\r
+                                       {\r
+                                               $post .= current($row['keys']);\r
+                                               $post .= '"]';\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $i = 0;\r
+                                               foreach ($row['keys'] as $val)\r
+                                               {\r
+                                                       if ($i == 0)\r
+                                                       {\r
+                                                               $post .= $val.'"]';\r
+                                                               $i++;\r
+                                                               continue;\r
+                                                       }\r
+                                               \r
+                                                       $post .= '["'.$val.'"]';\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (is_array($row['postdata']))\r
+                                       {                                       \r
+                                               $array = array();\r
+                                               foreach ($row['postdata'] as $k => $v)\r
+                                               {\r
+                                                       $array[$k] = $this->prep_for_form($v);\r
+                                               }\r
+                                               \r
+                                               $post .= ' = $array;';\r
+                                       }\r
+                                       else\r
+                                       {                                               \r
+                                               $post .= ' = "'.$this->prep_for_form($row['postdata']).'";';\r
+                                       }\r
+\r
+                                       eval($post);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Executes the Validation routines\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @param       array\r
+        * @param       mixed\r
+        * @param       integer\r
+        * @return      mixed\r
+        */     \r
+       function _execute($row, $rules, $postdata = NULL, $cycles = 0)\r
+       {\r
+               // If the $_POST data is an array we will run a recursive call\r
+               if (is_array($postdata))\r
+               { \r
+                       foreach ($postdata as $key => $val)\r
+                       {\r
+                               $this->_execute($row, $rules, $val, $cycles);\r
+                               $cycles++;\r
+                       }\r
+                       \r
+                       return;\r
+               }\r
+               \r
+               // --------------------------------------------------------------------\r
+\r
+               // If the field is blank, but NOT required, no further tests are necessary\r
+               $callback = FALSE;\r
+               if ( ! in_array('required', $rules) AND is_null($postdata))\r
+               {\r
+                       // Before we bail out, does the rule contain a callback?\r
+                       if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))\r
+                       {\r
+                               $callback = TRUE;\r
+                               $rules = (array('1' => $match[1]));\r
+                       }\r
+                       else\r
+                       {\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               // --------------------------------------------------------------------\r
+               \r
+               // Isset Test. Typically this rule will only apply to checkboxes.\r
+               if (is_null($postdata) AND $callback == FALSE)\r
+               {\r
+                       if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))\r
+                       {\r
+                               // Set the message type\r
+                               $type = (in_array('required', $rules)) ? 'required' : 'isset';\r
+                       \r
+                               if ( ! isset($this->_error_messages[$type]))\r
+                               {\r
+                                       if (FALSE === ($line = $this->CI->lang->line($type)))\r
+                                       {\r
+                                               $line = 'The field was not set';\r
+                                       }                                                       \r
+                               }\r
+                               else\r
+                               {\r
+                                       $line = $this->_error_messages[$type];\r
+                               }\r
+                               \r
+                               // Build the error message\r
+                               $message = sprintf($line, $this->_translate_fieldname($row['label']));\r
+\r
+                               // Save the error message\r
+                               $this->_field_data[$row['field']]['error'] = $message;\r
+                               \r
+                               if ( ! isset($this->_error_array[$row['field']]))\r
+                               {\r
+                                       $this->_error_array[$row['field']] = $message;\r
+                               }\r
+                       }\r
+                                       \r
+                       return;\r
+               }\r
+\r
+               // --------------------------------------------------------------------\r
+\r
+               // Cycle through each rule and run it\r
+               foreach ($rules As $rule)\r
+               {\r
+                       $_in_array = FALSE;\r
+                       \r
+                       // We set the $postdata variable with the current data in our master array so that\r
+                       // each cycle of the loop is dealing with the processed data from the last cycle\r
+                       if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))\r
+                       {\r
+                               // We shouldn't need this safety, but just in case there isn't an array index\r
+                               // associated with this cycle we'll bail out\r
+                               if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))\r
+                               {\r
+                                       continue;\r
+                               }\r
+                       \r
+                               $postdata = $this->_field_data[$row['field']]['postdata'][$cycles];\r
+                               $_in_array = TRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               $postdata = $this->_field_data[$row['field']]['postdata'];\r
+                       }\r
+\r
+                       // --------------------------------------------------------------------\r
+       \r
+                       // Is the rule a callback?                      \r
+                       $callback = FALSE;\r
+                       if (substr($rule, 0, 9) == 'callback_')\r
+                       {\r
+                               $rule = substr($rule, 9);\r
+                               $callback = TRUE;\r
+                       }\r
+                       \r
+                       // Strip the parameter (if exists) from the rule\r
+                       // Rules can contain a parameter: max_length[5]\r
+                       $param = FALSE;\r
+                       if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))\r
+                       {\r
+                               $rule   = $match[1];\r
+                               $param  = $match[2];\r
+                       }\r
+                       \r
+                       // Call the function that corresponds to the rule\r
+                       if ($callback === TRUE)\r
+                       {\r
+                               if ( ! method_exists($this->CI, $rule))\r
+                               {               \r
+                                       continue;\r
+                               }\r
+                               \r
+                               // Run the function and grab the result\r
+                               $result = $this->CI->$rule($postdata, $param);\r
+\r
+                               // Re-assign the result to the master data array\r
+                               if ($_in_array == TRUE)\r
+                               {\r
+                                       $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;\r
+                               }\r
+                       \r
+                               // If the field isn't required and we just processed a callback we'll move on...\r
+                               if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)\r
+                               {\r
+                                       return;\r
+                               }\r
+                       }\r
+                       else\r
+                       {                               \r
+                               if ( ! method_exists($this, $rule))\r
+                               {\r
+                                       // If our own wrapper function doesn't exist we see if a native PHP function does. \r
+                                       // Users can use any native PHP function call that has one param.\r
+                                       if (function_exists($rule))\r
+                                       {\r
+                                               $result = $rule($postdata);\r
+                                                                                       \r
+                                               if ($_in_array == TRUE)\r
+                                               {\r
+                                                       $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;\r
+                                               }\r
+                                       }\r
+                                                                               \r
+                                       continue;\r
+                               }\r
+\r
+                               $result = $this->$rule($postdata, $param);\r
+\r
+                               if ($_in_array == TRUE)\r
+                               {\r
+                                       $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;\r
+                               }\r
+                       }\r
+                                                       \r
+                       // Did the rule test negatively?  If so, grab the error.\r
+                       if ($result === FALSE)\r
+                       {                       \r
+                               if ( ! isset($this->_error_messages[$rule]))\r
+                               {\r
+                                       if (FALSE === ($line = $this->CI->lang->line($rule)))\r
+                                       {\r
+                                               $line = 'Unable to access an error message corresponding to your field name.';\r
+                                       }                                               \r
+                               }\r
+                               else\r
+                               {\r
+                                       $line = $this->_error_messages[$rule];\r
+                               }\r
+\r
+                               // Build the error message\r
+                               $message = sprintf($line, $this->_translate_fieldname($row['label']), $param);\r
+\r
+                               // Save the error message\r
+                               $this->_field_data[$row['field']]['error'] = $message;\r
+                               \r
+                               if ( ! isset($this->_error_array[$row['field']]))\r
+                               {\r
+                                       $this->_error_array[$row['field']] = $message;\r
+                               }\r
+                               \r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Translate a field name\r
+        *\r
+        * @access      private\r
+        * @param       string  the field name\r
+        * @return      string\r
+        */     \r
+       function _translate_fieldname($fieldname)\r
+       {\r
+               // Do we need to translate the field name?\r
+               // We look for the prefix lang: to determine this\r
+               if (substr($fieldname, 0, 5) == 'lang:')\r
+               {\r
+                       // Grab the variable\r
+                       $line = substr($fieldname, 5);                  \r
+                       \r
+                       // Were we able to translate the field name?  If not we use $line\r
+                       if (FALSE === ($fieldname = $this->CI->lang->line($line)))\r
+                       {\r
+                               return $line;\r
+                       }\r
+               }\r
+\r
+               return $fieldname;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the value from a form\r
+        *\r
+        * Permits you to repopulate a form field with the value it was submitted\r
+        * with, or, if that value doesn't exist, with the default\r
+        *\r
+        * @access      public\r
+        * @param       string  the field name\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_value($field = '', $default = '')\r
+       {\r
+               if ( ! isset($this->_field_data[$field]))\r
+               {\r
+                       return $default;\r
+               }\r
+               \r
+               return $this->_field_data[$field]['postdata'];\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Select\r
+        *\r
+        * Enables pull-down lists to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_select($field = '', $value = '', $default = FALSE)\r
+       {               \r
+               if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))\r
+               {\r
+                       if ($default === TRUE AND count($this->_field_data) === 0)\r
+                       {\r
+                               return ' selected="selected"';\r
+                       }\r
+                       return '';\r
+               }\r
+       \r
+               $field = $this->_field_data[$field]['postdata'];\r
+               \r
+               if (is_array($field))\r
+               {\r
+                       if ( ! in_array($value, $field))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if (($field == '' OR $value == '') OR ($field != $value))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+                       \r
+               return ' selected="selected"';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Radio\r
+        *\r
+        * Enables radio buttons to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_radio($field = '', $value = '', $default = FALSE)\r
+       {\r
+               if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))\r
+               {\r
+                       if ($default === TRUE AND count($this->_field_data) === 0)\r
+                       {\r
+                               return ' checked="checked"';\r
+                       }\r
+                       return '';\r
+               }\r
+       \r
+               $field = $this->_field_data[$field]['postdata'];\r
+               \r
+               if (is_array($field))\r
+               {\r
+                       if ( ! in_array($value, $field))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if (($field == '' OR $value == '') OR ($field != $value))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+                       \r
+               return ' checked="checked"';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Checkbox\r
+        *\r
+        * Enables checkboxes to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_checkbox($field = '', $value = '', $default = FALSE)\r
+       {\r
+               if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))\r
+               {\r
+                       if ($default === TRUE AND count($this->_field_data) === 0)\r
+                       {\r
+                               return ' checked="checked"';\r
+                       }\r
+                       return '';\r
+               }\r
+       \r
+               $field = $this->_field_data[$field]['postdata'];\r
+               \r
+               if (is_array($field))\r
+               {\r
+                       if ( ! in_array($value, $field))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if (($field == '' OR $value == '') OR ($field != $value))\r
+                       {\r
+                               return '';\r
+                       }\r
+               }\r
+                       \r
+               return ' checked="checked"';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Required\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function required($str)\r
+       {\r
+               if ( ! is_array($str))\r
+               {\r
+                       return (trim($str) == '') ? FALSE : TRUE;\r
+               }\r
+               else\r
+               {\r
+                       return ( ! empty($str));\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Match one field to another\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       field\r
+        * @return      bool\r
+        */\r
+       function matches($str, $field)\r
+       {\r
+               if ( ! isset($_POST[$field]))\r
+               {\r
+                       return FALSE;                           \r
+               }\r
+               \r
+               $field = $_POST[$field];\r
+\r
+               return ($str !== $field) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Minimum Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function min_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) < $val) ? FALSE : TRUE;         \r
+               }\r
+       \r
+               return (strlen($str) < $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Max Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function max_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) > $val) ? FALSE : TRUE;         \r
+               }\r
+       \r
+               return (strlen($str) > $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Exact Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function exact_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) != $val) ? FALSE : TRUE;                \r
+               }\r
+       \r
+               return (strlen($str) != $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Email\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function valid_email($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Emails\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function valid_emails($str)\r
+       {\r
+               if (strpos($str, ',') === FALSE)\r
+               {\r
+                       return $this->valid_email(trim($str));\r
+               }\r
+               \r
+               foreach(explode(',', $str) as $email)\r
+               {\r
+                       if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validate IP Address\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function valid_ip($ip)\r
+       {\r
+               return $this->CI->input->valid_ip($ip);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */             \r
+       function alpha($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha-numeric\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function alpha_numeric($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha-numeric with underscores and dashes\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function alpha_dash($str)\r
+       {\r
+               return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Numeric\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function numeric($str)\r
+       {\r
+               return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);\r
+\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+    /**\r
+     * Is Numeric\r
+     *\r
+     * @access    public\r
+     * @param    string\r
+     * @return    bool\r
+     */\r
+    function is_numeric($str)\r
+    {\r
+        return ( ! is_numeric($str)) ? FALSE : TRUE;\r
+    } \r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Integer\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function integer($str)\r
+       {\r
+               return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+    /**\r
+     * Is a Natural number  (0,1,2,3, etc.)\r
+     *\r
+     * @access public\r
+     * @param  string\r
+     * @return bool\r
+     */\r
+    function is_natural($str)\r
+    {   \r
+               return (bool)preg_match( '/^[0-9]+$/', $str);\r
+    }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+    /**\r
+     * Is a Natural number, but not a zero  (1,2,3, etc.)\r
+     *\r
+     * @access public\r
+     * @param  string\r
+     * @return bool\r
+     */\r
+       function is_natural_no_zero($str)\r
+    {\r
+       if ( ! preg_match( '/^[0-9]+$/', $str))\r
+       {\r
+               return FALSE;\r
+       }\r
+       \r
+       if ($str == 0)\r
+       {\r
+               return FALSE;\r
+       }\r
+    \r
+               return TRUE;\r
+    }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Base64\r
+        *\r
+        * Tests a string for characters outside of the Base64 alphabet\r
+        * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function valid_base64($str)\r
+       {\r
+               return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep data for form\r
+        *\r
+        * This function allows HTML to be safely shown in a form.\r
+        * Special characters are converted.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function prep_for_form($data = '')\r
+       {\r
+               if (is_array($data))\r
+               {\r
+                       foreach ($data as $key => $val)\r
+                       {\r
+                               $data[$key] = $this->prep_for_form($val);\r
+                       }\r
+                       \r
+                       return $data;\r
+               }\r
+               \r
+               if ($this->_safe_form_data == FALSE OR $data === '')\r
+               {\r
+                       return $data;\r
+               }\r
+\r
+               return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep URL\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function prep_url($str = '')\r
+       {\r
+               if ($str == 'http://' OR $str == '')\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')\r
+               {\r
+                       $str = 'http://'.$str;\r
+               }\r
+               \r
+               return $str;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Strip Image Tags\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function strip_image_tags($str)\r
+       {\r
+               return $this->CI->input->strip_image_tags($str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * XSS Clean\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function xss_clean($str)\r
+       {\r
+               return $this->CI->input->xss_clean($str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Convert PHP tags to entities\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function encode_php_tags($str)\r
+       {\r
+               return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);\r
+       }\r
+\r
+}\r
+// END Form Validation Class\r
+\r
+/* End of file Form_validation.php */\r
+/* Location: ./system/libraries/Form_validation.php */
\ No newline at end of file
diff --git a/libraries/Ftp.php b/libraries/Ftp.php
new file mode 100644 (file)
index 0000000..0e3dd5e
--- /dev/null
@@ -0,0 +1,618 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * FTP Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/ftp.html\r
+ */ \r
+class CI_FTP {\r
+\r
+       var $hostname   = '';\r
+       var $username   = '';\r
+       var $password   = '';\r
+       var $port               = 21;\r
+       var $passive    = TRUE;\r
+       var $debug              = FALSE;\r
+       var $conn_id    = FALSE;\r
+\r
+\r
+       /**\r
+        * Constructor - Sets Preferences\r
+        *\r
+        * The constructor can be passed an array of config values\r
+        */     \r
+       function CI_FTP($config = array())\r
+       {               \r
+               if (count($config) > 0)\r
+               {\r
+                       $this->initialize($config);\r
+               }       \r
+\r
+               log_message('debug', "FTP Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize preferences\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */     \r
+       function initialize($config = array())\r
+       {\r
+               foreach ($config as $key => $val)\r
+               {\r
+                       if (isset($this->$key))\r
+                       {\r
+                               $this->$key = $val;\r
+                       }\r
+               }\r
+               \r
+               // Prep the hostname\r
+               $this->hostname = preg_replace('|.+?://|', '', $this->hostname);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * FTP Connect\r
+        *\r
+        * @access      public\r
+        * @param       array    the connection values\r
+        * @return      bool\r
+        */     \r
+       function connect($config = array())\r
+       {               \r
+               if (count($config) > 0)\r
+               {\r
+                       $this->initialize($config);\r
+               }       \r
+       \r
+               if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_connect');\r
+                       }               \r
+                       return FALSE;\r
+               }\r
+               \r
+               if ( ! $this->_login())\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_login');\r
+                       }               \r
+                       return FALSE;\r
+               }\r
+               \r
+               // Set passive mode if needed\r
+               if ($this->passive == TRUE)\r
+               {\r
+                       ftp_pasv($this->conn_id, TRUE);\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * FTP Login\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _login()\r
+       {\r
+               return @ftp_login($this->conn_id, $this->username, $this->password);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Validates the connection ID\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */     \r
+       function _is_conn()\r
+       {\r
+               if ( ! is_resource($this->conn_id))\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_no_connection');\r
+                       }               \r
+                       return FALSE;\r
+               }\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+\r
+       /**\r
+        * Change direcotry\r
+        *\r
+        * The second parameter lets us momentarily turn off debugging so that\r
+        * this function can be used to test for the existance of a folder\r
+        * without throwing an error.  There's no FTP equivalent to is_dir()\r
+        * so we do it by trying to change to a particular directory.  \r
+        * Internally, this paramter is only used by the "mirror" function below.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      bool\r
+        */     \r
+       function changedir($path = '', $supress_debug = FALSE)\r
+       {\r
+               if ($path == '' OR ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $result = @ftp_chdir($this->conn_id, $path);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE AND $supress_debug == FALSE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_changedir');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Create a directory\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function mkdir($path = '', $permissions = NULL)\r
+       {\r
+               if ($path == '' OR ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               $result = @ftp_mkdir($this->conn_id, $path);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_makdir');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+\r
+               // Set file permissions if needed\r
+               if ( ! is_null($permissions))\r
+               {\r
+                       $this->chmod($path, (int)$permissions);\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Upload a file to the server\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if ( ! file_exists($locpath))\r
+               {\r
+                       $this->_error('ftp_no_source_file');\r
+                       return FALSE;\r
+               }\r
+       \r
+               // Set the mode if not specified\r
+               if ($mode == 'auto')\r
+               {\r
+                       // Get the file extension so we can set the upload type\r
+                       $ext = $this->_getext($locpath);\r
+                       $mode = $this->_settype($ext);\r
+               }\r
+               \r
+               $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;\r
+               \r
+               $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_upload');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               // Set file permissions if needed\r
+               if ( ! is_null($permissions))\r
+               {\r
+                       $this->chmod($rempath, (int)$permissions);\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename (or move) a file\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      bool\r
+        */     \r
+       function rename($old_file, $new_file, $move = FALSE)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $result = @ftp_rename($this->conn_id, $old_file, $new_file);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';\r
+                               \r
+                               $this->_error($msg);\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Move a file\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function move($old_file, $new_file)\r
+       {\r
+               return $this->rename($old_file, $new_file, TRUE);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Rename (or move) a file\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function delete_file($filepath)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $result = @ftp_delete($this->conn_id, $filepath);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {                               \r
+                               $this->_error('ftp_unable_to_delete');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Delete a folder and recursively delete everything (including sub-folders)\r
+        * containted within it.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function delete_dir($filepath)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // Add a trailing slash to the file path if needed\r
+               $filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);\r
+               \r
+               $list = $this->list_files($filepath);\r
+               \r
+               if ($list !== FALSE AND count($list) > 0)\r
+               {\r
+                       foreach ($list as $item)\r
+                       {                       \r
+                               // If we can't delete the item it's probaly a folder so\r
+                               // we'll recursively call delete_dir()\r
+                               if ( ! @ftp_delete($this->conn_id, $item))\r
+                               {\r
+                                       $this->delete_dir($item);\r
+                               }\r
+                       }\r
+               }\r
+       \r
+               $result = @ftp_rmdir($this->conn_id, $filepath);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {                               \r
+                               $this->_error('ftp_unable_to_delete');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set file permissions\r
+        *\r
+        * @access      public\r
+        * @param       string  the file path\r
+        * @param       string  the permissions\r
+        * @return      bool\r
+        */             \r
+       function chmod($path, $perm)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // Permissions can only be set when running PHP 5\r
+               if ( ! function_exists('ftp_chmod'))\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_chmod');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+       \r
+               $result = @ftp_chmod($this->conn_id, $perm, $path);\r
+               \r
+               if ($result === FALSE)\r
+               {\r
+                       if ($this->debug == TRUE)\r
+                       {\r
+                               $this->_error('ftp_unable_to_chmod');\r
+                       }               \r
+                       return FALSE;           \r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * FTP List files in the specified directory\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */     \r
+       function list_files($path = '.')\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return ftp_nlist($this->conn_id, $path);\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Read a directory and recreate it remotely\r
+        *\r
+        * This function recursively reads a folder and everything it contains (including\r
+        * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure\r
+        * of the original file path will be recreated on the server.\r
+        *\r
+        * @access      public\r
+        * @param       string  path to source with trailing slash\r
+        * @param       string  path to destination - include the base folder with trailing slash\r
+        * @return      bool\r
+        */     \r
+       function mirror($locpath, $rempath)\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               // Open the local file path\r
+               if ($fp = @opendir($locpath))\r
+               {\r
+                       // Attempt to open the remote file path.\r
+                       if ( ! $this->changedir($rempath, TRUE))\r
+                       {\r
+                               // If it doesn't exist we'll attempt to create the direcotory\r
+                               if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))\r
+                               {\r
+                                       return FALSE;\r
+                               }\r
+                       }\r
+               \r
+                       // Recursively read the local directory\r
+                       while (FALSE !== ($file = readdir($fp)))\r
+                       {\r
+                               if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')\r
+                               {                                       \r
+                                       $this->mirror($locpath.$file."/", $rempath.$file."/");\r
+                               }\r
+                               elseif (substr($file, 0, 1) != ".")\r
+                               {\r
+                                       // Get the file extension so we can se the upload type\r
+                                       $ext = $this->_getext($file);\r
+                                       $mode = $this->_settype($ext);\r
+                                       \r
+                                       $this->upload($locpath.$file, $rempath.$file, $mode);\r
+                               }\r
+                       }\r
+                       return TRUE;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Extract the file extension\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _getext($filename)\r
+       {\r
+               if (FALSE === strpos($filename, '.'))\r
+               {\r
+                       return 'txt';\r
+               }\r
+       \r
+               $x = explode('.', $filename);\r
+               return end($x);\r
+       }       \r
+\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the upload type\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _settype($ext)\r
+       {\r
+               $text_types = array(\r
+                                                       'txt',\r
+                                                       'text',\r
+                                                       'php',\r
+                                                       'phps',\r
+                                                       'php4',\r
+                                                       'js',\r
+                                                       'css',\r
+                                                       'htm',\r
+                                                       'html',\r
+                                                       'phtml',\r
+                                                       'shtml',\r
+                                                       'log',\r
+                                                       'xml'\r
+                                                       );\r
+       \r
+       \r
+               return (in_array($ext, $text_types)) ? 'ascii' : 'binary';\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Close the connection\r
+        *\r
+        * @access      public\r
+        * @param       string  path to source\r
+        * @param       string  path to destination\r
+        * @return      bool\r
+        */     \r
+       function close()\r
+       {\r
+               if ( ! $this->_is_conn())\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               @ftp_close($this->conn_id);\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Display error message\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function _error($line)\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('ftp');\r
+               show_error($CI->lang->line($line));             \r
+       }\r
+\r
+\r
+}\r
+// END FTP Class\r
+\r
+/* End of file Ftp.php */\r
+/* Location: ./system/libraries/Ftp.php */
\ No newline at end of file
diff --git a/libraries/Hooks.php b/libraries/Hooks.php
new file mode 100644 (file)
index 0000000..34dd98f
--- /dev/null
@@ -0,0 +1,226 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Hooks Class\r
+ *\r
+ * Provides a mechanism to extend the base system without hacking.  Most of\r
+ * this class is borrowed from Paul's Extension class in ExpressionEngine.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/encryption.html\r
+ */\r
+class CI_Hooks {\r
+       \r
+       var $enabled            = FALSE;\r
+       var $hooks              = array();\r
+       var $in_progress        = FALSE;\r
+       \r
+       /**\r
+        * Constructor\r
+        *\r
+        */\r
+       function CI_Hooks()\r
+       {\r
+               $this->_initialize();   \r
+               log_message('debug', "Hooks Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize the Hooks Preferences\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _initialize()\r
+       {\r
+               $CFG =& load_class('Config');\r
+               \r
+               // If hooks are not enabled in the config file\r
+               // there is nothing else to do\r
+               \r
+               if ($CFG->item('enable_hooks') == FALSE)\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               // Grab the "hooks" definition file.\r
+               // If there are no hooks, we're done.\r
+               \r
+               @include(APPPATH.'config/hooks'.EXT);\r
+               \r
+               if ( ! isset($hook) OR ! is_array($hook))\r
+               {\r
+                       return;\r
+               }\r
+\r
+               $this->hooks =& $hook;\r
+               $this->enabled = TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Call Hook\r
+        *\r
+        * Calls a particular hook\r
+        *\r
+        * @access      private\r
+        * @param       string  the hook name\r
+        * @return      mixed\r
+        */\r
+       function _call_hook($which = '')\r
+       {\r
+               if ( ! $this->enabled OR ! isset($this->hooks[$which]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))\r
+               {\r
+                       foreach ($this->hooks[$which] as $val)\r
+                       {\r
+                               $this->_run_hook($val);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->_run_hook($this->hooks[$which]);\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Run Hook\r
+        *\r
+        * Runs a particular hook\r
+        *\r
+        * @access      private\r
+        * @param       array   the hook details\r
+        * @return      bool\r
+        */\r
+       function _run_hook($data)\r
+       {\r
+               if ( ! is_array($data))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // -----------------------------------\r
+               // Safety - Prevents run-away loops\r
+               // -----------------------------------\r
+       \r
+               // If the script being called happens to have the same\r
+               // hook call within it a loop can happen\r
+               \r
+               if ($this->in_progress == TRUE)\r
+               {\r
+                       return;\r
+               }\r
+\r
+               // -----------------------------------\r
+               // Set file path\r
+               // -----------------------------------\r
+               \r
+               if ( ! isset($data['filepath']) OR ! isset($data['filename']))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];\r
+       \r
+               if ( ! file_exists($filepath))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // -----------------------------------\r
+               // Set class/function name\r
+               // -----------------------------------\r
+               \r
+               $class          = FALSE;\r
+               $function       = FALSE;\r
+               $params         = '';\r
+               \r
+               if (isset($data['class']) AND $data['class'] != '')\r
+               {\r
+                       $class = $data['class'];\r
+               }\r
+\r
+               if (isset($data['function']))\r
+               {\r
+                       $function = $data['function'];\r
+               }\r
+\r
+               if (isset($data['params']))\r
+               {\r
+                       $params = $data['params'];\r
+               }\r
+               \r
+               if ($class === FALSE AND $function === FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // -----------------------------------\r
+               // Set the in_progress flag\r
+               // -----------------------------------\r
+\r
+               $this->in_progress = TRUE;\r
+               \r
+               // -----------------------------------\r
+               // Call the requested class and/or function\r
+               // -----------------------------------\r
+               \r
+               if ($class !== FALSE)\r
+               {\r
+                       if ( ! class_exists($class))\r
+                       {\r
+                               require($filepath);\r
+                       }\r
+               \r
+                       $HOOK = new $class;\r
+                       $HOOK->$function($params);\r
+               }\r
+               else\r
+               {\r
+                       if ( ! function_exists($function))\r
+                       {\r
+                               require($filepath);\r
+                       }\r
+               \r
+                       $function($params);\r
+               }\r
+       \r
+               $this->in_progress = FALSE;\r
+               return TRUE;\r
+       }\r
+\r
+}\r
+\r
+// END CI_Hooks class\r
+\r
+/* End of file Hooks.php */\r
+/* Location: ./system/libraries/Hooks.php */
\ No newline at end of file
diff --git a/libraries/Image_lib.php b/libraries/Image_lib.php
new file mode 100644 (file)
index 0000000..67b7309
--- /dev/null
@@ -0,0 +1,1546 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Image Manipulation class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Image_lib\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/image_lib.html\r
+ */\r
+class CI_Image_lib {\r
+       \r
+       var $image_library              = 'gd2';        // Can be:  imagemagick, netpbm, gd, gd2\r
+       var $library_path               = '';\r
+       var $dynamic_output             = FALSE;        // Whether to send to browser or write to disk\r
+       var $source_image               = '';   \r
+       var $new_image                  = '';\r
+       var $width                              = '';\r
+       var $height                             = '';\r
+       var $quality                    = '90';\r
+       var $create_thumb               = FALSE;\r
+       var $thumb_marker               = '_thumb';\r
+       var $maintain_ratio             = TRUE;         // Whether to maintain aspect ratio when resizing or use hard values\r
+       var $master_dim                 = 'auto';       // auto, height, or width.  Determines what to use as the master dimension\r
+       var $rotation_angle             = '';\r
+       var $x_axis                             = '';\r
+       var     $y_axis                         = '';\r
+       \r
+       // Watermark Vars\r
+       var $wm_text                    = '';                   // Watermark text if graphic is not used\r
+       var $wm_type                    = 'text';               // Type of watermarking.  Options:  text/overlay\r
+       var $wm_x_transp                = 4;\r
+       var $wm_y_transp                = 4;\r
+       var $wm_overlay_path    = '';                   // Watermark image path\r
+       var $wm_font_path               = '';                   // TT font\r
+       var $wm_font_size               = 17;                   // Font size (different versions of GD will either use points or pixels)\r
+       var $wm_vrt_alignment   = 'B';                  // Vertical alignment:   T M B\r
+       var $wm_hor_alignment   = 'C';                  // Horizontal alignment: L R C\r
+       var $wm_padding                 = 0;                    // Padding around text\r
+       var $wm_hor_offset              = 0;                    // Lets you push text to the right\r
+       var $wm_vrt_offset              = 0;                     // Lets you push  text down\r
+       var $wm_font_color              = '#ffffff';    // Text color\r
+       var $wm_shadow_color    = '';                   // Dropshadow color\r
+       var $wm_shadow_distance = 2;                    // Dropshadow distance\r
+       var $wm_opacity                 = 50;                   // Image opacity: 1 - 100  Only works with image\r
+       \r
+       // Private Vars\r
+       var $source_folder              = '';\r
+       var $dest_folder                = '';\r
+       var $mime_type                  = '';\r
+       var $orig_width                 = '';\r
+       var $orig_height                = '';\r
+       var $image_type                 = '';\r
+       var $size_str                   = '';\r
+       var $full_src_path              = '';\r
+       var $full_dst_path              = '';\r
+       var $create_fnc                 = 'imagecreatetruecolor';\r
+       var $copy_fnc                   = 'imagecopyresampled';\r
+       var $error_msg                  = array();\r
+       var $wm_use_drop_shadow = FALSE;\r
+       var $wm_use_truetype    = FALSE;                \r
+       \r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function CI_Image_lib($props = array())\r
+       {\r
+               if (count($props) > 0)\r
+               {\r
+                       $this->initialize($props);\r
+               }\r
+               \r
+               log_message('debug', "Image Lib Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Initialize image properties\r
+        *\r
+        * Resets values in case this class is used in a loop\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function clear()\r
+       {\r
+               $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');\r
+       \r
+               foreach ($props as $val)\r
+               {\r
+                       $this->$val = '';\r
+               }\r
+\r
+               // special consideration for master_dim\r
+               $this->master_dim = 'auto';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * initialize image preferences\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */     \r
+       function initialize($props = array())\r
+       {\r
+               /*\r
+                * Convert array elements into class variables\r
+                */\r
+               if (count($props) > 0)\r
+               {\r
+                       foreach ($props as $key => $val)\r
+                       {\r
+                               $this->$key = $val;\r
+                       }\r
+               }\r
+\r
+               /*\r
+                * Is there a source image?\r
+                *\r
+                * If not, there's no reason to continue\r
+                *\r
+                */\r
+               if ($this->source_image == '')\r
+               {\r
+                       $this->set_error('imglib_source_image_required');\r
+                       return FALSE;           \r
+               }\r
+               \r
+               /*\r
+                * Is getimagesize() Available?\r
+                *\r
+                * We use it to determine the image properties (width/height).\r
+                * Note:  We need to figure out how to determine image\r
+                * properties using ImageMagick and NetPBM\r
+                *\r
+                */             \r
+               if ( ! function_exists('getimagesize'))\r
+               {\r
+                       $this->set_error('imglib_gd_required_for_props');\r
+                       return FALSE;           \r
+               }\r
+               \r
+               $this->image_library = strtolower($this->image_library);\r
+               \r
+               /*\r
+                * Set the full server path\r
+                *\r
+                * The source image may or may not contain a path.\r
+                * Either way, we'll try use realpath to generate the\r
+                * full server path in order to more reliably read it.\r
+                *\r
+                */     \r
+               if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)\r
+               {\r
+                       $full_source_path = str_replace("\\", "/", realpath($this->source_image));\r
+               }\r
+               else\r
+               {\r
+                       $full_source_path = $this->source_image;\r
+               }\r
+               \r
+               $x = explode('/', $full_source_path);\r
+               $this->source_image = end($x);\r
+               $this->source_folder = str_replace($this->source_image, '', $full_source_path);\r
+                                                               \r
+               // Set the Image Properties\r
+               if ( ! $this->get_image_properties($this->source_folder.$this->source_image))\r
+               {\r
+                       return FALSE;           \r
+               }                               \r
+\r
+               /*\r
+                * Assign the "new" image name/path\r
+                *\r
+                * If the user has set a "new_image" name it means\r
+                * we are making a copy of the source image. If not\r
+                * it means we are altering the original.  We'll\r
+                * set the destination filename and path accordingly.\r
+                *\r
+                */                     \r
+               if ($this->new_image == '')\r
+               {\r
+                       $this->dest_image = $this->source_image;\r
+                       $this->dest_folder = $this->source_folder;\r
+               }\r
+               else\r
+               {\r
+                       if (strpos($this->new_image, '/') === FALSE)\r
+                       {\r
+                               $this->dest_folder = $this->source_folder;\r
+                               $this->dest_image = $this->new_image;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)\r
+                               {\r
+                                       $full_dest_path = str_replace("\\", "/", realpath($this->new_image));\r
+                               }\r
+                               else\r
+                               {\r
+                                       $full_dest_path = $this->new_image;\r
+                               }\r
+                               \r
+                               // Is there a file name?\r
+                               if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))\r
+                               {\r
+                                       $this->dest_folder = $full_dest_path.'/';\r
+                                       $this->dest_image = $this->source_image;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $x = explode('/', $full_dest_path);\r
+                                       $this->dest_image = end($x);\r
+                                       $this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               /*\r
+                * Compile the finalized filenames/paths\r
+                *\r
+                * We'll create two master strings containing the\r
+                * full server path to the source image and the\r
+                * full server path to the destination image.\r
+                * We'll also split the destination image name\r
+                * so we can insert the thumbnail marker if needed.\r
+                *\r
+                */     \r
+               if ($this->create_thumb === FALSE OR $this->thumb_marker == '')\r
+               {\r
+                       $this->thumb_marker = '';\r
+               }\r
+\r
+               $xp     = $this->explode_name($this->dest_image);\r
+       \r
+               $filename = $xp['name'];\r
+               $file_ext = $xp['ext'];\r
+                               \r
+               $this->full_src_path = $this->source_folder.$this->source_image;                \r
+               $this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;\r
+\r
+               /*\r
+                * Should we maintain image proportions?\r
+                *\r
+                * When creating thumbs or copies, the target width/height\r
+                * might not be in correct proportion with the source\r
+                * image's width/height.  We'll recalculate it here.\r
+                *\r
+                */     \r
+               if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))\r
+               {\r
+                       $this->image_reproportion();\r
+               }\r
+\r
+               /*\r
+                * Was a width and height specified?\r
+                *\r
+                * If the destination width/height was\r
+                * not submitted we will use the values\r
+                * from the actual file\r
+                *\r
+                */     \r
+               if ($this->width == '')\r
+                       $this->width = $this->orig_width;\r
+       \r
+               if ($this->height == '')\r
+                       $this->height = $this->orig_height;\r
+       \r
+               // Set the quality\r
+               $this->quality = trim(str_replace("%", "", $this->quality));\r
+               \r
+               if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))\r
+                       $this->quality = 90;\r
+       \r
+               // Set the x/y coordinates\r
+               $this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;\r
+               $this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;\r
+       \r
+               // Watermark-related Stuff...\r
+               if ($this->wm_font_color != '')\r
+               {\r
+                       if (strlen($this->wm_font_color) == 6)\r
+                       {\r
+                               $this->wm_font_color = '#'.$this->wm_font_color;\r
+                       }\r
+               }\r
+               \r
+               if ($this->wm_shadow_color != '')\r
+               {\r
+                       if (strlen($this->wm_shadow_color) == 6)\r
+                       {\r
+                               $this->wm_shadow_color = '#'.$this->wm_shadow_color;\r
+                       }\r
+               }\r
+       \r
+               if ($this->wm_overlay_path != '')\r
+               {\r
+                       $this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));\r
+               }\r
+       \r
+               if ($this->wm_shadow_color != '')\r
+               {\r
+                       $this->wm_use_drop_shadow = TRUE;\r
+               }\r
+\r
+               if ($this->wm_font_path != '')\r
+               {\r
+                       $this->wm_use_truetype = TRUE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Resize\r
+        *\r
+        * This is a wrapper function that chooses the proper\r
+        * resize function based on the protocol specified\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function resize()\r
+       {\r
+               $protocol = 'image_process_'.$this->image_library;\r
+               \r
+               if (eregi("gd2$", $protocol))\r
+               {\r
+                       $protocol = 'image_process_gd';\r
+               }\r
+               \r
+               return $this->$protocol('resize');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Crop\r
+        *\r
+        * This is a wrapper function that chooses the proper\r
+        * cropping function based on the protocol specified\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function crop()\r
+       {\r
+               $protocol = 'image_process_'.$this->image_library;\r
+               \r
+               if (eregi("gd2$", $protocol))\r
+               {\r
+                       $protocol = 'image_process_gd';\r
+               }\r
+               \r
+               return $this->$protocol('crop');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Rotate\r
+        *\r
+        * This is a wrapper function that chooses the proper\r
+        * rotation function based on the protocol specified\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function rotate()\r
+       {\r
+               // Allowed rotation values              \r
+               $degs = array(90, 180, 270, 'vrt', 'hor');      \r
+       \r
+               if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE))\r
+               {\r
+                       $this->set_error('imglib_rotation_angle_required');\r
+                       return FALSE;           \r
+               }\r
+       \r
+               // Reassign the width and height\r
+               if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)\r
+               {\r
+                       $this->width    = $this->orig_height;\r
+                       $this->height   = $this->orig_width;\r
+               }\r
+               else\r
+               {\r
+                       $this->width    = $this->orig_width;\r
+                       $this->height   = $this->orig_height;\r
+               }\r
+       \r
+\r
+               // Choose resizing function\r
+               if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')\r
+               {\r
+                       $protocol = 'image_process_'.$this->image_library;\r
+               \r
+                       return $this->$protocol('rotate');\r
+               }\r
+               \r
+               if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')\r
+               {\r
+                       return $this->image_mirror_gd();\r
+               }\r
+               else\r
+               {               \r
+                       return $this->image_rotate_gd();\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Process Using GD/GD2\r
+        *\r
+        * This function will resize or crop\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */             \r
+       function image_process_gd($action = 'resize')\r
+       {       \r
+               $v2_override = FALSE;\r
+\r
+               // If the target width/height match the source, AND if the new file name is not equal to the old file name\r
+               // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.\r
+               if ($this->dynamic_output === FALSE)\r
+               {\r
+                       if ($this->orig_width == $this->width AND $this->orig_height == $this->height)                  \r
+                       {\r
+                               if ($this->source_image != $this->new_image)\r
+                               {\r
+                                       if (@copy($this->full_src_path, $this->full_dst_path))\r
+                                       {\r
+                                               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+                                       }\r
+                               }\r
+                               \r
+                               return TRUE;\r
+                       }\r
+               }\r
+               \r
+               // Let's set up our values based on the action\r
+               if ($action == 'crop')\r
+               {\r
+                       //  Reassign the source width/height if cropping\r
+                       $this->orig_width  = $this->width;\r
+                       $this->orig_height = $this->height;     \r
+                               \r
+                       // GD 2.0 has a cropping bug so we'll test for it\r
+                       if ($this->gd_version() !== FALSE)\r
+                       {\r
+                               $gd_version = str_replace('0', '', $this->gd_version());                        \r
+                               $v2_override = ($gd_version == 2) ? TRUE : FALSE;\r
+                       }\r
+               }\r
+               else\r
+               {                       \r
+                       // If resizing the x/y axis must be zero\r
+                       $this->x_axis = 0;\r
+                       $this->y_axis = 0;\r
+               }\r
+               \r
+               //  Create the image handle\r
+               if ( ! ($src_img = $this->image_create_gd()))\r
+               {               \r
+                       return FALSE;\r
+               }\r
+\r
+               //  Create The Image\r
+               //\r
+               //  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"\r
+               //  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment\r
+               //  below should that ever prove inaccurate.\r
+               //\r
+               //  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)\r
+               if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))          \r
+               {\r
+                       $create = 'imagecreatetruecolor';\r
+                       $copy   = 'imagecopyresampled';\r
+               }\r
+               else\r
+               {\r
+                       $create = 'imagecreate';        \r
+                       $copy   = 'imagecopyresized';\r
+               }\r
+                       \r
+               $dst_img = $create($this->width, $this->height);\r
+               $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);\r
+\r
+               //  Show the image      \r
+               if ($this->dynamic_output == TRUE)\r
+               {\r
+                       $this->image_display_gd($dst_img);\r
+               }\r
+               else\r
+               {\r
+                       // Or save it\r
+                       if ( ! $this->image_save_gd($dst_img))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               //  Kill the file handles\r
+               imagedestroy($dst_img);\r
+               imagedestroy($src_img);\r
+               \r
+               // Set the file to 777\r
+               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Process Using ImageMagick\r
+        *\r
+        * This function will resize, crop or rotate\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */             \r
+       function image_process_imagemagick($action = 'resize')\r
+       {\r
+               //  Do we have a vaild library path?\r
+               if ($this->library_path == '')\r
+               {\r
+                       $this->set_error('imglib_libpath_invalid');\r
+                       return FALSE;\r
+               }\r
+                               \r
+               if ( ! eregi("convert$", $this->library_path))\r
+               {\r
+                       if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/";\r
+               \r
+                       $this->library_path .= 'convert';\r
+               }\r
+               \r
+               // Execute the command\r
+               $cmd = $this->library_path." -quality ".$this->quality;\r
+       \r
+               if ($action == 'crop')\r
+               {\r
+                       $cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";\r
+               }\r
+               elseif ($action == 'rotate')\r
+               {\r
+                       switch ($this->rotation_angle)\r
+                       {\r
+                               case 'hor'      : $angle = '-flop';\r
+                                       break;\r
+                               case 'vrt'      : $angle = '-flip';\r
+                                       break;\r
+                               default         : $angle = '-rotate '.$this->rotation_angle;\r
+                                       break;\r
+                       }                       \r
+               \r
+                       $cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";\r
+               }\r
+               else  // Resize\r
+               {\r
+                       $cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";\r
+               }\r
+       \r
+               $retval = 1;\r
+       \r
+               @exec($cmd, $output, $retval);\r
+\r
+               //      Did it work?    \r
+               if ($retval > 0)\r
+               {\r
+                       $this->set_error('imglib_image_process_failed');\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Set the file to 777\r
+               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Process Using NetPBM\r
+        *\r
+        * This function will resize, crop or rotate\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */             \r
+       function image_process_netpbm($action = 'resize')\r
+       {\r
+               if ($this->library_path == '')\r
+               {\r
+                       $this->set_error('imglib_libpath_invalid');\r
+                       return FALSE;\r
+               }\r
+                       \r
+               //  Build the resizing command\r
+               switch ($this->image_type)\r
+               {\r
+                       case 1 :\r
+                                               $cmd_in         = 'giftopnm';\r
+                                               $cmd_out        = 'ppmtogif';\r
+                               break;\r
+                       case 2 :\r
+                                               $cmd_in         = 'jpegtopnm';\r
+                                               $cmd_out        = 'ppmtojpeg';                  \r
+                               break;\r
+                       case 3 :\r
+                                               $cmd_in         = 'pngtopnm';\r
+                                               $cmd_out        = 'ppmtopng';\r
+                               break;\r
+               }\r
+               \r
+               if ($action == 'crop')\r
+               {\r
+                       $cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;\r
+               }\r
+               elseif ($action == 'rotate')\r
+               {\r
+                       switch ($this->rotation_angle)\r
+                       {\r
+                               case 90         :       $angle = 'r270';\r
+                                       break;\r
+                               case 180        :       $angle = 'r180';\r
+                                       break;\r
+                               case 270        :       $angle = 'r90';\r
+                                       break;\r
+                               case 'vrt'      :       $angle = 'tb';\r
+                                       break;\r
+                               case 'hor'      :       $angle = 'lr';\r
+                                       break;\r
+                       }\r
+               \r
+                       $cmd_inner = 'pnmflip -'.$angle.' ';\r
+               }\r
+               else // Resize\r
+               {\r
+                       $cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;\r
+               }\r
+                                               \r
+               $cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';\r
+               \r
+               $retval = 1;\r
+               \r
+               @exec($cmd, $output, $retval);\r
+               \r
+               //  Did it work?\r
+               if ($retval > 0)\r
+               {\r
+                       $this->set_error('imglib_image_process_failed');\r
+                       return FALSE;\r
+               }\r
+               \r
+               // With NetPBM we have to create a temporary image.\r
+               // If you try manipulating the original it fails so\r
+               // we have to rename the temp file.\r
+               copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);\r
+               unlink ($this->dest_folder.'netpbm.tmp');\r
+               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Rotate Using GD\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function image_rotate_gd()\r
+       {       \r
+               // Is Image Rotation Supported?\r
+               // this function is only supported as of PHP 4.3\r
+               if ( ! function_exists('imagerotate'))\r
+               {\r
+                       $this->set_error('imglib_rotate_unsupported');\r
+                       return FALSE;\r
+               }\r
+               \r
+               //  Create the image handle\r
+               if ( ! ($src_img = $this->image_create_gd()))\r
+               {               \r
+                       return FALSE;\r
+               }\r
+\r
+               // Set the background color             \r
+               // This won't work with transparent PNG files so we are\r
+               // going to have to figure out how to determine the color\r
+               // of the alpha channel in a future release.\r
+       \r
+               $white  = imagecolorallocate($src_img, 255, 255, 255);\r
+\r
+               //  Rotate it!\r
+               $dst_img = imagerotate($src_img, $this->rotation_angle, $white);\r
+       \r
+               //  Save the Image\r
+               if ($this->dynamic_output == TRUE)\r
+               {\r
+                       $this->image_display_gd($dst_img);\r
+               }\r
+               else\r
+               {\r
+                       // Or save it\r
+                       if ( ! $this->image_save_gd($dst_img))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               //  Kill the file handles\r
+               imagedestroy($dst_img);\r
+               imagedestroy($src_img);\r
+               \r
+               // Set the file to 777\r
+               \r
+               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+               \r
+               return true;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Create Mirror Image using GD\r
+        *\r
+        * This function will flip horizontal or vertical\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function image_mirror_gd()\r
+       {               \r
+               if ( ! $src_img = $this->image_create_gd())\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $width  = $this->orig_width;\r
+               $height = $this->orig_height;\r
+       \r
+               if ($this->rotation_angle == 'hor')\r
+               {\r
+                       for ($i = 0; $i < $height; $i++)\r
+                       {\r
+                               $left  = 0;\r
+                               $right = $width-1;\r
+       \r
+                               while ($left < $right)\r
+                               {\r
+                                       $cl = imagecolorat($src_img, $left, $i);\r
+                                       $cr = imagecolorat($src_img, $right, $i);\r
+                                       \r
+                                       imagesetpixel($src_img, $left, $i, $cr);\r
+                                       imagesetpixel($src_img, $right, $i, $cl);\r
+                                       \r
+                                       $left++;\r
+                                       $right--;\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       for ($i = 0; $i < $width; $i++)\r
+                       {\r
+                               $top = 0;\r
+                               $bot = $height-1;\r
+       \r
+                               while ($top < $bot)\r
+                               {\r
+                                       $ct = imagecolorat($src_img, $i, $top);\r
+                                       $cb = imagecolorat($src_img, $i, $bot);\r
+                                       \r
+                                       imagesetpixel($src_img, $i, $top, $cb);\r
+                                       imagesetpixel($src_img, $i, $bot, $ct);\r
+                                       \r
+                                       $top++;\r
+                                       $bot--;\r
+                               }\r
+                       }               \r
+               }               \r
+\r
+               //  Show the image\r
+               if ($this->dynamic_output == TRUE)\r
+               {\r
+                       $this->image_display_gd($src_img);\r
+               }\r
+               else\r
+               {\r
+                       // Or save it\r
+                       if ( ! $this->image_save_gd($src_img))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               //  Kill the file handles\r
+               imagedestroy($src_img);\r
+               \r
+               // Set the file to 777\r
+               @chmod($this->full_dst_path, DIR_WRITE_MODE);\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Image Watermark\r
+        *\r
+        * This is a wrapper function that chooses the type\r
+        * of watermarking based on the specified preference.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function watermark()\r
+       {\r
+               if ($this->wm_type == 'overlay')\r
+               {\r
+                       return $this->overlay_watermark();\r
+               }\r
+               else\r
+               {\r
+                       return $this->text_watermark();\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Watermark - Graphic Version\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function overlay_watermark()\r
+       {\r
+               if ( ! function_exists('imagecolortransparent'))\r
+               {\r
+                       $this->set_error('imglib_gd_required');\r
+                       return FALSE;           \r
+               }\r
+       \r
+               //  Fetch source image properties\r
+               $this->get_image_properties();\r
+\r
+               //  Fetch watermark image properties\r
+               $props                  = $this->get_image_properties($this->wm_overlay_path, TRUE);    \r
+               $wm_img_type    = $props['image_type'];\r
+               $wm_width               = $props['width'];\r
+               $wm_height              = $props['height'];\r
+       \r
+               //  Create two image resources  \r
+               $wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);\r
+               $src_img = $this->image_create_gd($this->full_src_path);\r
+               \r
+               // Reverse the offset if necessary              \r
+               // When the image is positioned at the bottom\r
+               // we don't want the vertical offset to push it\r
+               // further down.  We want the reverse, so we'll\r
+               // invert the offset.  Same with the horizontal\r
+               // offset when the image is at the right\r
+               \r
+               $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));\r
+               $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));\r
+       \r
+               if ($this->wm_vrt_alignment == 'B')\r
+                       $this->wm_vrt_offset = $this->wm_vrt_offset * -1;\r
+       \r
+               if ($this->wm_hor_alignment == 'R')\r
+                       $this->wm_hor_offset = $this->wm_hor_offset * -1;\r
+\r
+               //  Set the base x and y axis values\r
+               $x_axis = $this->wm_hor_offset + $this->wm_padding;\r
+               $y_axis = $this->wm_vrt_offset + $this->wm_padding;\r
+\r
+               //  Set the vertical position\r
+               switch ($this->wm_vrt_alignment)\r
+               {\r
+                       case 'T':\r
+                               break;\r
+                       case 'M':       $y_axis += ($this->orig_height / 2) - ($wm_height / 2);\r
+                               break;\r
+                       case 'B':       $y_axis += $this->orig_height - $wm_height;\r
+                               break;\r
+               }\r
+\r
+               //  Set the horizontal position\r
+               switch ($this->wm_hor_alignment)\r
+               {\r
+                       case 'L':\r
+                               break;  \r
+                       case 'C':       $x_axis += ($this->orig_width / 2) - ($wm_width / 2);\r
+                               break;\r
+                       case 'R':       $x_axis += $this->orig_width - $wm_width;\r
+                               break;\r
+               }\r
+       \r
+               //  Build the finalized image                   \r
+               if ($wm_img_type == 3 AND function_exists('imagealphablending'))\r
+               {\r
+                       @imagealphablending($src_img, TRUE);\r
+               }               \r
+\r
+               // Set RGB values for text and shadow\r
+               $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);\r
+               $alpha = ($rgba & 0x7F000000) >> 24;\r
+               \r
+               // make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency\r
+               if ($alpha > 0)\r
+               {\r
+                       // copy the image directly, the image's alpha transparency being the sole determinant of blending\r
+                       imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);\r
+               }\r
+               else\r
+               {\r
+                       // set our RGB value from above to be transparent and merge the images with the specified opacity\r
+                       imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));\r
+                       imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);                    \r
+               }\r
+                               \r
+               //  Output the image\r
+               if ($this->dynamic_output == TRUE)\r
+               {\r
+                       $this->image_display_gd($src_img);\r
+               }\r
+               else\r
+               {\r
+                       if ( ! $this->image_save_gd($src_img))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               imagedestroy($src_img);\r
+               imagedestroy($wm_img);\r
+                               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Watermark - Text Version\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function text_watermark()\r
+       {\r
+               if ( ! ($src_img = $this->image_create_gd()))\r
+               {               \r
+                       return FALSE;\r
+               }\r
+                               \r
+               if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path))\r
+               {\r
+                       $this->set_error('imglib_missing_font');\r
+                       return FALSE;\r
+               }\r
+               \r
+               //  Fetch source image properties               \r
+               $this->get_image_properties();                          \r
+               \r
+               // Set RGB values for text and shadow           \r
+               $this->wm_font_color    = str_replace('#', '', $this->wm_font_color);\r
+               $this->wm_shadow_color  = str_replace('#', '', $this->wm_shadow_color);\r
+               \r
+               $R1 = hexdec(substr($this->wm_font_color, 0, 2));\r
+               $G1 = hexdec(substr($this->wm_font_color, 2, 2));\r
+               $B1 = hexdec(substr($this->wm_font_color, 4, 2));\r
+       \r
+               $R2 = hexdec(substr($this->wm_shadow_color, 0, 2));\r
+               $G2 = hexdec(substr($this->wm_shadow_color, 2, 2));\r
+               $B2 = hexdec(substr($this->wm_shadow_color, 4, 2));\r
+               \r
+               $txt_color      = imagecolorclosest($src_img, $R1, $G1, $B1);\r
+               $drp_color      = imagecolorclosest($src_img, $R2, $G2, $B2);\r
+\r
+               // Reverse the vertical offset\r
+               // When the image is positioned at the bottom\r
+               // we don't want the vertical offset to push it\r
+               // further down.  We want the reverse, so we'll\r
+               // invert the offset.  Note: The horizontal\r
+               // offset flips itself automatically\r
+       \r
+               if ($this->wm_vrt_alignment == 'B')\r
+                       $this->wm_vrt_offset = $this->wm_vrt_offset * -1;\r
+                       \r
+               if ($this->wm_hor_alignment == 'R')\r
+                       $this->wm_hor_offset = $this->wm_hor_offset * -1;\r
+\r
+               // Set font width and height\r
+               // These are calculated differently depending on\r
+               // whether we are using the true type font or not\r
+               if ($this->wm_use_truetype == TRUE)\r
+               {\r
+                       if ($this->wm_font_size == '')\r
+                               $this->wm_font_size = '17';\r
+               \r
+                       $fontwidth  = $this->wm_font_size-($this->wm_font_size/4);\r
+                       $fontheight = $this->wm_font_size;\r
+                       $this->wm_vrt_offset += $this->wm_font_size;\r
+               }\r
+               else\r
+               {\r
+                       $fontwidth  = imagefontwidth($this->wm_font_size);\r
+                       $fontheight = imagefontheight($this->wm_font_size);\r
+               }\r
+\r
+               // Set base X and Y axis values\r
+               $x_axis = $this->wm_hor_offset + $this->wm_padding;\r
+               $y_axis = $this->wm_vrt_offset + $this->wm_padding;\r
+\r
+               // Set verticle alignment\r
+               if ($this->wm_use_drop_shadow == FALSE)\r
+                       $this->wm_shadow_distance = 0;\r
+                       \r
+               $this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));\r
+               $this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));\r
+       \r
+               switch ($this->wm_vrt_alignment)\r
+               {\r
+                       case     "T" :\r
+                               break;\r
+                       case "M":       $y_axis += ($this->orig_height/2)+($fontheight/2);\r
+                               break;\r
+                       case "B":       $y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));\r
+                               break;\r
+               }\r
+       \r
+               $x_shad = $x_axis + $this->wm_shadow_distance;\r
+               $y_shad = $y_axis + $this->wm_shadow_distance;\r
+               \r
+               // Set horizontal alignment\r
+               switch ($this->wm_hor_alignment)\r
+               {\r
+                       case "L":\r
+                               break;\r
+                       case "R":\r
+                                               if ($this->wm_use_drop_shadow)\r
+                                                       $x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));\r
+                                                       $x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));\r
+                               break;\r
+                       case "C":\r
+                                               if ($this->wm_use_drop_shadow)\r
+                                                       $x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);\r
+                                                       $x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);\r
+                               break;\r
+               }\r
+               \r
+               //  Add the text to the source image\r
+               if ($this->wm_use_truetype)\r
+               {       \r
+                       if ($this->wm_use_drop_shadow)\r
+                               imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);\r
+                               imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);\r
+               }\r
+               else\r
+               {\r
+                       if ($this->wm_use_drop_shadow)\r
+                               imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);\r
+                               imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);\r
+               }\r
+       \r
+               //  Output the final image\r
+               if ($this->dynamic_output == TRUE)\r
+               {\r
+                       $this->image_display_gd($src_img);\r
+               }\r
+               else\r
+               {\r
+                       $this->image_save_gd($src_img);\r
+               }\r
+               \r
+               imagedestroy($src_img);\r
+       \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Create Image - GD\r
+        *\r
+        * This simply creates an image resource handle\r
+        * based on the type of image being processed\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      resource\r
+        */                     \r
+       function image_create_gd($path = '', $image_type = '')\r
+       {\r
+               if ($path == '')\r
+                       $path = $this->full_src_path;\r
+                       \r
+               if ($image_type == '')\r
+                       $image_type = $this->image_type;\r
+       \r
+               \r
+               switch ($image_type)\r
+               {\r
+                       case     1 :\r
+                                               if ( ! function_exists('imagecreatefromgif'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));\r
+                                                       return FALSE;\r
+                                               }\r
+                                       \r
+                                               return imagecreatefromgif($path);\r
+                               break;\r
+                       case 2 :\r
+                                               if ( ! function_exists('imagecreatefromjpeg'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));\r
+                                                       return FALSE;\r
+                                               }\r
+                                       \r
+                                               return imagecreatefromjpeg($path);\r
+                               break;\r
+                       case 3 :\r
+                                               if ( ! function_exists('imagecreatefrompng'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));                          \r
+                                                       return FALSE;\r
+                                               }\r
+                                       \r
+                                               return imagecreatefrompng($path);\r
+                               break;                  \r
+               \r
+               }\r
+               \r
+               $this->set_error(array('imglib_unsupported_imagecreate'));\r
+               return FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Write image file to disk - GD\r
+        *\r
+        * Takes an image resource as input and writes the file\r
+        * to the specified destination\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      bool\r
+        */                     \r
+       function image_save_gd($resource)\r
+       {       \r
+               switch ($this->image_type)\r
+               {\r
+                       case 1 :\r
+                                               if ( ! function_exists('imagegif'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));\r
+                                                       return FALSE;           \r
+                                               }\r
+                                               \r
+                                               @imagegif($resource, $this->full_dst_path);\r
+                               break;\r
+                       case 2  :\r
+                                               if ( ! function_exists('imagejpeg'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));\r
+                                                       return FALSE;           \r
+                                               }\r
+                                               \r
+                                               if (phpversion() == '4.4.1')\r
+                                               {\r
+                                                       @touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround\r
+                                               }\r
+                                               \r
+                                               @imagejpeg($resource, $this->full_dst_path, $this->quality);\r
+                               break;\r
+                       case 3  :\r
+                                               if ( ! function_exists('imagepng'))\r
+                                               {\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));\r
+                                                       return FALSE;           \r
+                                               }\r
+                                       \r
+                                               @imagepng($resource, $this->full_dst_path);\r
+                               break;\r
+                       default         :\r
+                                                       $this->set_error(array('imglib_unsupported_imagecreate'));\r
+                                                       return FALSE;           \r
+                               break;          \r
+               }\r
+       \r
+               return TRUE;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Dynamically outputs an image\r
+        *\r
+        * @access      public\r
+        * @param       resource\r
+        * @return      void\r
+        */                     \r
+       function image_display_gd($resource)\r
+       {               \r
+               header("Content-Disposition: filename={$this->source_image};");\r
+               header("Content-Type: {$this->mime_type}");\r
+               header('Content-Transfer-Encoding: binary');\r
+               header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');\r
+       \r
+               switch ($this->image_type)\r
+               {\r
+                       case 1          :       imagegif($resource);\r
+                               break;\r
+                       case 2          :       imagejpeg($resource, '', $this->quality);\r
+                               break;\r
+                       case 3          :       imagepng($resource);\r
+                               break;\r
+                       default         :       echo 'Unable to display the image';\r
+                               break;          \r
+               }                       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Re-proportion Image Width/Height\r
+        *\r
+        * When creating thumbs, the desired width/height\r
+        * can end up warping the image due to an incorrect\r
+        * ratio between the full-sized image and the thumb.\r
+        *\r
+        * This function lets us re-proportion the width/height\r
+        * if users choose to maintain the aspect ratio when resizing.\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */                     \r
+       function image_reproportion()\r
+       {\r
+               if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)\r
+                       return;\r
+               \r
+               if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)\r
+                       return;\r
+               \r
+               $new_width      = ceil($this->orig_width*$this->height/$this->orig_height);             \r
+               $new_height     = ceil($this->width*$this->orig_height/$this->orig_width);\r
+               \r
+               $ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));\r
+       \r
+               if ($this->master_dim != 'width' AND $this->master_dim != 'height')\r
+               {\r
+                       $this->master_dim = ($ratio < 0) ? 'width' : 'height';\r
+               }\r
+               \r
+               if (($this->width != $new_width) AND ($this->height != $new_height))\r
+               {\r
+                       if ($this->master_dim == 'height')\r
+                       {\r
+                               $this->width = $new_width;\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->height = $new_height;\r
+                       }\r
+               }\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get image properties\r
+        *\r
+        * A helper function that gets info about the file\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      mixed\r
+        */                     \r
+       function get_image_properties($path = '', $return = FALSE)\r
+       {\r
+               // For now we require GD but we should\r
+               // find a way to determine this using IM or NetPBM\r
+               \r
+               if ($path == '')\r
+                       $path = $this->full_src_path;\r
+                               \r
+               if ( ! file_exists($path))\r
+               {\r
+                       $this->set_error('imglib_invalid_path');                \r
+                       return FALSE;                           \r
+               }\r
+               \r
+               $vals = @getimagesize($path);\r
+               \r
+               $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');\r
+               \r
+               $mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';\r
+                               \r
+               if ($return == TRUE)\r
+               {\r
+                       $v['width']                     = $vals['0'];\r
+                       $v['height']            = $vals['1'];\r
+                       $v['image_type']        = $vals['2'];\r
+                       $v['size_str']          = $vals['3'];\r
+                       $v['mime_type']         = $mime;\r
+                       \r
+                       return $v;\r
+               }\r
+               \r
+               $this->orig_width       = $vals['0'];\r
+               $this->orig_height      = $vals['1'];\r
+               $this->image_type       = $vals['2'];\r
+               $this->size_str         = $vals['3'];\r
+               $this->mime_type        = $mime;\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Size calculator\r
+        *\r
+        * This function takes a known width x height and\r
+        * recalculates it to a new size.  Only one\r
+        * new variable needs to be known\r
+        *\r
+        *      $props = array(\r
+        *                                      'width'                 => $width,\r
+        *                                      'height'                => $height,\r
+        *                                      'new_width'             => 40,\r
+        *                                      'new_height'    => ''\r
+        *                                );\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      array\r
+        */                     \r
+       function size_calculator($vals)\r
+       {\r
+               if ( ! is_array($vals))\r
+                       return;\r
+                       \r
+               $allowed = array('new_width', 'new_height', 'width', 'height');\r
+       \r
+               foreach ($allowed as $item)\r
+               {\r
+                       if ( ! isset($vals[$item]) OR $vals[$item] == '')\r
+                               $vals[$item] = 0;\r
+               }\r
+               \r
+               if ($vals['width'] == 0 OR $vals['height'] == 0)\r
+               {\r
+                       return $vals;\r
+               }\r
+                       \r
+               if ($vals['new_width'] == 0)\r
+               {\r
+                       $vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);\r
+               }\r
+               elseif ($vals['new_height'] == 0)\r
+               {\r
+                       $vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);\r
+               }\r
+       \r
+               return $vals;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Explode source_image\r
+        *\r
+        * This is a helper function that extracts the extension\r
+        * from the source_image.  This function lets us deal with\r
+        * source_images with multiple periods, like:  my.cool.jpg\r
+        * It returns an associative array with two elements:\r
+        * $array['ext']  = '.jpg';\r
+        * $array['name'] = 'my.cool';\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      array\r
+        */     \r
+       function explode_name($source_image)\r
+       {\r
+               $x = explode('.', $source_image);\r
+               $ret['ext'] = '.'.end($x);\r
+               \r
+               $name = '';\r
+               \r
+               $ct = count($x)-1;\r
+               \r
+               for ($i = 0; $i < $ct; $i++)\r
+               {\r
+                       $name .= $x[$i];\r
+                       \r
+                       if ($i < ($ct - 1))\r
+                       {\r
+                               $name .= '.';\r
+                       }\r
+               }\r
+               \r
+               $ret['name'] = $name;\r
+               \r
+               return $ret;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Is GD Installed?\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function gd_loaded()\r
+       {\r
+               if ( ! extension_loaded('gd'))\r
+               {\r
+                       if ( ! dl('gd.so'))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get GD version\r
+        *\r
+        * @access      public\r
+        * @return      mixed\r
+        */     \r
+       function gd_version()\r
+       {\r
+               if (function_exists('gd_info'))\r
+               {\r
+                       $gd_version = @gd_info();\r
+                       $gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);\r
+                       \r
+                       return $gd_version;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_error($msg)\r
+       {\r
+               $CI =& get_instance();\r
+               $CI->lang->load('imglib');\r
+               \r
+               if (is_array($msg))\r
+               {\r
+                       foreach ($msg as $val)\r
+                       {\r
+                               \r
+                               $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);\r
+                               $this->error_msg[] = $msg;\r
+                               log_message('error', $msg);\r
+                       }               \r
+               }\r
+               else\r
+               {\r
+                       $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);\r
+                       $this->error_msg[] = $msg;\r
+                       log_message('error', $msg);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Show error messages\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function display_errors($open = '<p>', $close = '</p>')\r
+       {       \r
+               $str = '';\r
+               foreach ($this->error_msg as $val)\r
+               {\r
+                       $str .= $open.$val.$close;\r
+               }\r
+       \r
+               return $str;\r
+       }\r
+\r
+}\r
+// END Image_lib Class\r
+\r
+/* End of file Image_lib.php */\r
+/* Location: ./system/libraries/Image_lib.php */
\ No newline at end of file
diff --git a/libraries/Input.php b/libraries/Input.php
new file mode 100644 (file)
index 0000000..e66d481
--- /dev/null
@@ -0,0 +1,1059 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Input Class\r
+ *\r
+ * Pre-processes global input data for security\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Input\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/input.html\r
+ */\r
+class CI_Input {\r
+       var $use_xss_clean              = FALSE;\r
+       var $xss_hash                   = '';\r
+       var $ip_address                 = FALSE;\r
+       var $user_agent                 = FALSE;\r
+       var $allow_get_array    = FALSE;\r
+       \r
+       /* never allowed, string replacement */\r
+       var $never_allowed_str = array(\r
+                                                                       'document.cookie'       => '[removed]',\r
+                                                                       'document.write'        => '[removed]',\r
+                                                                       '.parentNode'           => '[removed]',\r
+                                                                       '.innerHTML'            => '[removed]',\r
+                                                                       'window.location'       => '[removed]',\r
+                                                                       '-moz-binding'          => '[removed]',\r
+                                                                       '<!--'                          => '&lt;!--',\r
+                                                                       '-->'                           => '--&gt;',\r
+                                                                       '<![CDATA['                     => '&lt;![CDATA['\r
+                                                                       );\r
+       /* never allowed, regex replacement */\r
+       var $never_allowed_regex = array(\r
+                                                                               "javascript\s*:"        => '[removed]',\r
+                                                                               "expression\s*\("       => '[removed]', // CSS and IE\r
+                                                                               "Redirect\s+302"        => '[removed]'\r
+                                                                       );\r
+                               \r
+       /**\r
+        * Constructor\r
+        *\r
+        * Sets whether to globally enable the XSS processing\r
+        * and whether to allow the $_GET array\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Input()\r
+       {\r
+               log_message('debug', "Input Class Initialized");\r
+\r
+               $CFG =& load_class('Config');\r
+               $this->use_xss_clean    = ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE;\r
+               $this->allow_get_array  = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE;\r
+               $this->_sanitize_globals();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Sanitize Globals\r
+        *\r
+        * This function does the following:\r
+        *\r
+        * Unsets $_GET data (if query strings are not enabled)\r
+        *\r
+        * Unsets all globals if register_globals is enabled\r
+        *\r
+        * Standardizes newline characters to \n\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _sanitize_globals()\r
+       {\r
+               // Would kind of be "wrong" to unset any of these GLOBALS\r
+               $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',\r
+                                                       'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN');\r
+\r
+               // Unset globals for security. \r
+               // This is effectively the same as register_globals = off\r
+               foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global)\r
+               {\r
+                       if ( ! is_array($global))\r
+                       {\r
+                               if ( ! in_array($global, $protected))\r
+                               {\r
+                                       unset($GLOBALS[$global]);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               foreach ($global as $key => $val)\r
+                               {\r
+                                       if ( ! in_array($key, $protected))\r
+                                       {\r
+                                               unset($GLOBALS[$key]);\r
+                                       }\r
+                       \r
+                                       if (is_array($val))\r
+                                       {\r
+                                               foreach($val as $k => $v)\r
+                                               {\r
+                                                       if ( ! in_array($k, $protected))\r
+                                                       {\r
+                                                               unset($GLOBALS[$k]);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Is $_GET data allowed? If not we'll set the $_GET to an empty array\r
+               if ($this->allow_get_array == FALSE)\r
+               {\r
+                       $_GET = array();\r
+               }\r
+               else\r
+               {\r
+                       $_GET = $this->_clean_input_data($_GET);\r
+               }\r
+\r
+               // Clean $_POST Data\r
+               $_POST = $this->_clean_input_data($_POST);\r
+               \r
+               // Clean $_COOKIE Data\r
+               // Also get rid of specially treated cookies that might be set by a server\r
+               // or silly application, that are of no use to a CI application anyway\r
+               // but that when present will trip our 'Disallowed Key Characters' alarm\r
+               // http://www.ietf.org/rfc/rfc2109.txt\r
+               // note that the key names below are single quoted strings, and are not PHP variables\r
+               unset($_COOKIE['$Version']);\r
+               unset($_COOKIE['$Path']);\r
+               unset($_COOKIE['$Domain']);\r
+               $_COOKIE = $this->_clean_input_data($_COOKIE);\r
+\r
+               log_message('debug', "Global POST and COOKIE data sanitized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Clean Input Data\r
+        *\r
+        * This is a helper function. It escapes data and\r
+        * standardizes newline characters to \n\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _clean_input_data($str)\r
+       {\r
+               if (is_array($str))\r
+               {\r
+                       $new_array = array();\r
+                       foreach ($str as $key => $val)\r
+                       {\r
+                               $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);\r
+                       }\r
+                       return $new_array;\r
+               }\r
+\r
+               // We strip slashes if magic quotes is on to keep things consistent\r
+               if (get_magic_quotes_gpc())\r
+               {\r
+                       $str = stripslashes($str);\r
+               }\r
+\r
+               // Should we filter the input data?\r
+               if ($this->use_xss_clean === TRUE)\r
+               {\r
+                       $str = $this->xss_clean($str);\r
+               }\r
+\r
+               // Standardize newlines\r
+               if (strpos($str, "\r") !== FALSE)\r
+               {\r
+                       $str = str_replace(array("\r\n", "\r"), "\n", $str);\r
+               }\r
+               \r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Clean Keys\r
+        *\r
+        * This is a helper function. To prevent malicious users\r
+        * from trying to exploit keys we make sure that keys are\r
+        * only named with alpha-numeric text and a few other items.\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _clean_input_keys($str)\r
+       {\r
+                if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))\r
+                {\r
+                       exit('Disallowed Key Characters.');\r
+                }\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch from array\r
+        *\r
+        * This is a helper function to retrieve values from global arrays\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)\r
+       {\r
+               if ( ! isset($array[$index]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if ($xss_clean === TRUE)\r
+               {\r
+                       return $this->xss_clean($array[$index]);\r
+               }\r
+\r
+               return $array[$index];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch an item from the GET array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function get($index = '', $xss_clean = FALSE)\r
+       {\r
+               return $this->_fetch_from_array($_GET, $index, $xss_clean);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch an item from the POST array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function post($index = '', $xss_clean = FALSE)\r
+       {\r
+               return $this->_fetch_from_array($_POST, $index, $xss_clean);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch an item from either the GET array or the POST\r
+        *\r
+        * @access      public\r
+        * @param       string  The index key\r
+        * @param       bool    XSS cleaning\r
+        * @return      string\r
+        */\r
+       function get_post($index = '', $xss_clean = FALSE)\r
+       {               \r
+               if ( ! isset($_POST[$index]) )\r
+               {\r
+                       return $this->get($index, $xss_clean);\r
+               }\r
+               else\r
+               {\r
+                       return $this->post($index, $xss_clean);\r
+               }               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch an item from the COOKIE array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function cookie($index = '', $xss_clean = FALSE)\r
+       {\r
+               return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch an item from the SERVER array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function server($index = '', $xss_clean = FALSE)\r
+       {\r
+               return $this->_fetch_from_array($_SERVER, $index, $xss_clean);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch the IP Address\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function ip_address()\r
+       {\r
+               if ($this->ip_address !== FALSE)\r
+               {\r
+                       return $this->ip_address;\r
+               }\r
+\r
+               if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))\r
+               {\r
+                        $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];\r
+               }\r
+               elseif ($this->server('REMOTE_ADDR'))\r
+               {\r
+                        $this->ip_address = $_SERVER['REMOTE_ADDR'];\r
+               }\r
+               elseif ($this->server('HTTP_CLIENT_IP'))\r
+               {\r
+                        $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];\r
+               }\r
+               elseif ($this->server('HTTP_X_FORWARDED_FOR'))\r
+               {\r
+                        $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];\r
+               }\r
+\r
+               if ($this->ip_address === FALSE)\r
+               {\r
+                       $this->ip_address = '0.0.0.0';\r
+                       return $this->ip_address;\r
+               }\r
+\r
+               if (strstr($this->ip_address, ','))\r
+               {\r
+                       $x = explode(',', $this->ip_address);\r
+                       $this->ip_address = end($x);\r
+               }\r
+\r
+               if ( ! $this->valid_ip($this->ip_address))\r
+               {\r
+                       $this->ip_address = '0.0.0.0';\r
+               }\r
+               \r
+               return $this->ip_address;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Validate IP Address\r
+        *\r
+        * Updated version suggested by Geert De Deckere\r
+        * \r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function valid_ip($ip)\r
+       {\r
+               $ip_segments = explode('.', $ip);\r
+\r
+               // Always 4 segments needed\r
+               if (count($ip_segments) != 4)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               // IP can not start with 0\r
+               if ($ip_segments[0][0] == '0')\r
+               {\r
+                       return FALSE;\r
+               }\r
+               // Check each segment\r
+               foreach ($ip_segments as $segment)\r
+               {\r
+                       // IP segments must be digits and can not be \r
+                       // longer than 3 digits or greater then 255\r
+                       if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * User Agent\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function user_agent()\r
+       {\r
+               if ($this->user_agent !== FALSE)\r
+               {\r
+                       return $this->user_agent;\r
+               }\r
+\r
+               $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];\r
+\r
+               return $this->user_agent;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Filename Security\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function filename_security($str)\r
+       {\r
+               $bad = array(\r
+                                               "../",\r
+                                               "./",\r
+                                               "<!--",\r
+                                               "-->",\r
+                                               "<",\r
+                                               ">",\r
+                                               "'",\r
+                                               '"',\r
+                                               '&',\r
+                                               '$',\r
+                                               '#',\r
+                                               '{',\r
+                                               '}',\r
+                                               '[',\r
+                                               ']',\r
+                                               '=',\r
+                                               ';',\r
+                                               '?',\r
+                                               "%20",\r
+                                               "%22",\r
+                                               "%3c",          // <\r
+                                               "%253c",        // <\r
+                                               "%3e",          // >\r
+                                               "%0e",          // >\r
+                                               "%28",          // (  \r
+                                               "%29",          // ) \r
+                                               "%2528",        // (\r
+                                               "%26",          // &\r
+                                               "%24",          // $\r
+                                               "%3f",          // ?\r
+                                               "%3b",          // ;\r
+                                               "%3d"           // =\r
+                                       );\r
+\r
+               return stripslashes(str_replace($bad, '', $str));\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * XSS Clean\r
+        *\r
+        * Sanitizes data so that Cross Site Scripting Hacks can be\r
+        * prevented.  This function does a fair amount of work but\r
+        * it is extremely thorough, designed to prevent even the\r
+        * most obscure XSS attempts.  Nothing is ever 100% foolproof,\r
+        * of course, but I haven't been able to get anything passed\r
+        * the filter.\r
+        *\r
+        * Note: This function should only be used to deal with data\r
+        * upon submission.  It's not something that should\r
+        * be used for general runtime processing.\r
+        *\r
+        * This function was based in part on some code and ideas I\r
+        * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention\r
+        *\r
+        * To help develop this script I used this great list of\r
+        * vulnerabilities along with a few other hacks I've\r
+        * harvested from examining vulnerabilities in other programs:\r
+        * http://ha.ckers.org/xss.html\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function xss_clean($str, $is_image = FALSE)\r
+       {\r
+               /*\r
+                * Is the string an array?\r
+                *\r
+                */\r
+               if (is_array($str))\r
+               {\r
+                       while (list($key) = each($str))\r
+                       {\r
+                               $str[$key] = $this->xss_clean($str[$key]);\r
+                       }\r
+       \r
+                       return $str;\r
+               }\r
+\r
+               /*\r
+                * Remove Invisible Characters\r
+                */\r
+               $str = $this->_remove_invisible_characters($str);\r
+\r
+               /*\r
+                * Protect GET variables in URLs\r
+                */\r
+                \r
+                // 901119URL5918AMP18930PROTECT8198\r
+                \r
+               $str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str);\r
+\r
+               /*\r
+                * Validate standard character entities\r
+                *\r
+                * Add a semicolon if missing.  We do this to enable\r
+                * the conversion of entities to ASCII later.\r
+                *\r
+                */\r
+               $str = preg_replace('#(&\#?[0-9a-z]{2,})[\x00-\x20]*;?#i', "\\1;", $str);\r
+\r
+               /*\r
+                * Validate UTF16 two byte encoding (x00) \r
+                *\r
+                * Just as above, adds a semicolon if missing.\r
+                *\r
+                */\r
+               $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);\r
+\r
+               /*\r
+                * Un-Protect GET variables in URLs\r
+                */\r
+               $str = str_replace($this->xss_hash(), '&', $str);\r
+\r
+               /*\r
+                * URL Decode\r
+                *\r
+                * Just in case stuff like this is submitted:\r
+                *\r
+                * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>\r
+                *\r
+                * Note: Use rawurldecode() so it does not remove plus signs\r
+                *\r
+                */\r
+               $str = rawurldecode($str);\r
+       \r
+               /*\r
+                * Convert character entities to ASCII \r
+                *\r
+                * This permits our tests below to work reliably.\r
+                * We only convert entities that are within tags since\r
+                * these are the ones that will pose security problems.\r
+                *\r
+                */\r
+\r
+               $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);\r
+        \r
+               $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str);\r
+\r
+               /*\r
+                * Remove Invisible Characters Again!\r
+                */\r
+               $str = $this->_remove_invisible_characters($str);\r
+               \r
+               /*\r
+                * Convert all tabs to spaces\r
+                *\r
+                * This prevents strings like this: ja  vascript\r
+                * NOTE: we deal with spaces between characters later.\r
+                * NOTE: preg_replace was found to be amazingly slow here on large blocks of data,\r
+                * so we use str_replace.\r
+                *\r
+                */\r
+               \r
+               if (strpos($str, "\t") !== FALSE)\r
+               {\r
+                       $str = str_replace("\t", ' ', $str);\r
+               }\r
+               \r
+               /*\r
+                * Capture converted string for later comparison\r
+                */\r
+               $converted_string = $str;\r
+               \r
+               /*\r
+                * Not Allowed Under Any Conditions\r
+                */\r
+               \r
+               foreach ($this->never_allowed_str as $key => $val)\r
+               {\r
+                       $str = str_replace($key, $val, $str);   \r
+               }\r
+       \r
+               foreach ($this->never_allowed_regex as $key => $val)\r
+               {\r
+                       $str = preg_replace("#".$key."#i", $val, $str);   \r
+               }\r
+\r
+               /*\r
+                * Makes PHP tags safe\r
+                *\r
+                *  Note: XML tags are inadvertently replaced too:\r
+                *\r
+                *      <?xml\r
+                *\r
+                * But it doesn't seem to pose a problem.\r
+                *\r
+                */\r
+               if ($is_image === TRUE)\r
+               {\r
+                       // Images have a tendency to have the PHP short opening and closing tags every so often\r
+                       // so we skip those and only do the long opening tags.\r
+                       $str = str_replace(array('<?php', '<?PHP'),  array('&lt;?php', '&lt;?PHP'), $str);\r
+               }\r
+               else\r
+               {\r
+                       $str = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);\r
+               }\r
+               \r
+               /*\r
+                * Compact any exploded words\r
+                *\r
+                * This corrects words like:  j a v a s c r i p t\r
+                * These words are compacted back to their correct state.\r
+                *\r
+                */\r
+               $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');\r
+               foreach ($words as $word)\r
+               {\r
+                       $temp = '';\r
+                       \r
+                       for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)\r
+                       {\r
+                               $temp .= substr($word, $i, 1)."\s*";\r
+                       }\r
+\r
+                       // We only want to do this when it is followed by a non-word character\r
+                       // That way valid stuff like "dealer to" does not become "dealerto"\r
+                       $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);\r
+               }\r
+               \r
+               /*\r
+                * Remove disallowed Javascript in links or img tags\r
+                * We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared\r
+                * to these simplified non-capturing preg_match(), especially if the pattern exists in the string\r
+                */\r
+               do\r
+               {\r
+                       $original = $str;\r
+       \r
+                       if (preg_match("/<a/i", $str))\r
+                       {\r
+                               $str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);\r
+                       }\r
+       \r
+                       if (preg_match("/<img/i", $str))\r
+                       {\r
+                               $str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);\r
+                       }\r
+       \r
+                       if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))\r
+                       {\r
+                               $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);\r
+                       }\r
+               }\r
+               while($original != $str);\r
+\r
+               unset($original);\r
+\r
+               /*\r
+                * Remove JavaScript Event Handlers\r
+                *\r
+                * Note: This code is a little blunt.  It removes\r
+                * the event handler and anything up to the closing >,\r
+                * but it's unlikely to be a problem.\r
+                *\r
+                */\r
+               $event_handlers = array('[^a-z_\-]on\w*','xmlns');\r
+\r
+               if ($is_image === TRUE)\r
+               {\r
+                       /*\r
+                        * Adobe Photoshop puts XML metadata into JFIF images, including namespacing, \r
+                        * so we have to allow this for images. -Paul\r
+                        */\r
+                       unset($event_handlers[array_search('xmlns', $event_handlers)]);\r
+               }\r
+\r
+               $str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str);\r
+\r
+               /*\r
+                * Sanitize naughty HTML elements\r
+                *\r
+                * If a tag containing any of the words in the list\r
+                * below is found, the tag gets converted to entities.\r
+                *\r
+                * So this: <blink>\r
+                * Becomes: &lt;blink&gt;\r
+                *\r
+                */\r
+               $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';\r
+               $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);\r
+\r
+               /*\r
+                * Sanitize naughty scripting elements\r
+                *\r
+                * Similar to above, only instead of looking for\r
+                * tags it looks for PHP and JavaScript commands\r
+                * that are disallowed.  Rather than removing the\r
+                * code, it simply converts the parenthesis to entities\r
+                * rendering the code un-executable.\r
+                *\r
+                * For example: eval('some code')\r
+                * Becomes:             eval&#40;'some code'&#41;\r
+                *\r
+                */\r
+               $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);\r
+                                       \r
+               /*\r
+                * Final clean up\r
+                *\r
+                * This adds a bit of extra precaution in case\r
+                * something got through the above filters\r
+                *\r
+                */\r
+               foreach ($this->never_allowed_str as $key => $val)\r
+               {\r
+                       $str = str_replace($key, $val, $str);   \r
+               }\r
+       \r
+               foreach ($this->never_allowed_regex as $key => $val)\r
+               {\r
+                       $str = preg_replace("#".$key."#i", $val, $str);\r
+               }\r
+\r
+               /*\r
+                *  Images are Handled in a Special Way\r
+                *  - Essentially, we want to know that after all of the character conversion is done whether\r
+                *  any unwanted, likely XSS, code was found.  If not, we return TRUE, as the image is clean.\r
+                *  However, if the string post-conversion does not matched the string post-removal of XSS,\r
+                *  then it fails, as there was unwanted XSS code found and removed/changed during processing.\r
+                */\r
+\r
+               if ($is_image === TRUE)\r
+               {\r
+                       if ($str == $converted_string)\r
+                       {\r
+                               return TRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               log_message('debug', "XSS Filtering completed");\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Random Hash for protecting URLs\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function xss_hash()\r
+       {\r
+               if ($this->xss_hash == '')\r
+               {\r
+                       if (phpversion() >= 4.2)\r
+                               mt_srand();\r
+                       else\r
+                               mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);\r
+\r
+                       $this->xss_hash = md5(time() + mt_rand(0, 1999999999));\r
+               }\r
+\r
+               return $this->xss_hash;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Remove Invisible Characters\r
+        *\r
+        * This prevents sandwiching null characters\r
+        * between ascii characters, like Java\0script.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _remove_invisible_characters($str)\r
+       {\r
+               static $non_displayables;\r
+               \r
+               if ( ! isset($non_displayables))\r
+               {\r
+                       // every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),\r
+                       $non_displayables = array(\r
+                                                                               '/%0[0-8bcef]/',                        // url encoded 00-08, 11, 12, 14, 15\r
+                                                                               '/%1[0-9a-f]/',                         // url encoded 16-31\r
+                                                                               '/[\x00-\x08]/',                        // 00-08\r
+                                                                               '/\x0b/', '/\x0c/',                     // 11, 12\r
+                                                                               '/[\x0e-\x1f]/'                         // 14-31\r
+                                                                       );\r
+               }\r
+\r
+               do\r
+               {\r
+                       $cleaned = $str;\r
+                       $str = preg_replace($non_displayables, '', $str);\r
+               }\r
+               while ($cleaned != $str);\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Compact Exploded Words\r
+        *\r
+        * Callback function for xss_clean() to remove whitespace from\r
+        * things like j a v a s c r i p t\r
+        *\r
+        * @access      public\r
+        * @param       type\r
+        * @return      type\r
+        */\r
+       function _compact_exploded_words($matches)\r
+       {\r
+               return preg_replace('/\s+/s', '', $matches[1]).$matches[2];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Sanitize Naughty HTML\r
+        *\r
+        * Callback function for xss_clean() to remove naughty HTML elements\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      string\r
+        */\r
+       function _sanitize_naughty_html($matches)\r
+       {\r
+               // encode opening brace\r
+               $str = '&lt;'.$matches[1].$matches[2].$matches[3];\r
+               \r
+               // encode captured opening or closing brace to prevent recursive vectors\r
+               $str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);\r
+               \r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * JS Link Removal\r
+        *\r
+        * Callback function for xss_clean() to sanitize links\r
+        * This limits the PCRE backtracks, making it more performance friendly\r
+        * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in\r
+        * PHP 5.2+ on link-heavy strings\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      string\r
+        */\r
+       function _js_link_removal($match)\r
+       {\r
+               $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));\r
+               return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);\r
+       }\r
+\r
+       /**\r
+        * JS Image Removal\r
+        *\r
+        * Callback function for xss_clean() to sanitize image tags\r
+        * This limits the PCRE backtracks, making it more performance friendly\r
+        * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in\r
+        * PHP 5.2+ on image tag heavy strings\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      string\r
+        */\r
+       function _js_img_removal($match)\r
+       {\r
+               $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));\r
+               return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Attribute Conversion\r
+        *\r
+        * Used as a callback for XSS Clean\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      string\r
+        */\r
+       function _convert_attribute($match)\r
+       {\r
+               return str_replace(array('>', '<'), array('&gt;', '&lt;'), $match[0]);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * HTML Entity Decode Callback\r
+        *\r
+        * Used as a callback for XSS Clean\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      string\r
+        */\r
+       function _html_entity_decode_callback($match)\r
+       {\r
+               $CFG =& load_class('Config');\r
+               $charset = $CFG->item('charset');\r
+\r
+               return $this->_html_entity_decode($match[0], strtoupper($charset));\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * HTML Entities Decode\r
+        *\r
+        * This function is a replacement for html_entity_decode()\r
+        *\r
+        * In some versions of PHP the native function does not work\r
+        * when UTF-8 is the specified character set, so this gives us\r
+        * a work-around.  More info here:\r
+        * http://bugs.php.net/bug.php?id=25670\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       /* -------------------------------------------------\r
+       /*  Replacement for html_entity_decode()\r
+       /* -------------------------------------------------*/\r
+\r
+       /*\r
+       NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the\r
+       character set, and the PHP developers said they were not back porting the\r
+       fix to versions other than PHP 5.x.\r
+       */\r
+       function _html_entity_decode($str, $charset='UTF-8')\r
+       {\r
+               if (stristr($str, '&') === FALSE) return $str;\r
+\r
+               // The reason we are not using html_entity_decode() by itself is because\r
+               // while it is not technically correct to leave out the semicolon\r
+               // at the end of an entity most browsers will still interpret the entity\r
+               // correctly.  html_entity_decode() does not convert entities without\r
+               // semicolons, so we are left with our own little solution here. Bummer.\r
+\r
+               if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>=')))\r
+               {\r
+                       $str = html_entity_decode($str, ENT_COMPAT, $charset);\r
+                       $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);\r
+                       return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);\r
+               }\r
+\r
+               // Numeric Entities\r
+               $str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);\r
+               $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);\r
+\r
+               // Literal Entities - Slightly slow so we do another check\r
+               if (stristr($str, '&') === FALSE)\r
+               {\r
+                       $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));\r
+               }\r
+\r
+               return $str;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Filter Attributes\r
+        *\r
+        * Filters tag attributes for consistency and safety\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _filter_attributes($str)\r
+       {\r
+               $out = '';\r
+\r
+               if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))\r
+               {\r
+                       foreach ($matches[0] as $match)\r
+                       {\r
+                               $out .= "{$match}";\r
+                       }                       \r
+               }\r
+\r
+               return $out;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+}\r
+// END Input class\r
+\r
+/* End of file Input.php */\r
+/* Location: ./system/libraries/Input.php */
\ No newline at end of file
diff --git a/libraries/Language.php b/libraries/Language.php
new file mode 100644 (file)
index 0000000..eb4613d
--- /dev/null
@@ -0,0 +1,124 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Language Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Language\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/language.html\r
+ */\r
+class CI_Language {\r
+\r
+       var $language   = array();\r
+       var $is_loaded  = array();\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        */     \r
+       function CI_Language()\r
+       {\r
+               log_message('debug', "Language Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load a language file\r
+        *\r
+        * @access      public\r
+        * @param       mixed   the name of the language file to be loaded. Can be an array\r
+        * @param       string  the language (english, etc.)\r
+        * @return      void\r
+        */\r
+       function load($langfile = '', $idiom = '', $return = FALSE)\r
+       {       \r
+               $langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;\r
+               \r
+               if (in_array($langfile, $this->is_loaded, TRUE))\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               if ($idiom == '')\r
+               {\r
+                       $CI =& get_instance();\r
+                       $deft_lang = $CI->config->item('language');\r
+                       $idiom = ($deft_lang == '') ? 'english' : $deft_lang;\r
+               }\r
+       \r
+               // Determine where the language file is and load it\r
+               if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))\r
+               {\r
+                       include(APPPATH.'language/'.$idiom.'/'.$langfile);\r
+               }\r
+               else\r
+               {               \r
+                       if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))\r
+                       {\r
+                               include(BASEPATH.'language/'.$idiom.'/'.$langfile);\r
+                       }\r
+                       else\r
+                       {\r
+                               show_error('Unable to load the requested language file: language/'.$langfile);\r
+                       }\r
+               }\r
+\r
+               \r
+               if ( ! isset($lang))\r
+               {\r
+                       log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);\r
+                       return;\r
+               }\r
+               \r
+               if ($return == TRUE)\r
+               {\r
+                       return $lang;\r
+               }\r
+               \r
+               $this->is_loaded[] = $langfile;\r
+               $this->language = array_merge($this->language, $lang);\r
+               unset($lang);\r
+               \r
+               log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a single line of text from the language array\r
+        *\r
+        * @access      public\r
+        * @param       string  $line   the language line\r
+        * @return      string\r
+        */\r
+       function line($line = '')\r
+       {\r
+               $line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];\r
+               return $line;\r
+       }\r
+\r
+}\r
+// END Language Class\r
+\r
+/* End of file Language.php */\r
+/* Location: ./system/libraries/Language.php */
\ No newline at end of file
diff --git a/libraries/Loader.php b/libraries/Loader.php
new file mode 100644 (file)
index 0000000..da8d9e7
--- /dev/null
@@ -0,0 +1,1088 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Loader Class\r
+ *\r
+ * Loads views and files\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @category   Loader\r
+ * @link               http://codeigniter.com/user_guide/libraries/loader.html\r
+ */\r
+class CI_Loader {\r
+\r
+       // All these are set automatically. Don't mess with them.\r
+       var $_ci_ob_level;\r
+       var $_ci_view_path              = '';\r
+       var $_ci_is_php5                = FALSE;\r
+       var $_ci_is_instance    = FALSE; // Whether we should use $this or $CI =& get_instance()\r
+       var $_ci_cached_vars    = array();\r
+       var $_ci_classes                = array();\r
+       var $_ci_loaded_files   = array();\r
+       var $_ci_models                 = array();\r
+       var $_ci_helpers                = array();\r
+       var $_ci_plugins                = array();\r
+       var $_ci_varmap                 = array('unit_test' => 'unit', 'user_agent' => 'agent');\r
+       \r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Sets the path to the view files and gets the initial output buffering level\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Loader()\r
+       {       \r
+               $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;\r
+               $this->_ci_view_path = APPPATH.'views/';\r
+               $this->_ci_ob_level  = ob_get_level();\r
+                               \r
+               log_message('debug', "Loader Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Class Loader\r
+        *\r
+        * This function lets users load and instantiate classes.\r
+        * It is designed to be called from a user's app controllers.\r
+        *\r
+        * @access      public\r
+        * @param       string  the name of the class\r
+        * @param       mixed   the optional parameters\r
+        * @param       string  an optional object name\r
+        * @return      void\r
+        */     \r
+       function library($library = '', $params = NULL, $object_name = NULL)\r
+       {\r
+               if ($library == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if ( ! is_null($params) AND ! is_array($params))\r
+               {\r
+                       $params = NULL;\r
+               }\r
+\r
+               if (is_array($library))\r
+               {\r
+                       foreach ($library as $class)\r
+                       {\r
+                               $this->_ci_load_class($class, $params, $object_name);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->_ci_load_class($library, $params, $object_name);\r
+               }\r
+               \r
+               $this->_ci_assign_to_models();\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Model Loader\r
+        *\r
+        * This function lets users load and instantiate models.\r
+        *\r
+        * @access      public\r
+        * @param       string  the name of the class\r
+        * @param       string  name for the model\r
+        * @param       bool    database connection\r
+        * @return      void\r
+        */     \r
+       function model($model, $name = '', $db_conn = FALSE)\r
+       {               \r
+               if (is_array($model))\r
+               {\r
+                       foreach($model as $babe)\r
+                       {\r
+                               $this->model($babe);    \r
+                       }\r
+                       return;\r
+               }\r
+\r
+               if ($model == '')\r
+               {\r
+                       return;\r
+               }\r
+       \r
+               // Is the model in a sub-folder? If so, parse out the filename and path.\r
+               if (strpos($model, '/') === FALSE)\r
+               {\r
+                       $path = '';\r
+               }\r
+               else\r
+               {\r
+                       $x = explode('/', $model);\r
+                       $model = end($x);                       \r
+                       unset($x[count($x)-1]);\r
+                       $path = implode('/', $x).'/';\r
+               }\r
+       \r
+               if ($name == '')\r
+               {\r
+                       $name = $model;\r
+               }\r
+               \r
+               if (in_array($name, $this->_ci_models, TRUE))\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               $CI =& get_instance();\r
+               if (isset($CI->$name))\r
+               {\r
+                       show_error('The model name you are loading is the name of a resource that is already being used: '.$name);\r
+               }\r
+       \r
+               $model = strtolower($model);\r
+               \r
+               if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))\r
+               {\r
+                       show_error('Unable to locate the model you have specified: '.$model);\r
+               }\r
+                               \r
+               if ($db_conn !== FALSE AND ! class_exists('CI_DB'))\r
+               {\r
+                       if ($db_conn === TRUE)\r
+                               $db_conn = '';\r
+               \r
+                       $CI->load->database($db_conn, FALSE, TRUE);\r
+               }\r
+       \r
+               if ( ! class_exists('Model'))\r
+               {\r
+                       load_class('Model', FALSE);\r
+               }\r
+\r
+               require_once(APPPATH.'models/'.$path.$model.EXT);\r
+\r
+               $model = ucfirst($model);\r
+                               \r
+               $CI->$name = new $model();\r
+               $CI->$name->_assign_libraries();\r
+               \r
+               $this->_ci_models[] = $name;    \r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Database Loader\r
+        *\r
+        * @access      public\r
+        * @param       string  the DB credentials\r
+        * @param       bool    whether to return the DB object\r
+        * @param       bool    whether to enable active record (this allows us to override the config setting)\r
+        * @return      object\r
+        */     \r
+       function database($params = '', $return = FALSE, $active_record = FALSE)\r
+       {\r
+               // Grab the super object\r
+               $CI =& get_instance();\r
+               \r
+               // Do we even need to load the database class?\r
+               if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))\r
+               {\r
+                       return FALSE;\r
+               }       \r
+       \r
+               require_once(BASEPATH.'database/DB'.EXT);\r
+\r
+               if ($return === TRUE)\r
+               {\r
+                       return DB($params, $active_record);\r
+               }\r
+               \r
+               // Initialize the db variable.  Needed to prevent   \r
+               // reference errors with some configurations\r
+               $CI->db = '';\r
+               \r
+               // Load the DB class\r
+               $CI->db =& DB($params, $active_record); \r
+               \r
+               // Assign the DB object to any existing models\r
+               $this->_ci_assign_to_models();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Load the Utilities Class\r
+        *\r
+        * @access      public\r
+        * @return      string          \r
+        */             \r
+       function dbutil()\r
+       {\r
+               if ( ! class_exists('CI_DB'))\r
+               {\r
+                       $this->database();\r
+               }\r
+               \r
+               $CI =& get_instance();\r
+\r
+               // for backwards compatibility, load dbforge so we can extend dbutils off it\r
+               // this use is deprecated and strongly discouraged\r
+               $CI->load->dbforge();\r
+       \r
+               require_once(BASEPATH.'database/DB_utility'.EXT);\r
+               require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);\r
+               $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';\r
+\r
+               $CI->dbutil =& new $class();\r
+\r
+               $CI->load->_ci_assign_to_models();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Load the Database Forge Class\r
+        *\r
+        * @access      public\r
+        * @return      string          \r
+        */             \r
+       function dbforge()\r
+       {\r
+               if ( ! class_exists('CI_DB'))\r
+               {\r
+                       $this->database();\r
+               }\r
+               \r
+               $CI =& get_instance();\r
+       \r
+               require_once(BASEPATH.'database/DB_forge'.EXT);\r
+               require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);\r
+               $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';\r
+\r
+               $CI->dbforge = new $class();\r
+               \r
+               $CI->load->_ci_assign_to_models();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load View\r
+        *\r
+        * This function is used to load a "view" file.  It has three parameters:\r
+        *\r
+        * 1. The name of the "view" file to be included.\r
+        * 2. An associative array of data to be extracted for use in the view.\r
+        * 3. TRUE/FALSE - whether to return the data or load it.  In\r
+        * some cases it's advantageous to be able to return data so that\r
+        * a developer can process it in some way.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       array\r
+        * @param       bool\r
+        * @return      void\r
+        */\r
+       function view($view, $vars = array(), $return = FALSE)\r
+       {\r
+               return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load File\r
+        *\r
+        * This is a generic file loader\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function file($path, $return = FALSE)\r
+       {\r
+               return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Variables\r
+        *\r
+        * Once variables are set they become available within\r
+        * the controller class and its "view" files.\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function vars($vars = array(), $val = '')\r
+       {\r
+               if ($val != '' AND is_string($vars))\r
+               {\r
+                       $vars = array($vars => $val);\r
+               }\r
+       \r
+               $vars = $this->_ci_object_to_array($vars);\r
+       \r
+               if (is_array($vars) AND count($vars) > 0)\r
+               {\r
+                       foreach ($vars as $key => $val)\r
+                       {\r
+                               $this->_ci_cached_vars[$key] = $val;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load Helper\r
+        *\r
+        * This function loads the specified helper file.\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @return      void\r
+        */\r
+       function helper($helpers = array())\r
+       {\r
+               if ( ! is_array($helpers))\r
+               {\r
+                       $helpers = array($helpers);\r
+               }\r
+       \r
+               foreach ($helpers as $helper)\r
+               {               \r
+                       $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');\r
+\r
+                       if (isset($this->_ci_helpers[$helper]))\r
+                       {\r
+                               continue;\r
+                       }\r
+                       \r
+                       $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;\r
+\r
+                       // Is this a helper extension request?                  \r
+                       if (file_exists($ext_helper))\r
+                       {\r
+                               $base_helper = BASEPATH.'helpers/'.$helper.EXT;\r
+                               \r
+                               if ( ! file_exists($base_helper))\r
+                               {\r
+                                       show_error('Unable to load the requested file: helpers/'.$helper.EXT);\r
+                               }\r
+                               \r
+                               include_once($ext_helper);\r
+                               include_once($base_helper);\r
+                       }\r
+                       elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))\r
+                       { \r
+                               include_once(APPPATH.'helpers/'.$helper.EXT);\r
+                       }\r
+                       else\r
+                       {               \r
+                               if (file_exists(BASEPATH.'helpers/'.$helper.EXT))\r
+                               {\r
+                                       include_once(BASEPATH.'helpers/'.$helper.EXT);\r
+                               }\r
+                               else\r
+                               {\r
+                                       show_error('Unable to load the requested file: helpers/'.$helper.EXT);\r
+                               }\r
+                       }\r
+\r
+                       $this->_ci_helpers[$helper] = TRUE;\r
+                       log_message('debug', 'Helper loaded: '.$helper);        \r
+               }               \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load Helpers\r
+        *\r
+        * This is simply an alias to the above function in case the\r
+        * user has written the plural form of this function.\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function helpers($helpers = array())\r
+       {\r
+               $this->helper($helpers);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load Plugin\r
+        *\r
+        * This function loads the specified plugin.\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function plugin($plugins = array())\r
+       {\r
+               if ( ! is_array($plugins))\r
+               {\r
+                       $plugins = array($plugins);\r
+               }\r
+       \r
+               foreach ($plugins as $plugin)\r
+               {       \r
+                       $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');              \r
+\r
+                       if (isset($this->_ci_plugins[$plugin]))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (file_exists(APPPATH.'plugins/'.$plugin.EXT))\r
+                       {\r
+                               include_once(APPPATH.'plugins/'.$plugin.EXT);   \r
+                       }\r
+                       else\r
+                       {\r
+                               if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))\r
+                               {\r
+                                       include_once(BASEPATH.'plugins/'.$plugin.EXT);  \r
+                               }\r
+                               else\r
+                               {\r
+                                       show_error('Unable to load the requested file: plugins/'.$plugin.EXT);\r
+                               }\r
+                       }\r
+                       \r
+                       $this->_ci_plugins[$plugin] = TRUE;\r
+                       log_message('debug', 'Plugin loaded: '.$plugin);\r
+               }               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Load Plugins\r
+        *\r
+        * This is simply an alias to the above function in case the\r
+        * user has written the plural form of this function.\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function plugins($plugins = array())\r
+       {\r
+               $this->plugin($plugins);\r
+       }\r
+               \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Loads a language file\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function language($file = array(), $lang = '')\r
+       {\r
+               $CI =& get_instance();\r
+\r
+               if ( ! is_array($file))\r
+               {\r
+                       $file = array($file);\r
+               }\r
+\r
+               foreach ($file as $langfile)\r
+               {       \r
+                       $CI->lang->load($langfile, $lang);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Loads language files for scaffolding\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      arra\r
+        */\r
+       function scaffold_language($file = '', $lang = '', $return = FALSE)\r
+       {\r
+               $CI =& get_instance();\r
+               return $CI->lang->load($file, $lang, $return);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Loads a config file\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)\r
+       {                       \r
+               $CI =& get_instance();\r
+               $CI->config->load($file, $use_sections, $fail_gracefully);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Scaffolding Loader\r
+        *\r
+        * This initializing function works a bit different than the\r
+        * others. It doesn't load the class.  Instead, it simply\r
+        * sets a flag indicating that scaffolding is allowed to be\r
+        * used.  The actual scaffolding function below is\r
+        * called by the front controller based on whether the\r
+        * second segment of the URL matches the "secret" scaffolding\r
+        * word stored in the application/config/routes.php\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function scaffolding($table = '')\r
+       {               \r
+               if ($table === FALSE)\r
+               {\r
+                       show_error('You must include the name of the table you would like to access when you initialize scaffolding');\r
+               }\r
+               \r
+               $CI =& get_instance();\r
+               $CI->_ci_scaffolding = TRUE;\r
+               $CI->_ci_scaff_table = $table;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+               \r
+       /**\r
+        * Loader\r
+        *\r
+        * This function is used to load views and files.\r
+        * Variables are prefixed with _ci_ to avoid symbol collision with\r
+        * variables made available to view files\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function _ci_load($_ci_data)\r
+       {\r
+               // Set the default data variables\r
+               foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)\r
+               {\r
+                       $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];\r
+               }\r
+\r
+               // Set the path to the requested file\r
+               if ($_ci_path == '')\r
+               {\r
+                       $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);\r
+                       $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;\r
+                       $_ci_path = $this->_ci_view_path.$_ci_file;\r
+               }\r
+               else\r
+               {\r
+                       $_ci_x = explode('/', $_ci_path);\r
+                       $_ci_file = end($_ci_x);\r
+               }\r
+               \r
+               if ( ! file_exists($_ci_path))\r
+               {\r
+                       show_error('Unable to load the requested file: '.$_ci_file);\r
+               }\r
+       \r
+               // This allows anything loaded using $this->load (views, files, etc.)\r
+               // to become accessible from within the Controller and Model functions.\r
+               // Only needed when running PHP 5\r
+               \r
+               if ($this->_ci_is_instance())\r
+               {\r
+                       $_ci_CI =& get_instance();\r
+                       foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)\r
+                       {\r
+                               if ( ! isset($this->$_ci_key))\r
+                               {\r
+                                       $this->$_ci_key =& $_ci_CI->$_ci_key;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               /*\r
+                * Extract and cache variables\r
+                *\r
+                * You can either set variables using the dedicated $this->load_vars()\r
+                * function or via the second parameter of this function. We'll merge\r
+                * the two types and cache them so that views that are embedded within\r
+                * other views can have access to these variables.\r
+                */     \r
+               if (is_array($_ci_vars))\r
+               {\r
+                       $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);\r
+               }\r
+               extract($this->_ci_cached_vars);\r
+                               \r
+               /*\r
+                * Buffer the output\r
+                *\r
+                * We buffer the output for two reasons:\r
+                * 1. Speed. You get a significant speed boost.\r
+                * 2. So that the final rendered template can be\r
+                * post-processed by the output class.  Why do we\r
+                * need post processing?  For one thing, in order to\r
+                * show the elapsed page load time.  Unless we\r
+                * can intercept the content right before it's sent to\r
+                * the browser and then stop the timer it won't be accurate.\r
+                */\r
+               ob_start();\r
+                               \r
+               // If the PHP installation does not support short tags we'll\r
+               // do a little string replacement, changing the short tags\r
+               // to standard PHP echo statements.\r
+               \r
+               if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)\r
+               {\r
+                       echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));\r
+               }\r
+               else\r
+               {\r
+                       include($_ci_path); // include() vs include_once() allows for multiple views with the same name\r
+               }\r
+               \r
+               log_message('debug', 'File loaded: '.$_ci_path);\r
+               \r
+               // Return the file data if requested\r
+               if ($_ci_return === TRUE)\r
+               {               \r
+                       $buffer = ob_get_contents();\r
+                       @ob_end_clean();\r
+                       return $buffer;\r
+               }\r
+\r
+               /*\r
+                * Flush the buffer... or buff the flusher?\r
+                *\r
+                * In order to permit views to be nested within\r
+                * other views, we need to flush the content back out whenever\r
+                * we are beyond the first level of output buffering so that\r
+                * it can be seen and included properly by the first included\r
+                * template and any subsequent ones. Oy!\r
+                *\r
+                */     \r
+               if (ob_get_level() > $this->_ci_ob_level + 1)\r
+               {\r
+                       ob_end_flush();\r
+               }\r
+               else\r
+               {\r
+                       // PHP 4 requires that we use a global\r
+                       global $OUT;\r
+                       $OUT->append_output(ob_get_contents());\r
+                       @ob_end_clean();\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Load class\r
+        *\r
+        * This function loads the requested class.\r
+        *\r
+        * @access      private\r
+        * @param       string  the item that is being loaded\r
+        * @param       mixed   any additional parameters\r
+        * @param       string  an optional object name\r
+        * @return      void\r
+        */\r
+       function _ci_load_class($class, $params = NULL, $object_name = NULL)\r
+       {       \r
+               // Get the class name, and while we're at it trim any slashes.  \r
+               // The directory path can be included as part of the class name, \r
+               // but we don't want a leading slash\r
+               $class = str_replace(EXT, '', trim($class, '/'));\r
+       \r
+               // Was the path included with the class name?\r
+               // We look for a slash to determine this\r
+               $subdir = '';\r
+               if (strpos($class, '/') !== FALSE)\r
+               {\r
+                       // explode the path so we can separate the filename from the path\r
+                       $x = explode('/', $class);      \r
+                       \r
+                       // Reset the $class variable now that we know the actual filename\r
+                       $class = end($x);\r
+                       \r
+                       // Kill the filename from the array\r
+                       unset($x[count($x)-1]);\r
+                       \r
+                       // Glue the path back together, sans filename\r
+                       $subdir = implode($x, '/').'/';\r
+               }\r
+\r
+               // We'll test for both lowercase and capitalized versions of the file name\r
+               foreach (array(ucfirst($class), strtolower($class)) as $class)\r
+               {\r
+                       $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;\r
+\r
+                       // Is this a class extension request?                   \r
+                       if (file_exists($subclass))\r
+                       {\r
+                               $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;\r
+                               \r
+                               if ( ! file_exists($baseclass))\r
+                               {\r
+                                       log_message('error', "Unable to load the requested class: ".$class);\r
+                                       show_error("Unable to load the requested class: ".$class);\r
+                               }\r
+\r
+                               // Safety:  Was the class already loaded by a previous call?\r
+                               if (in_array($subclass, $this->_ci_loaded_files))\r
+                               {\r
+                                       // Before we deem this to be a duplicate request, let's see\r
+                                       // if a custom object name is being supplied.  If so, we'll\r
+                                       // return a new instance of the object\r
+                                       if ( ! is_null($object_name))\r
+                                       {\r
+                                               $CI =& get_instance();\r
+                                               if ( ! isset($CI->$object_name))\r
+                                               {\r
+                                                       return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);                    \r
+                                               }\r
+                                       }\r
+                                       \r
+                                       $is_duplicate = TRUE;\r
+                                       log_message('debug', $class." class already loaded. Second attempt ignored.");\r
+                                       return;\r
+                               }\r
+       \r
+                               include_once($baseclass);                               \r
+                               include_once($subclass);\r
+                               $this->_ci_loaded_files[] = $subclass;\r
+       \r
+                               return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);                    \r
+                       }\r
+               \r
+                       // Lets search for the requested library file and load it.\r
+                       $is_duplicate = FALSE;          \r
+                       for ($i = 1; $i < 3; $i++)\r
+                       {\r
+                               $path = ($i % 2) ? APPPATH : BASEPATH;  \r
+                               $filepath = $path.'libraries/'.$subdir.$class.EXT;\r
+                               \r
+                               // Does the file exist?  No?  Bummer...\r
+                               if ( ! file_exists($filepath))\r
+                               {\r
+                                       continue;\r
+                               }\r
+                               \r
+                               // Safety:  Was the class already loaded by a previous call?\r
+                               if (in_array($filepath, $this->_ci_loaded_files))\r
+                               {\r
+                                       // Before we deem this to be a duplicate request, let's see\r
+                                       // if a custom object name is being supplied.  If so, we'll\r
+                                       // return a new instance of the object\r
+                                       if ( ! is_null($object_name))\r
+                                       {\r
+                                               $CI =& get_instance();\r
+                                               if ( ! isset($CI->$object_name))\r
+                                               {\r
+                                                       return $this->_ci_init_class($class, '', $params, $object_name);\r
+                                               }\r
+                                       }\r
+                               \r
+                                       $is_duplicate = TRUE;\r
+                                       log_message('debug', $class." class already loaded. Second attempt ignored.");\r
+                                       return;\r
+                               }\r
+                               \r
+                               include_once($filepath);\r
+                               $this->_ci_loaded_files[] = $filepath;\r
+                               return $this->_ci_init_class($class, '', $params, $object_name);\r
+                       }\r
+               } // END FOREACH\r
+\r
+               // One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?\r
+               if ($subdir == '')\r
+               {\r
+                       $path = strtolower($class).'/'.$class;\r
+                       return $this->_ci_load_class($path, $params);\r
+               }\r
+               \r
+               // If we got this far we were unable to find the requested class.\r
+               // We do not issue errors if the load call failed due to a duplicate request\r
+               if ($is_duplicate == FALSE)\r
+               {\r
+                       log_message('error', "Unable to load the requested class: ".$class);\r
+                       show_error("Unable to load the requested class: ".$class);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Instantiates a class\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @param       string  an optional object name\r
+        * @return      null\r
+        */\r
+       function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)\r
+       {       \r
+               // Is there an associated config file for this class?\r
+               if ($config === NULL)\r
+               {\r
+                       // We test for both uppercase and lowercase, for servers that\r
+                       // are case-sensitive with regard to file names\r
+                       if (file_exists(APPPATH.'config/'.strtolower($class).EXT))\r
+                       {\r
+                               include_once(APPPATH.'config/'.strtolower($class).EXT);\r
+                       }                       \r
+                       else\r
+                       {\r
+                               if (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))\r
+                               {\r
+                                       include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);\r
+                               }                       \r
+                       }\r
+               }\r
+               \r
+               if ($prefix == '')\r
+               {                       \r
+                       if (class_exists('CI_'.$class)) \r
+                       {\r
+                               $name = 'CI_'.$class;\r
+                       }\r
+                       elseif (class_exists(config_item('subclass_prefix').$class)) \r
+                       {\r
+                               $name = config_item('subclass_prefix').$class;\r
+                       }\r
+                       else\r
+                       {\r
+                               $name = $class;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $name = $prefix.$class;\r
+               }\r
+               \r
+               // Is the class name valid?\r
+               if ( ! class_exists($name))\r
+               {\r
+                       log_message('error', "Non-existent class: ".$name);\r
+                       show_error("Non-existent class: ".$class);\r
+               }\r
+               \r
+               // Set the variable name we will assign the class to\r
+               // Was a custom class name supplied?  If so we'll use it\r
+               $class = strtolower($class);\r
+               \r
+               if (is_null($object_name))\r
+               {\r
+                       $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];\r
+               }\r
+               else\r
+               {\r
+                       $classvar = $object_name;\r
+               }\r
+\r
+               // Save the class name and object name          \r
+               $this->_ci_classes[$class] = $classvar;\r
+\r
+               // Instantiate the class                \r
+               $CI =& get_instance();\r
+               if ($config !== NULL)\r
+               {\r
+                       $CI->$classvar = new $name($config);\r
+               }\r
+               else\r
+               {               \r
+                       $CI->$classvar = new $name;\r
+               }       \r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Autoloader\r
+        *\r
+        * The config/autoload.php file contains an array that permits sub-systems,\r
+        * libraries, plugins, and helpers to be loaded automatically.\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function _ci_autoloader()\r
+       {       \r
+               include_once(APPPATH.'config/autoload'.EXT);\r
+               \r
+               if ( ! isset($autoload))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Load any custom config file\r
+               if (count($autoload['config']) > 0)\r
+               {                       \r
+                       $CI =& get_instance();\r
+                       foreach ($autoload['config'] as $key => $val)\r
+                       {\r
+                               $CI->config->load($val);\r
+                       }\r
+               }               \r
+\r
+               // Autoload plugins, helpers and languages\r
+               foreach (array('helper', 'plugin', 'language') as $type)\r
+               {                       \r
+                       if (isset($autoload[$type]) AND count($autoload[$type]) > 0)\r
+                       {\r
+                               $this->$type($autoload[$type]);\r
+                       }               \r
+               }\r
+\r
+               // A little tweak to remain backward compatible\r
+               // The $autoload['core'] item was deprecated\r
+               if ( ! isset($autoload['libraries']))\r
+               {\r
+                       $autoload['libraries'] = $autoload['core'];\r
+               }\r
+               \r
+               // Load libraries\r
+               if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)\r
+               {\r
+                       // Load the database driver.\r
+                       if (in_array('database', $autoload['libraries']))\r
+                       {\r
+                               $this->database();\r
+                               $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));\r
+                       }\r
+\r
+                       // Load scaffolding\r
+                       if (in_array('scaffolding', $autoload['libraries']))\r
+                       {\r
+                               $this->scaffolding();\r
+                               $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));\r
+                       }\r
+               \r
+                       // Load all other libraries\r
+                       foreach ($autoload['libraries'] as $item)\r
+                       {\r
+                               $this->library($item);\r
+                       }\r
+               }               \r
+\r
+               // Autoload models\r
+               if (isset($autoload['model']))\r
+               {\r
+                       $this->model($autoload['model']);\r
+               }\r
+\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Assign to Models\r
+        *\r
+        * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)\r
+        * will be available to models, if any exist.\r
+        *\r
+        * @access      private\r
+        * @param       object\r
+        * @return      array\r
+        */\r
+       function _ci_assign_to_models()\r
+       {\r
+               if (count($this->_ci_models) == 0)\r
+               {\r
+                       return;\r
+               }\r
+       \r
+               if ($this->_ci_is_instance())\r
+               {\r
+                       $CI =& get_instance();\r
+                       foreach ($this->_ci_models as $model)\r
+                       {                       \r
+                               $CI->$model->_assign_libraries();\r
+                       }\r
+               }\r
+               else\r
+               {               \r
+                       foreach ($this->_ci_models as $model)\r
+                       {                       \r
+                               $this->$model->_assign_libraries();\r
+                       }\r
+               }\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Object to Array\r
+        *\r
+        * Takes an object as input and converts the class variables to array key/vals\r
+        *\r
+        * @access      private\r
+        * @param       object\r
+        * @return      array\r
+        */\r
+       function _ci_object_to_array($object)\r
+       {\r
+               return (is_object($object)) ? get_object_vars($object) : $object;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determines whether we should use the CI instance or $this\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */\r
+       function _ci_is_instance()\r
+       {\r
+               if ($this->_ci_is_php5 == TRUE)\r
+               {\r
+                       return TRUE;\r
+               }\r
+       \r
+               global $CI;\r
+               return (is_object($CI)) ? TRUE : FALSE;\r
+       }\r
+\r
+}\r
+\r
+/* End of file Loader.php */\r
+/* Location: ./system/libraries/Loader.php */
\ No newline at end of file
diff --git a/libraries/Log.php b/libraries/Log.php
new file mode 100644 (file)
index 0000000..811c873
--- /dev/null
@@ -0,0 +1,117 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Logging Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Logging\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/general/errors.html\r
+ */\r
+class CI_Log {\r
+\r
+       var $log_path;\r
+       var $_threshold = 1;\r
+       var $_date_fmt  = 'Y-m-d H:i:s';\r
+       var $_enabled   = TRUE;\r
+       var $_levels    = array('ERROR' => '1', 'DEBUG' => '2',  'INFO' => '3', 'ALL' => '4');\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Log()\r
+       {\r
+               $config =& get_config();\r
+               \r
+               $this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/';\r
+               \r
+               if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path))\r
+               {\r
+                       $this->_enabled = FALSE;\r
+               }\r
+               \r
+               if (is_numeric($config['log_threshold']))\r
+               {\r
+                       $this->_threshold = $config['log_threshold'];\r
+               }\r
+                       \r
+               if ($config['log_date_format'] != '')\r
+               {\r
+                       $this->_date_fmt = $config['log_date_format'];\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Write Log File\r
+        *\r
+        * Generally this function will be called using the global log_message() function\r
+        *\r
+        * @access      public\r
+        * @param       string  the error level\r
+        * @param       string  the error message\r
+        * @param       bool    whether the error is a native PHP error\r
+        * @return      bool\r
+        */             \r
+       function write_log($level = 'error', $msg, $php_error = FALSE)\r
+       {               \r
+               if ($this->_enabled === FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               $level = strtoupper($level);\r
+               \r
+               if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               $filepath = $this->log_path.'log-'.date('Y-m-d').EXT;\r
+               $message  = '';\r
+               \r
+               if ( ! file_exists($filepath))\r
+               {\r
+                       $message .= "<"."?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n";\r
+               }\r
+                       \r
+               if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n";\r
+               \r
+               flock($fp, LOCK_EX);    \r
+               fwrite($fp, $message);\r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);\r
+       \r
+               @chmod($filepath, FILE_WRITE_MODE);             \r
+               return TRUE;\r
+       }\r
+\r
+}\r
+// END Log Class\r
+\r
+/* End of file Log.php */\r
+/* Location: ./system/libraries/Log.php */
\ No newline at end of file
diff --git a/libraries/Model.php b/libraries/Model.php
new file mode 100644 (file)
index 0000000..1d3cbdf
--- /dev/null
@@ -0,0 +1,83 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Model Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/config.html\r
+ */\r
+class Model {\r
+\r
+       var $_parent_name = '';\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access public\r
+        */\r
+       function Model()\r
+       {\r
+               // If the magic __get() or __set() methods are used in a Model references can't be used.\r
+               $this->_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE );\r
+               \r
+               // We don't want to assign the model object to itself when using the\r
+               // assign_libraries function below so we'll grab the name of the model parent\r
+               $this->_parent_name = ucfirst(get_class($this));\r
+               \r
+               log_message('debug', "Model Class Initialized");\r
+       }\r
+\r
+       /**\r
+        * Assign Libraries\r
+        *\r
+        * Creates local references to all currently instantiated objects\r
+        * so that any syntax that can be legally used in a controller\r
+        * can be used within models.  \r
+        *\r
+        * @access private\r
+        */     \r
+       function _assign_libraries($use_reference = TRUE)\r
+       {\r
+               $CI =& get_instance();                          \r
+               foreach (array_keys(get_object_vars($CI)) as $key)\r
+               {\r
+                       if ( ! isset($this->$key) AND $key != $this->_parent_name)\r
+                       {                       \r
+                               // In some cases using references can cause\r
+                               // problems so we'll conditionally use them\r
+                               if ($use_reference == TRUE)\r
+                               {\r
+                                       $this->$key = NULL; // Needed to prevent reference errors with some configurations\r
+                                       $this->$key =& $CI->$key;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $this->$key = $CI->$key;\r
+                               }\r
+                       }\r
+               }               \r
+       }\r
+\r
+}\r
+// END Model Class\r
+\r
+/* End of file Model.php */\r
+/* Location: ./system/libraries/Model.php */
\ No newline at end of file
diff --git a/libraries/Output.php b/libraries/Output.php
new file mode 100644 (file)
index 0000000..98a941a
--- /dev/null
@@ -0,0 +1,478 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Output Class\r
+ *\r
+ * Responsible for sending final output to browser\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Output\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/output.html\r
+ */\r
+class CI_Output {\r
+\r
+       var $final_output;\r
+       var $cache_expiration   = 0;\r
+       var $headers                    = array();\r
+       var $enable_profiler    = FALSE;\r
+\r
+\r
+       function CI_Output()\r
+       {\r
+               log_message('debug', "Output Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get Output\r
+        *\r
+        * Returns the current output string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function get_output()\r
+       {\r
+               return $this->final_output;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Output\r
+        *\r
+        * Sets the output string\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_output($output)\r
+       {\r
+               $this->final_output = $output;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Append Output\r
+        *\r
+        * Appends data onto the output string\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function append_output($output)\r
+       {\r
+               if ($this->final_output == '')\r
+               {\r
+                       $this->final_output = $output;\r
+               }\r
+               else\r
+               {\r
+                       $this->final_output .= $output;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set Header\r
+        *\r
+        * Lets you set a server header which will be outputted with the final display.\r
+        *\r
+        * Note:  If a file is cached, headers will not be sent.  We need to figure out\r
+        * how to permit header data to be saved with the cache data...\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_header($header, $replace = TRUE)\r
+       {\r
+               $this->headers[] = array($header, $replace);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set HTTP Status Header\r
+        *\r
+        * @access      public\r
+        * @param       int     the status code\r
+        * @param       string  \r
+        * @return      void\r
+        */     \r
+       function set_status_header($code = '200', $text = '')\r
+       {\r
+               $stati = array(\r
+                                                       '200'   => 'OK',\r
+                                                       '201'   => 'Created',\r
+                                                       '202'   => 'Accepted',\r
+                                                       '203'   => 'Non-Authoritative Information',\r
+                                                       '204'   => 'No Content',\r
+                                                       '205'   => 'Reset Content',\r
+                                                       '206'   => 'Partial Content',\r
+                                                       \r
+                                                       '300'   => 'Multiple Choices',\r
+                                                       '301'   => 'Moved Permanently',\r
+                                                       '302'   => 'Found',\r
+                                                       '304'   => 'Not Modified',\r
+                                                       '305'   => 'Use Proxy',\r
+                                                       '307'   => 'Temporary Redirect',\r
+                                                       \r
+                                                       '400'   => 'Bad Request',\r
+                                                       '401'   => 'Unauthorized',\r
+                                                       '403'   => 'Forbidden',\r
+                                                       '404'   => 'Not Found',\r
+                                                       '405'   => 'Method Not Allowed',\r
+                                                       '406'   => 'Not Acceptable',\r
+                                                       '407'   => 'Proxy Authentication Required',\r
+                                                       '408'   => 'Request Timeout',\r
+                                                       '409'   => 'Conflict',\r
+                                                       '410'   => 'Gone',\r
+                                                       '411'   => 'Length Required',\r
+                                                       '412'   => 'Precondition Failed',\r
+                                                       '413'   => 'Request Entity Too Large',\r
+                                                       '414'   => 'Request-URI Too Long',\r
+                                                       '415'   => 'Unsupported Media Type',\r
+                                                       '416'   => 'Requested Range Not Satisfiable',\r
+                                                       '417'   => 'Expectation Failed',\r
+               \r
+                                                       '500'   => 'Internal Server Error',\r
+                                                       '501'   => 'Not Implemented',\r
+                                                       '502'   => 'Bad Gateway',\r
+                                                       '503'   => 'Service Unavailable',\r
+                                                       '504'   => 'Gateway Timeout',\r
+                                                       '505'   => 'HTTP Version Not Supported'\r
+                                               );\r
+\r
+               if ($code == '' OR ! is_numeric($code))\r
+               {\r
+                       show_error('Status codes must be numeric');\r
+               }\r
+\r
+               if (isset($stati[$code]) AND $text == '')\r
+               {                               \r
+                       $text = $stati[$code];\r
+               }\r
+               \r
+               if ($text == '')\r
+               {\r
+                       show_error('No status text available.  Please check your status code number or supply your own message text.');\r
+               }\r
+               \r
+               $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;\r
+       \r
+               if (substr(php_sapi_name(), 0, 3) == 'cgi')\r
+               {\r
+                       header("Status: {$code} {$text}", TRUE);\r
+               }\r
+               elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')\r
+               {\r
+                       header($server_protocol." {$code} {$text}", TRUE, $code);\r
+               }\r
+               else\r
+               {\r
+                       header("HTTP/1.1 {$code} {$text}", TRUE, $code);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Enable/disable Profiler\r
+        *\r
+        * @access      public\r
+        * @param       bool\r
+        * @return      void\r
+        */     \r
+       function enable_profiler($val = TRUE)\r
+       {\r
+               $this->enable_profiler = (is_bool($val)) ? $val : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Cache\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function cache($time)\r
+       {\r
+               $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Display Output\r
+        *\r
+        * All "view" data is automatically put into this variable by the controller class:\r
+        *\r
+        * $this->final_output\r
+        *\r
+        * This function sends the finalized output data to the browser along\r
+        * with any server headers and profile data.  It also stops the\r
+        * benchmark timer so the page rendering speed and memory usage can be shown.\r
+        *\r
+        * @access      public\r
+        * @return      mixed\r
+        */             \r
+       function _display($output = '')\r
+       {       \r
+               // Note:  We use globals because we can't use $CI =& get_instance()\r
+               // since this function is sometimes called by the caching mechanism,\r
+               // which happens before the CI super object is available.\r
+               global $BM, $CFG;\r
+               \r
+               // --------------------------------------------------------------------\r
+               \r
+               // Set the output data\r
+               if ($output == '')\r
+               {\r
+                       $output =& $this->final_output;\r
+               }\r
+               \r
+               // --------------------------------------------------------------------\r
+               \r
+               // Do we need to write a cache file?\r
+               if ($this->cache_expiration > 0)\r
+               {\r
+                       $this->_write_cache($output);\r
+               }\r
+               \r
+               // --------------------------------------------------------------------\r
+\r
+               // Parse out the elapsed time and memory usage,\r
+               // then swap the pseudo-variables with the data\r
+\r
+               $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');         \r
+               $output = str_replace('{elapsed_time}', $elapsed, $output);\r
+               \r
+               $memory  = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';\r
+               $output = str_replace('{memory_usage}', $memory, $output);              \r
+\r
+               // --------------------------------------------------------------------\r
+               \r
+               // Is compression requested?\r
+               if ($CFG->item('compress_output') === TRUE)\r
+               {\r
+                       if (extension_loaded('zlib'))\r
+                       {\r
+                               if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)\r
+                               {\r
+                                       ob_start('ob_gzhandler');\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // --------------------------------------------------------------------\r
+               \r
+               // Are there any server headers to send?\r
+               if (count($this->headers) > 0)\r
+               {\r
+                       foreach ($this->headers as $header)\r
+                       {\r
+                               @header($header[0], $header[1]);\r
+                       }\r
+               }               \r
+\r
+               // --------------------------------------------------------------------\r
+               \r
+               // Does the get_instance() function exist?\r
+               // If not we know we are dealing with a cache file so we'll\r
+               // simply echo out the data and exit.\r
+               if ( ! function_exists('get_instance'))\r
+               {\r
+                       echo $output;\r
+                       log_message('debug', "Final output sent to browser");\r
+                       log_message('debug', "Total execution time: ".$elapsed);\r
+                       return TRUE;\r
+               }\r
+       \r
+               // --------------------------------------------------------------------\r
+\r
+               // Grab the super object.  We'll need it in a moment...\r
+               $CI =& get_instance();\r
+               \r
+               // Do we need to generate profile data?\r
+               // If so, load the Profile class and run it.\r
+               if ($this->enable_profiler == TRUE)\r
+               {\r
+                       $CI->load->library('profiler');                         \r
+                                                                               \r
+                       // If the output data contains closing </body> and </html> tags\r
+                       // we will remove them and add them back after we insert the profile data\r
+                       if (preg_match("|</body>.*?</html>|is", $output))\r
+                       {\r
+                               $output  = preg_replace("|</body>.*?</html>|is", '', $output);\r
+                               $output .= $CI->profiler->run();\r
+                               $output .= '</body></html>';\r
+                       }\r
+                       else\r
+                       {\r
+                               $output .= $CI->profiler->run();\r
+                       }\r
+               }\r
+               \r
+               // --------------------------------------------------------------------\r
+\r
+               // Does the controller contain a function named _output()?\r
+               // If so send the output there.  Otherwise, echo it.\r
+               if (method_exists($CI, '_output'))\r
+               {\r
+                       $CI->_output($output);\r
+               }\r
+               else\r
+               {\r
+                       echo $output;  // Send it to the browser!\r
+               }\r
+               \r
+               log_message('debug', "Final output sent to browser");\r
+               log_message('debug', "Total execution time: ".$elapsed);                \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Write a Cache File\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function _write_cache($output)\r
+       {\r
+               $CI =& get_instance();  \r
+               $path = $CI->config->item('cache_path');\r
+       \r
+               $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;\r
+               \r
+               if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               $uri =  $CI->config->item('base_url').\r
+                               $CI->config->item('index_page').\r
+                               $CI->uri->uri_string();\r
+               \r
+               $cache_path .= md5($uri);\r
+\r
+               if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))\r
+               {\r
+                       log_message('error', "Unable to write cache file: ".$cache_path);\r
+                       return;\r
+               }\r
+               \r
+               $expire = time() + ($this->cache_expiration * 60);\r
+               \r
+               if (flock($fp, LOCK_EX))\r
+               {\r
+                       fwrite($fp, $expire.'TS--->'.$output);\r
+                       flock($fp, LOCK_UN);\r
+               }\r
+               else\r
+               {\r
+                       log_message('error', "Unable to secure a file lock for file at: ".$cache_path);\r
+                       return;\r
+               }\r
+               fclose($fp);\r
+               @chmod($cache_path, DIR_WRITE_MODE);\r
+\r
+               log_message('debug', "Cache file written: ".$cache_path);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Update/serve a cached file\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function _display_cache(&$CFG, &$URI)\r
+       {\r
+               $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');\r
+                       \r
+               if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Build the file path.  The file name is an MD5 hash of the full URI\r
+               $uri =  $CFG->item('base_url').\r
+                               $CFG->item('index_page').\r
+                               $URI->uri_string;\r
+                               \r
+               $filepath = $cache_path.md5($uri);\r
+               \r
+               if ( ! @file_exists($filepath))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               if ( ! $fp = @fopen($filepath, FOPEN_READ))\r
+               {\r
+                       return FALSE;\r
+               }\r
+                       \r
+               flock($fp, LOCK_SH);\r
+               \r
+               $cache = '';\r
+               if (filesize($filepath) > 0)\r
+               {\r
+                       $cache = fread($fp, filesize($filepath));\r
+               }\r
+       \r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);\r
+                                       \r
+               // Strip out the embedded timestamp             \r
+               if ( ! preg_match("/(\d+TS--->)/", $cache, $match))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Has the file expired? If so we'll delete it.\r
+               if (time() >= trim(str_replace('TS--->', '', $match['1'])))\r
+               {               \r
+                       @unlink($filepath);\r
+                       log_message('debug', "Cache file has expired. File deleted");\r
+                       return FALSE;\r
+               }\r
+\r
+               // Display the cache\r
+               $this->_display(str_replace($match['0'], '', $cache));\r
+               log_message('debug', "Cache file is current. Sending it to browser.");          \r
+               return TRUE;\r
+       }\r
+\r
+\r
+}\r
+// END Output Class\r
+\r
+/* End of file Output.php */\r
+/* Location: ./system/libraries/Output.php */
\ No newline at end of file
diff --git a/libraries/Pagination.php b/libraries/Pagination.php
new file mode 100644 (file)
index 0000000..5435f42
--- /dev/null
@@ -0,0 +1,244 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Pagination Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Pagination\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/pagination.html\r
+ */\r
+class CI_Pagination {\r
+\r
+       var $base_url                   = ''; // The page we are linking to\r
+       var $total_rows                 = ''; // Total number of items (database results)\r
+       var $per_page                   = 10; // Max number of items you want shown per page\r
+       var $num_links                  =  2; // Number of "digit" links to show before/after the currently viewed page\r
+       var $cur_page                   =  0; // The current page being viewed\r
+       var $first_link                 = '&lsaquo; First';\r
+       var $next_link                  = '&gt;';\r
+       var $prev_link                  = '&lt;';\r
+       var $last_link                  = 'Last &rsaquo;';\r
+       var $uri_segment                = 3;\r
+       var $full_tag_open              = '';\r
+       var $full_tag_close             = '';\r
+       var $first_tag_open             = '';\r
+       var $first_tag_close    = '&nbsp;';\r
+       var $last_tag_open              = '&nbsp;';\r
+       var $last_tag_close             = '';\r
+       var $cur_tag_open               = '&nbsp;<b>';\r
+       var $cur_tag_close              = '</b>';\r
+       var $next_tag_open              = '&nbsp;';\r
+       var $next_tag_close             = '&nbsp;';\r
+       var $prev_tag_open              = '&nbsp;';\r
+       var $prev_tag_close             = '';\r
+       var $num_tag_open               = '&nbsp;';\r
+       var $num_tag_close              = '';\r
+       var $page_query_string  = FALSE;\r
+       var $query_string_segment = 'per_page';\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        * @param       array   initialization parameters\r
+        */\r
+       function CI_Pagination($params = array())\r
+       {\r
+               if (count($params) > 0)\r
+               {\r
+                       $this->initialize($params);             \r
+               }\r
+               \r
+               log_message('debug', "Pagination Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Initialize Preferences\r
+        *\r
+        * @access      public\r
+        * @param       array   initialization parameters\r
+        * @return      void\r
+        */\r
+       function initialize($params = array())\r
+       {\r
+               if (count($params) > 0)\r
+               {\r
+                       foreach ($params as $key => $val)\r
+                       {\r
+                               if (isset($this->$key))\r
+                               {\r
+                                       $this->$key = $val;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate the pagination links\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function create_links()\r
+       {\r
+               // If our item count or per-page total is zero there is no need to continue.\r
+               if ($this->total_rows == 0 OR $this->per_page == 0)\r
+               {\r
+                  return '';\r
+               }\r
+\r
+               // Calculate the total number of pages\r
+               $num_pages = ceil($this->total_rows / $this->per_page);\r
+\r
+               // Is there only one page? Hm... nothing more to do here then.\r
+               if ($num_pages == 1)\r
+               {\r
+                       return '';\r
+               }\r
+\r
+               // Determine the current page number.           \r
+               $CI =& get_instance();\r
+               \r
+               if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)\r
+               {\r
+                       if ($CI->input->get($this->query_string_segment) != 0)\r
+                       {\r
+                               $this->cur_page = $CI->input->get($this->query_string_segment);\r
+                               \r
+                               // Prep the current page - no funny business!\r
+                               $this->cur_page = (int) $this->cur_page;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if ($CI->uri->segment($this->uri_segment) != 0)\r
+                       {\r
+                               $this->cur_page = $CI->uri->segment($this->uri_segment);\r
+                               \r
+                               // Prep the current page - no funny business!\r
+                               $this->cur_page = (int) $this->cur_page;\r
+                       }\r
+               }\r
+\r
+               $this->num_links = (int)$this->num_links;\r
+               \r
+               if ($this->num_links < 1)\r
+               {\r
+                       show_error('Your number of links must be a positive number.');\r
+               }\r
+                               \r
+               if ( ! is_numeric($this->cur_page))\r
+               {\r
+                       $this->cur_page = 0;\r
+               }\r
+               \r
+               // Is the page number beyond the result range?\r
+               // If so we show the last page\r
+               if ($this->cur_page > $this->total_rows)\r
+               {\r
+                       $this->cur_page = ($num_pages - 1) * $this->per_page;\r
+               }\r
+               \r
+               $uri_page_number = $this->cur_page;\r
+               $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);\r
+\r
+               // Calculate the start and end numbers. These determine\r
+               // which number to start and end the digit links with\r
+               $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;\r
+               $end   = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;\r
+\r
+               // Is pagination being used over GET or POST?  If get, add a per_page query\r
+               // string. If post, add a trailing slash to the base URL if needed\r
+               if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)\r
+               {\r
+                       $this->base_url = rtrim($this->base_url).'&amp;'.$this->query_string_segment.'=';\r
+               }\r
+               else\r
+               {\r
+                       $this->base_url = rtrim($this->base_url, '/') .'/';\r
+               }\r
+\r
+               // And here we go...\r
+               $output = '';\r
+\r
+               // Render the "First" link\r
+               if  ($this->cur_page > ($this->num_links + 1))\r
+               {\r
+                       $output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;\r
+               }\r
+\r
+               // Render the "previous" link\r
+               if  ($this->cur_page != 1)\r
+               {\r
+                       $i = $uri_page_number - $this->per_page;\r
+                       if ($i == 0) $i = '';\r
+                       $output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;\r
+               }\r
+\r
+               // Write the digit links\r
+               for ($loop = $start -1; $loop <= $end; $loop++)\r
+               {\r
+                       $i = ($loop * $this->per_page) - $this->per_page;\r
+                                       \r
+                       if ($i >= 0)\r
+                       {\r
+                               if ($this->cur_page == $loop)\r
+                               {\r
+                                       $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page\r
+                               }\r
+                               else\r
+                               {\r
+                                       $n = ($i == 0) ? '' : $i;\r
+                                       $output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Render the "next" link\r
+               if ($this->cur_page < $num_pages)\r
+               {\r
+                       $output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;\r
+               }\r
+\r
+               // Render the "Last" link\r
+               if (($this->cur_page + $this->num_links) < $num_pages)\r
+               {\r
+                       $i = (($num_pages * $this->per_page) - $this->per_page);\r
+                       $output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close;\r
+               }\r
+\r
+               // Kill double slashes.  Note: Sometimes we can end up with a double slash\r
+               // in the penultimate link so we'll kill all double slashes.\r
+               $output = preg_replace("#([^:])//+#", "\\1/", $output);\r
+\r
+               // Add the wrapper HTML if exists\r
+               $output = $this->full_tag_open.$output.$this->full_tag_close;\r
+               \r
+               return $output;         \r
+       }\r
+}\r
+// END Pagination Class\r
+\r
+/* End of file Pagination.php */\r
+/* Location: ./system/libraries/Pagination.php */
\ No newline at end of file
diff --git a/libraries/Parser.php b/libraries/Parser.php
new file mode 100644 (file)
index 0000000..e276a0d
--- /dev/null
@@ -0,0 +1,173 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Parser Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Parser\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/parser.html\r
+ */\r
+class CI_Parser {\r
+\r
+       var $l_delim = '{';\r
+       var $r_delim = '}';\r
+       var $object;\r
+               \r
+       /**\r
+        *  Parse a template\r
+        *\r
+        * Parses pseudo-variables contained in the specified template,\r
+        * replacing them with the data in the second param\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       array\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function parse($template, $data, $return = FALSE)\r
+       {\r
+               $CI =& get_instance();\r
+               $template = $CI->load->view($template, $data, TRUE);\r
+               \r
+               if ($template == '')\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               foreach ($data as $key => $val)\r
+               {\r
+                       if (is_array($val))\r
+                       {\r
+                               $template = $this->_parse_pair($key, $val, $template);          \r
+                       }\r
+                       else\r
+                       {\r
+                               $template = $this->_parse_single($key, (string)$val, $template);\r
+                       }\r
+               }\r
+               \r
+               if ($return == FALSE)\r
+               {\r
+                       $CI->output->append_output($template);\r
+               }\r
+               \r
+               return $template;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Set the left/right variable delimiters\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_delimiters($l = '{', $r = '}')\r
+       {\r
+               $this->l_delim = $l;\r
+               $this->r_delim = $r;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Parse a single key/value\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _parse_single($key, $val, $string)\r
+       {\r
+               return str_replace($this->l_delim.$key.$this->r_delim, $val, $string);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Parse a tag pair\r
+        *\r
+        * Parses tag pairs:  {some_tag} string... {/some_tag}\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       array\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _parse_pair($variable, $data, $string)\r
+       {       \r
+               if (FALSE === ($match = $this->_match_pair($string, $variable)))\r
+               {\r
+                       return $string;\r
+               }\r
+\r
+               $str = '';\r
+               foreach ($data as $row)\r
+               {\r
+                       $temp = $match['1'];\r
+                       foreach ($row as $key => $val)\r
+                       {\r
+                               if ( ! is_array($val))\r
+                               {\r
+                                       $temp = $this->_parse_single($key, $val, $temp);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $temp = $this->_parse_pair($key, $val, $temp);\r
+                               }\r
+                       }\r
+                       \r
+                       $str .= $temp;\r
+               }\r
+               \r
+               return str_replace($match['0'], $str, $string);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Matches a variable pair\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @param       string\r
+        * @return      mixed\r
+        */\r
+       function _match_pair($string, $variable)\r
+       {\r
+               if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+?)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return $match;\r
+       }\r
+\r
+}\r
+// END Parser Class\r
+\r
+/* End of file Parser.php */\r
+/* Location: ./system/libraries/Parser.php */
\ No newline at end of file
diff --git a/libraries/Profiler.php b/libraries/Profiler.php
new file mode 100644 (file)
index 0000000..7f869f4
--- /dev/null
@@ -0,0 +1,392 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * CodeIgniter Profiler Class\r
+ *\r
+ * This class enables you to display benchmark, query, and other data\r
+ * in order to help with debugging and optimization.\r
+ *\r
+ * Note: At some point it would be good to move all the HTML in this class\r
+ * into a set of template files in order to allow customization.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/general/profiling.html\r
+ */\r
+class CI_Profiler {\r
+\r
+       var $CI;\r
+       \r
+       function CI_Profiler()\r
+       {\r
+               $this->CI =& get_instance();\r
+               $this->CI->load->language('profiler');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Auto Profiler\r
+        *\r
+        * This function cycles through the entire array of mark points and\r
+        * matches any two points that are named identically (ending in "_start"\r
+        * and "_end" respectively).  It then compiles the execution times for\r
+        * all points and returns it as an array\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _compile_benchmarks()\r
+       {\r
+               $profile = array();\r
+               foreach ($this->CI->benchmark->marker as $key => $val)\r
+               {\r
+                       // We match the "end" marker so that the list ends\r
+                       // up in the order that it was defined\r
+                       if (preg_match("/(.+?)_end/i", $key, $match))\r
+                       {                       \r
+                               if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))\r
+                               {\r
+                                       $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Build a table containing the profile data.\r
+               // Note: At some point we should turn this into a template that can\r
+               // be modified.  We also might want to make this data available to be logged\r
+       \r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #990000;padding:6px 10px 10px 10px;margin:0 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#990000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";                        \r
+               $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";\r
+               \r
+               foreach ($profile as $key => $val)\r
+               {\r
+                       $key = ucwords(str_replace(array('_', '-'), ' ', $key));\r
+                       $output .= "<tr><td width='50%' style='color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td width='50%' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";\r
+               }\r
+               \r
+               $output .= "</table>\n";\r
+               $output .= "</fieldset>";\r
+               \r
+               return $output;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Compile Queries\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _compile_queries()\r
+       {\r
+               $dbs = array();\r
+               \r
+               // Let's determine which databases are currently connected to\r
+               foreach (get_object_vars($this->CI) as $CI_object)\r
+               {\r
+                       if ( is_subclass_of(get_class($CI_object), 'CI_DB') )\r
+                       {\r
+                               $dbs[] = $CI_object;\r
+                       }\r
+               }\r
+                                       \r
+               if (count($dbs) == 0)\r
+               {\r
+                       $output  = "\n\n";\r
+                       $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+                       $output .= "\n";\r
+                       $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';\r
+                       $output .= "\n";                \r
+                       $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";\r
+                       $output .="<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";\r
+                       $output .= "</table>\n";\r
+                       $output .= "</fieldset>";\r
+                       \r
+                       return $output;\r
+               }\r
+               \r
+               // Load the text helper so we can highlight the SQL\r
+               $this->CI->load->helper('text');\r
+\r
+               // Key words we want bolded\r
+               $highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');\r
+\r
+               $output  = "\n\n";\r
+                       \r
+               foreach ($dbs as $db)\r
+               {\r
+                       $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+                       $output .= "\n";\r
+                       $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($this->CI->db->queries).'&nbsp;&nbsp;&nbsp;</legend>';\r
+                       $output .= "\n";                \r
+                       $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";\r
+               \r
+                       if (count($db->queries) == 0)\r
+                       {\r
+                               $output .= "<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";\r
+                       }\r
+                       else\r
+                       {                               \r
+                               foreach ($db->queries as $key => $val)\r
+                               {                                       \r
+                                       $time = number_format($db->query_times[$key], 4);\r
+\r
+                                       $val = highlight_code($val, ENT_QUOTES);\r
+       \r
+                                       foreach ($highlight as $bold)\r
+                                       {\r
+                                               $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);  \r
+                                       }\r
+                                       \r
+                                       $output .= "<tr><td width='1%' valign='top' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";\r
+                               }\r
+                       }\r
+                       \r
+                       $output .= "</table>\n";\r
+                       $output .= "</fieldset>";\r
+                       \r
+               }\r
+               \r
+               return $output;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Compile $_GET Data\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _compile_get()\r
+       {       \r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";\r
+                               \r
+               if (count($_GET) == 0)\r
+               {\r
+                       $output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";\r
+               }\r
+               else\r
+               {\r
+                       $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";\r
+               \r
+                       foreach ($_GET as $key => $val)\r
+                       {\r
+                               if ( ! is_numeric($key))\r
+                               {\r
+                                       $key = "'".$key."'";\r
+                               }\r
+                       \r
+                               $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#cd6e00;font-weight:normal;background-color:#ddd;'>";\r
+                               if (is_array($val))\r
+                               {\r
+                                       $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";\r
+                               }\r
+                               else\r
+                               {\r
+                                       $output .= htmlspecialchars(stripslashes($val));\r
+                               }\r
+                               $output .= "</td></tr>\n";\r
+                       }\r
+                       \r
+                       $output .= "</table>\n";\r
+               }\r
+               $output .= "</fieldset>";\r
+\r
+               return $output; \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Compile $_POST Data\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _compile_post()\r
+       {       \r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";\r
+                               \r
+               if (count($_POST) == 0)\r
+               {\r
+                       $output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";\r
+               }\r
+               else\r
+               {\r
+                       $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";\r
+               \r
+                       foreach ($_POST as $key => $val)\r
+                       {\r
+                               if ( ! is_numeric($key))\r
+                               {\r
+                                       $key = "'".$key."'";\r
+                               }\r
+                       \r
+                               $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>";\r
+                               if (is_array($val))\r
+                               {\r
+                                       $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";\r
+                               }\r
+                               else\r
+                               {\r
+                                       $output .= htmlspecialchars(stripslashes($val));\r
+                               }\r
+                               $output .= "</td></tr>\n";\r
+                       }\r
+                       \r
+                       $output .= "</table>\n";\r
+               }\r
+               $output .= "</fieldset>";\r
+\r
+               return $output; \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Show query string\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _compile_uri_string()\r
+       {       \r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";\r
+               \r
+               if ($this->CI->uri->uri_string == '')\r
+               {\r
+                       $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";\r
+               }\r
+               else\r
+               {\r
+                       $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";                               \r
+               }\r
+               \r
+               $output .= "</fieldset>";\r
+\r
+               return $output; \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Show the controller and function that were called\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _compile_controller_info()\r
+       {       \r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";\r
+               \r
+               $output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";                                \r
+\r
+               \r
+               $output .= "</fieldset>";\r
+\r
+               return $output; \r
+       }\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Compile memory usage\r
+        *\r
+        * Display total used memory\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function _compile_memory_usage()\r
+       {\r
+               $output  = "\n\n";\r
+               $output .= '<fieldset style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';\r
+               $output .= "\n";\r
+               $output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';\r
+               $output .= "\n";\r
+               \r
+               if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')\r
+               {\r
+                       $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';\r
+               }\r
+               else\r
+               {\r
+                       $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>";                             \r
+               }\r
+               \r
+               $output .= "</fieldset>";\r
+\r
+               return $output;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Run the Profiler\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function run()\r
+       {\r
+               $output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";\r
+\r
+               $output .= $this->_compile_uri_string();\r
+               $output .= $this->_compile_controller_info();\r
+               $output .= $this->_compile_memory_usage();\r
+               $output .= $this->_compile_benchmarks();\r
+               $output .= $this->_compile_get();\r
+               $output .= $this->_compile_post();\r
+               $output .= $this->_compile_queries();\r
+\r
+               $output .= '</div>';\r
+\r
+               return $output;\r
+       }\r
+\r
+}\r
+\r
+// END CI_Profiler class\r
+\r
+/* End of file Profiler.php */\r
+/* Location: ./system/libraries/Profiler.php */
\ No newline at end of file
diff --git a/libraries/Router.php b/libraries/Router.php
new file mode 100644 (file)
index 0000000..cf42516
--- /dev/null
@@ -0,0 +1,385 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Router Class\r
+ *\r
+ * Parses URIs and determines routing\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @author             ExpressionEngine Dev Team\r
+ * @category   Libraries\r
+ * @link               http://codeigniter.com/user_guide/general/routing.html\r
+ */\r
+class CI_Router {\r
+\r
+       var $config;    \r
+       var $routes             = array();\r
+       var $error_routes       = array();\r
+       var $class                      = '';\r
+       var $method                     = 'index';\r
+       var $directory          = '';\r
+       var $uri_protocol       = 'auto';\r
+       var $default_controller;\r
+       var $scaffolding_request = FALSE; // Must be set to FALSE\r
+       \r
+       /**\r
+        * Constructor\r
+        *\r
+        * Runs the route mapping function.\r
+        */\r
+       function CI_Router()\r
+       {\r
+               $this->config =& load_class('Config');\r
+               $this->uri =& load_class('URI');\r
+               $this->_set_routing();\r
+               log_message('debug', "Router Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the route mapping\r
+        *\r
+        * This function determines what should be served based on the URI request,\r
+        * as well as any "routes" that have been set in the routing config file.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _set_routing()\r
+       {\r
+               // Are query strings enabled in the config file?\r
+               // If so, we're done since segment based URIs are not used with query strings.\r
+               if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))\r
+               {\r
+                       $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));\r
+\r
+                       if (isset($_GET[$this->config->item('function_trigger')]))\r
+                       {\r
+                               $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));\r
+                       }\r
+                       \r
+                       return;\r
+               }\r
+               \r
+               // Load the routes.php file.\r
+               @include(APPPATH.'config/routes'.EXT);\r
+               $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;\r
+               unset($route);\r
+\r
+               // Set the default controller so we can display it in the event\r
+               // the URI doesn't correlated to a valid controller.\r
+               $this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);     \r
+               \r
+               // Fetch the complete URI string\r
+               $this->uri->_fetch_uri_string();\r
+       \r
+               // Is there a URI string? If not, the default controller specified in the "routes" file will be shown.\r
+               if ($this->uri->uri_string == '')\r
+               {\r
+                       if ($this->default_controller === FALSE)\r
+                       {\r
+                               show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");\r
+                       }\r
+\r
+                       // Turn the default route into an array.  We explode it in the event that\r
+                       // the controller is located in a subfolder\r
+                       $segments = $this->_validate_request(explode('/', $this->default_controller));\r
+\r
+                       // Set the class and method\r
+                       $this->set_class($segments[0]);\r
+                       $this->set_method('index');\r
+                       \r
+                       // Assign the segments to the URI class\r
+                       $this->uri->rsegments = $segments;\r
+                       \r
+                       // re-index the routed segments array so it starts with 1 rather than 0\r
+                       $this->uri->_reindex_segments();\r
+                       \r
+                       log_message('debug', "No URI present. Default controller set.");\r
+                       return;\r
+               }\r
+               unset($this->routes['default_controller']);\r
+               \r
+               // Do we need to remove the URL suffix?\r
+               $this->uri->_remove_url_suffix();\r
+               \r
+               // Compile the segments into an array\r
+               $this->uri->_explode_segments();\r
+               \r
+               // Parse any custom routing that may exist\r
+               $this->_parse_routes();         \r
+               \r
+               // Re-index the segment array so that it starts with 1 rather than 0\r
+               $this->uri->_reindex_segments();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Route\r
+        *\r
+        * This function takes an array of URI segments as\r
+        * input, and sets the current class/method\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @param       bool\r
+        * @return      void\r
+        */\r
+       function _set_request($segments = array())\r
+       {       \r
+               $segments = $this->_validate_request($segments);\r
+               \r
+               if (count($segments) == 0)\r
+               {\r
+                       return;\r
+               }\r
+                                               \r
+               $this->set_class($segments[0]);\r
+               \r
+               if (isset($segments[1]))\r
+               {\r
+                       // A scaffolding request. No funny business with the URL\r
+                       if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding')\r
+                       {\r
+                               $this->scaffolding_request = TRUE;\r
+                               unset($this->routes['scaffolding_trigger']);\r
+                       }\r
+                       else\r
+                       {\r
+                               // A standard method request\r
+                               $this->set_method($segments[1]);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // This lets the "routed" segment array identify that the default\r
+                       // index method is being used.\r
+                       $segments[1] = 'index';\r
+               }\r
+               \r
+               // Update our "routed" segment array to contain the segments.\r
+               // Note: If there is no custom routing, this array will be\r
+               // identical to $this->uri->segments\r
+               $this->uri->rsegments = $segments;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validates the supplied segments.  Attempts to determine the path to\r
+        * the controller.\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      array\r
+        */     \r
+       function _validate_request($segments)\r
+       {\r
+               // Does the requested controller exist in the root folder?\r
+               if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))\r
+               {\r
+                       return $segments;\r
+               }\r
+\r
+               // Is the controller in a sub-folder?\r
+               if (is_dir(APPPATH.'controllers/'.$segments[0]))\r
+               {               \r
+                       // Set the directory and remove it from the segment array\r
+                       $this->set_directory($segments[0]);\r
+                       $segments = array_slice($segments, 1);\r
+                       \r
+                       if (count($segments) > 0)\r
+                       {\r
+                               // Does the requested controller exist in the sub-folder?\r
+                               if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))\r
+                               {\r
+                                       show_404($this->fetch_directory().$segments[0]);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->set_class($this->default_controller);\r
+                               $this->set_method('index');\r
+                       \r
+                               // Does the default controller exist in the sub-folder?\r
+                               if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))\r
+                               {\r
+                                       $this->directory = '';\r
+                                       return array();\r
+                               }\r
+                       \r
+                       }\r
+\r
+                       return $segments;\r
+               }\r
+\r
+               // Can't find the requested controller...\r
+               show_404($segments[0]);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        *  Parse Routes\r
+        *\r
+        * This function matches any routes that may exist in\r
+        * the config/routes.php file against the URI to\r
+        * determine if the class/method need to be remapped.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _parse_routes()\r
+       {\r
+               // Do we even have any custom routing to deal with?\r
+               // There is a default scaffolding trigger, so we'll look just for 1\r
+               if (count($this->routes) == 1)\r
+               {\r
+                       $this->_set_request($this->uri->segments);\r
+                       return;\r
+               }\r
+\r
+               // Turn the segment array into a URI string\r
+               $uri = implode('/', $this->uri->segments);\r
+\r
+               // Is there a literal match?  If so we're done\r
+               if (isset($this->routes[$uri]))\r
+               {\r
+                       $this->_set_request(explode('/', $this->routes[$uri]));         \r
+                       return;\r
+               }\r
+                               \r
+               // Loop through the route array looking for wild-cards\r
+               foreach ($this->routes as $key => $val)\r
+               {                                               \r
+                       // Convert wild-cards to RegEx\r
+                       $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));\r
+                       \r
+                       // Does the RegEx match?\r
+                       if (preg_match('#^'.$key.'$#', $uri))\r
+                       {                       \r
+                               // Do we have a back-reference?\r
+                               if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)\r
+                               {\r
+                                       $val = preg_replace('#^'.$key.'$#', $val, $uri);\r
+                               }\r
+                       \r
+                               $this->_set_request(explode('/', $val));                \r
+                               return;\r
+                       }\r
+               }\r
+\r
+               // If we got this far it means we didn't encounter a\r
+               // matching route so we'll set the site default route\r
+               $this->_set_request($this->uri->segments);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the class name\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_class($class)\r
+       {\r
+               $this->class = $class;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch the current class\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function fetch_class()\r
+       {\r
+               return $this->class;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Set the method name\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_method($method)\r
+       {\r
+               $this->method = $method;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Fetch the current method\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function fetch_method()\r
+       {\r
+               if ($this->method == $this->fetch_class())\r
+               {\r
+                       return 'index';\r
+               }\r
+\r
+               return $this->method;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Set the directory name\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_directory($dir)\r
+       {\r
+               $this->directory = $dir.'/';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        *  Fetch the sub-directory (if any) that contains the requested controller class\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */     \r
+       function fetch_directory()\r
+       {\r
+               return $this->directory;\r
+       }\r
+\r
+}\r
+// END Router Class\r
+\r
+/* End of file Router.php */\r
+/* Location: ./system/libraries/Router.php */
\ No newline at end of file
diff --git a/libraries/Session.php b/libraries/Session.php
new file mode 100644 (file)
index 0000000..ed5f9c3
--- /dev/null
@@ -0,0 +1,758 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Session Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Sessions\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/sessions.html\r
+ */\r
+class CI_Session {\r
+\r
+       var $sess_encrypt_cookie                = FALSE;\r
+       var $sess_use_database                  = FALSE;\r
+       var $sess_table_name                    = '';\r
+       var $sess_expiration                    = 7200;\r
+       var $sess_match_ip                              = FALSE;\r
+       var $sess_match_useragent               = TRUE;\r
+       var $sess_cookie_name                   = 'ci_session';\r
+       var $cookie_prefix                              = '';\r
+       var $cookie_path                                = '';\r
+       var $cookie_domain                              = '';\r
+       var $sess_time_to_update                = 300;\r
+       var $encryption_key                             = '';\r
+       var $flashdata_key                              = 'flash';\r
+       var $time_reference                             = 'time';\r
+       var $gc_probability                             = 5;\r
+       var $userdata                                   = array();\r
+       var $CI;\r
+       var $now;\r
+\r
+       /**\r
+        * Session Constructor\r
+        *\r
+        * The constructor runs the session routines automatically\r
+        * whenever the class is instantiated.\r
+        */             \r
+       function CI_Session($params = array())\r
+       {\r
+               log_message('debug', "Session Class Initialized");\r
+\r
+               // Set the super object to a local variable for use throughout the class\r
+               $this->CI =& get_instance();\r
+               \r
+               // Set all the session preferences, which can either be set \r
+               // manually via the $params array above or via the config file\r
+               foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)\r
+               {\r
+                       $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);\r
+               }               \r
+       \r
+               // Load the string helper so we can use the strip_slashes() function\r
+               $this->CI->load->helper('string');\r
+\r
+               // Do we need encryption? If so, load the encryption class\r
+               if ($this->sess_encrypt_cookie == TRUE)\r
+               {\r
+                       $this->CI->load->library('encrypt');\r
+               }\r
+\r
+               // Are we using a database?  If so, load it\r
+               if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')\r
+               {\r
+                       $this->CI->load->database();\r
+               }\r
+\r
+               // Set the "now" time.  Can either be GMT or server time, based on the\r
+               // config prefs.  We use this to set the "last activity" time\r
+               $this->now = $this->_get_time();\r
+\r
+               // Set the session length. If the session expiration is\r
+               // set to zero we'll set the expiration two years from now.\r
+               if ($this->sess_expiration == 0)\r
+               {\r
+                       $this->sess_expiration = (60*60*24*365*2);\r
+               }\r
+                                               \r
+               // Set the cookie name\r
+               $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;\r
+       \r
+               // Run the Session routine. If a session doesn't exist we'll \r
+               // create a new one.  If it does, we'll update it.\r
+               if ( ! $this->sess_read())\r
+               {\r
+                       $this->sess_create();\r
+               }\r
+               else\r
+               {       \r
+                       $this->sess_update();\r
+               }\r
+               \r
+               // Delete 'old' flashdata (from last request)\r
+               $this->_flashdata_sweep();\r
+               \r
+               // Mark all new flashdata as old (data will be deleted before next request)\r
+               $this->_flashdata_mark();\r
+\r
+               // Delete expired sessions if necessary\r
+               $this->_sess_gc();\r
+\r
+               log_message('debug', "Session routines successfully run");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch the current session data if it exists\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function sess_read()\r
+       {       \r
+               // Fetch the cookie\r
+               $session = $this->CI->input->cookie($this->sess_cookie_name);\r
+               \r
+               // No cookie?  Goodbye cruel world!...\r
+               if ($session === FALSE)\r
+               {\r
+                       log_message('debug', 'A session cookie was not found.');\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Decrypt the cookie data\r
+               if ($this->sess_encrypt_cookie == TRUE)\r
+               {\r
+                       $session = $this->CI->encrypt->decode($session);\r
+               }\r
+               else\r
+               {       \r
+                       // encryption was not used, so we need to check the md5 hash\r
+                       $hash    = substr($session, strlen($session)-32); // get last 32 chars\r
+                       $session = substr($session, 0, strlen($session)-32);\r
+\r
+                       // Does the md5 hash match?  This is to prevent manipulation of session data in userspace\r
+                       if ($hash !==  md5($session.$this->encryption_key))\r
+                       {\r
+                               log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');\r
+                               $this->sess_destroy();\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               // Unserialize the session array\r
+               $session = $this->_unserialize($session);\r
+               \r
+               // Is the session data we unserialized an array with the correct format?\r
+               if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))\r
+               {\r
+                       $this->sess_destroy();\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Is the session current?\r
+               if (($session['last_activity'] + $this->sess_expiration) < $this->now)\r
+               {\r
+                       $this->sess_destroy();\r
+                       return FALSE;\r
+               }\r
+\r
+               // Does the IP Match?\r
+               if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())\r
+               {\r
+                       $this->sess_destroy();\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Does the User Agent Match?\r
+               if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))\r
+               {\r
+                       $this->sess_destroy();\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Is there a corresponding session in the DB?\r
+               if ($this->sess_use_database === TRUE)\r
+               {\r
+                       $this->CI->db->where('session_id', $session['session_id']);\r
+                                       \r
+                       if ($this->sess_match_ip == TRUE)\r
+                       {\r
+                               $this->CI->db->where('ip_address', $session['ip_address']);\r
+                       }\r
+\r
+                       if ($this->sess_match_useragent == TRUE)\r
+                       {\r
+                               $this->CI->db->where('user_agent', $session['user_agent']);\r
+                       }\r
+                       \r
+                       $query = $this->CI->db->get($this->sess_table_name);\r
+\r
+                       // No result?  Kill it!\r
+                       if ($query->num_rows() == 0)\r
+                       {\r
+                               $this->sess_destroy();\r
+                               return FALSE;\r
+                       }\r
+\r
+                       // Is there custom data?  If so, add it to the main session array\r
+                       $row = $query->row();\r
+                       if (isset($row->user_data) AND $row->user_data != '')\r
+                       {\r
+                               $custom_data = $this->_unserialize($row->user_data);\r
+\r
+                               if (is_array($custom_data))\r
+                               {\r
+                                       foreach ($custom_data as $key => $val)\r
+                                       {\r
+                                               $session[$key] = $val;\r
+                                       }\r
+                               }\r
+                       }                               \r
+               }\r
+       \r
+               // Session is valid!\r
+               $this->userdata = $session;\r
+               unset($session);\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Write the session data\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function sess_write()\r
+       {\r
+               // Are we saving custom data to the DB?  If not, all we do is update the cookie\r
+               if ($this->sess_use_database === FALSE)\r
+               {\r
+                       $this->_set_cookie();\r
+                       return;\r
+               }\r
+\r
+               // set the custom userdata, the session data we will set in a second\r
+               $custom_userdata = $this->userdata;\r
+               $cookie_userdata = array();\r
+               \r
+               // Before continuing, we need to determine if there is any custom data to deal with.\r
+               // Let's determine this by removing the default indexes to see if there's anything left in the array\r
+               // and set the session data while we're at it\r
+               foreach (array('session_id','ip_address','user_agent','last_activity') as $val)\r
+               {\r
+                       unset($custom_userdata[$val]);\r
+                       $cookie_userdata[$val] = $this->userdata[$val];\r
+               }\r
+               \r
+               // Did we find any custom data?  If not, we turn the empty array into a string\r
+               // since there's no reason to serialize and store an empty array in the DB\r
+               if (count($custom_userdata) === 0)\r
+               {\r
+                       $custom_userdata = '';\r
+               }\r
+               else\r
+               {       \r
+                       // Serialize the custom data array so we can store it\r
+                       $custom_userdata = $this->_serialize($custom_userdata);\r
+               }\r
+               \r
+               // Run the update query\r
+               $this->CI->db->where('session_id', $this->userdata['session_id']);\r
+               $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));\r
+\r
+               // Write the cookie.  Notice that we manually pass the cookie data array to the\r
+               // _set_cookie() function. Normally that function will store $this->userdata, but \r
+               // in this case that array contains custom data, which we do not want in the cookie.\r
+               $this->_set_cookie($cookie_userdata);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Create a new session\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function sess_create()\r
+       {       \r
+               $sessid = '';\r
+               while (strlen($sessid) < 32)\r
+               {\r
+                       $sessid .= mt_rand(0, mt_getrandmax());\r
+               }\r
+               \r
+               // To make the session ID even more secure we'll combine it with the user's IP\r
+               $sessid .= $this->CI->input->ip_address();\r
+       \r
+               $this->userdata = array(\r
+                                                       'session_id'    => md5(uniqid($sessid, TRUE)),\r
+                                                       'ip_address'    => $this->CI->input->ip_address(),\r
+                                                       'user_agent'    => substr($this->CI->input->user_agent(), 0, 50),\r
+                                                       'last_activity' => $this->now\r
+                                                       );\r
+               \r
+               \r
+               // Save the data to the DB if needed\r
+               if ($this->sess_use_database === TRUE)\r
+               {\r
+                       $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));\r
+               }\r
+                       \r
+               // Write the cookie\r
+               $this->_set_cookie();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Update an existing session\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function sess_update()\r
+       {\r
+               // We only update the session every five minutes by default\r
+               if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)\r
+               {\r
+                       return;\r
+               }\r
+       \r
+               // Save the old session id so we know which record to \r
+               // update in the database if we need it\r
+               $old_sessid = $this->userdata['session_id'];\r
+               $new_sessid = '';\r
+               while (strlen($new_sessid) < 32)\r
+               {\r
+                       $new_sessid .= mt_rand(0, mt_getrandmax());\r
+               }\r
+               \r
+               // To make the session ID even more secure we'll combine it with the user's IP\r
+               $new_sessid .= $this->CI->input->ip_address();\r
+               \r
+               // Turn it into a hash\r
+               $new_sessid = md5(uniqid($new_sessid, TRUE));\r
+               \r
+               // Update the session data in the session data array\r
+               $this->userdata['session_id'] = $new_sessid;\r
+               $this->userdata['last_activity'] = $this->now;\r
+               \r
+               // _set_cookie() will handle this for us if we aren't using database sessions\r
+               // by pushing all userdata to the cookie.\r
+               $cookie_data = NULL;\r
+               \r
+               // Update the session ID and last_activity field in the DB if needed\r
+               if ($this->sess_use_database === TRUE)\r
+               {\r
+                       // set cookie explicitly to only have our session data\r
+                       $cookie_data = array();\r
+                       foreach (array('session_id','ip_address','user_agent','last_activity') as $val)\r
+                       {\r
+                               $cookie_data[$val] = $this->userdata[$val];\r
+                       }\r
+                       \r
+                       $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));\r
+               }\r
+               \r
+               // Write the cookie\r
+               $this->_set_cookie($cookie_data);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Destroy the current session\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function sess_destroy()\r
+       {       \r
+               // Kill the session DB row\r
+               if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))\r
+               {\r
+                       $this->CI->db->where('session_id', $this->userdata['session_id']);\r
+                       $this->CI->db->delete($this->sess_table_name);\r
+               }\r
+       \r
+               // Kill the cookie\r
+               setcookie(\r
+                                       $this->sess_cookie_name,\r
+                                       addslashes(serialize(array())),\r
+                                       ($this->now - 31500000),\r
+                                       $this->cookie_path,\r
+                                       $this->cookie_domain,\r
+                                       0\r
+                               );\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a specific item from the session array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */             \r
+       function userdata($item)\r
+       {\r
+               return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch all session data\r
+        *\r
+        * @access      public\r
+        * @return      mixed\r
+        */     \r
+       function all_userdata()\r
+       {\r
+               return ( ! isset($this->userdata)) ? FALSE : $this->userdata;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Add or change data in the "userdata" array\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      void\r
+        */             \r
+       function set_userdata($newdata = array(), $newval = '')\r
+       {\r
+               if (is_string($newdata))\r
+               {\r
+                       $newdata = array($newdata => $newval);\r
+               }\r
+       \r
+               if (count($newdata) > 0)\r
+               {\r
+                       foreach ($newdata as $key => $val)\r
+                       {\r
+                               $this->userdata[$key] = $val;\r
+                       }\r
+               }\r
+\r
+               $this->sess_write();\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Delete a session variable from the "userdata" array\r
+        *\r
+        * @access      array\r
+        * @return      void\r
+        */             \r
+       function unset_userdata($newdata = array())\r
+       {\r
+               if (is_string($newdata))\r
+               {\r
+                       $newdata = array($newdata => '');\r
+               }\r
+       \r
+               if (count($newdata) > 0)\r
+               {\r
+                       foreach ($newdata as $key => $val)\r
+                       {\r
+                               unset($this->userdata[$key]);\r
+                       }\r
+               }\r
+       \r
+               $this->sess_write();\r
+       }\r
+       \r
+       // ------------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add or change flashdata, only available\r
+        * until the next request\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_flashdata($newdata = array(), $newval = '')\r
+       {\r
+               if (is_string($newdata))\r
+               {\r
+                       $newdata = array($newdata => $newval);\r
+               }\r
+               \r
+               if (count($newdata) > 0)\r
+               {\r
+                       foreach ($newdata as $key => $val)\r
+                       {\r
+                               $flashdata_key = $this->flashdata_key.':new:'.$key;\r
+                               $this->set_userdata($flashdata_key, $val);\r
+                       }\r
+               }\r
+       } \r
+       \r
+       // ------------------------------------------------------------------------\r
+\r
+       /**\r
+        * Keeps existing flashdata available to next request.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function keep_flashdata($key)\r
+       {\r
+               // 'old' flashdata gets removed.  Here we mark all \r
+               // flashdata as 'new' to preserve it from _flashdata_sweep()\r
+               // Note the function will return FALSE if the $key \r
+               // provided cannot be found\r
+               $old_flashdata_key = $this->flashdata_key.':old:'.$key;\r
+               $value = $this->userdata($old_flashdata_key);\r
+\r
+               $new_flashdata_key = $this->flashdata_key.':new:'.$key;\r
+               $this->set_userdata($new_flashdata_key, $value);\r
+       }\r
+       \r
+       // ------------------------------------------------------------------------\r
+\r
+       /**\r
+        * Fetch a specific flashdata item from the session array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function flashdata($key)\r
+       {\r
+               $flashdata_key = $this->flashdata_key.':old:'.$key;\r
+               return $this->userdata($flashdata_key);\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+\r
+       /**\r
+        * Identifies flashdata as 'old' for removal\r
+        * when _flashdata_sweep() runs.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _flashdata_mark()\r
+       {\r
+               $userdata = $this->all_userdata();\r
+               foreach ($userdata as $name => $value)\r
+               {\r
+                       $parts = explode(':new:', $name);\r
+                       if (is_array($parts) && count($parts) === 2)\r
+                       {\r
+                               $new_name = $this->flashdata_key.':old:'.$parts[1];\r
+                               $this->set_userdata($new_name, $value);\r
+                               $this->unset_userdata($name);\r
+                       }\r
+               }\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+\r
+       /**\r
+        * Removes all flashdata marked as 'old'\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+\r
+       function _flashdata_sweep()\r
+       {\r
+               $userdata = $this->all_userdata();\r
+               foreach ($userdata as $key => $value)\r
+               {\r
+                       if (strpos($key, ':old:'))\r
+                       {\r
+                               $this->unset_userdata($key);\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the "now" time\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _get_time()\r
+       {\r
+               if (strtolower($this->time_reference) == 'gmt')\r
+               {\r
+                       $now = time();\r
+                       $time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));\r
+               }\r
+               else\r
+               {\r
+                       $time = time();\r
+               }\r
+       \r
+               return $time;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Write the session cookie\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function _set_cookie($cookie_data = NULL)\r
+       {\r
+               if (is_null($cookie_data))\r
+               {\r
+                       $cookie_data = $this->userdata;\r
+               }\r
+       \r
+               // Serialize the userdata for the cookie\r
+               $cookie_data = $this->_serialize($cookie_data);\r
+               \r
+               if ($this->sess_encrypt_cookie == TRUE)\r
+               {\r
+                       $cookie_data = $this->CI->encrypt->encode($cookie_data);\r
+               }\r
+               else\r
+               {\r
+                       // if encryption is not used, we provide an md5 hash to prevent userside tampering\r
+                       $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);\r
+               }\r
+               \r
+               // Set the cookie\r
+               setcookie(\r
+                                       $this->sess_cookie_name,\r
+                                       $cookie_data,\r
+                                       $this->sess_expiration + time(),\r
+                                       $this->cookie_path,\r
+                                       $this->cookie_domain,\r
+                                       0\r
+                               );\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Serialize an array\r
+        *\r
+        * This function first converts any slashes found in the array to a temporary\r
+        * marker, so when it gets unserialized the slashes will be preserved\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      string\r
+        */     \r
+       function _serialize($data)\r
+       {\r
+               if (is_array($data))\r
+               {\r
+                       foreach ($data as $key => $val)\r
+                       {\r
+                               $data[$key] = str_replace('\\', '{{slash}}', $val);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $data = str_replace('\\', '{{slash}}', $data);\r
+               }\r
+               \r
+               return serialize($data);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Unserialize\r
+        *\r
+        * This function unserializes a data string, then converts any\r
+        * temporary slash markers back to actual slashes\r
+        *\r
+        * @access      private\r
+        * @param       array\r
+        * @return      string\r
+        */             \r
+       function _unserialize($data)\r
+       {\r
+               $data = @unserialize(strip_slashes($data));\r
+               \r
+               if (is_array($data))\r
+               {\r
+                       foreach ($data as $key => $val)\r
+                       {\r
+                               $data[$key] = str_replace('{{slash}}', '\\', $val);\r
+                       }\r
+                       \r
+                       return $data;\r
+               }\r
+               \r
+               return str_replace('{{slash}}', '\\', $data);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Garbage collection\r
+        *\r
+        * This deletes expired session rows from database\r
+        * if the probability percentage is met\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function _sess_gc()\r
+       {\r
+               if ($this->sess_use_database != TRUE)\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               srand(time());\r
+               if ((rand() % 100) < $this->gc_probability)\r
+               {\r
+                       $expire = $this->now - $this->sess_expiration;\r
+                       \r
+                       $this->CI->db->where("last_activity < {$expire}");\r
+                       $this->CI->db->delete($this->sess_table_name);\r
+\r
+                       log_message('debug', 'Session garbage collection performed.');\r
+               }\r
+       }\r
+\r
+       \r
+}\r
+// END Session Class\r
+\r
+/* End of file Session.php */\r
+/* Location: ./system/libraries/Session.php */
\ No newline at end of file
diff --git a/libraries/Sha1.php b/libraries/Sha1.php
new file mode 100644 (file)
index 0000000..282cdb2
--- /dev/null
@@ -0,0 +1,251 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * SHA1 Encoding Class\r
+ *\r
+ * Purpose: Provides 160 bit hashing using The Secure Hash Algorithm\r
+ * developed at the National Institute of Standards and Technology. The 40\r
+ * character SHA1 message hash is computationally infeasible to crack.\r
+ *\r
+ * This class is a fallback for servers that are not running PHP greater than\r
+ * 4.3, or do not have the MHASH library.\r
+ *\r
+ * This class is based on two scripts:\r
+ *\r
+ * Marcus Campbell's PHP implementation (GNU license)\r
+ * http://www.tecknik.net/sha-1/\r
+ *\r
+ * ...which is based on Paul Johnston's JavaScript version\r
+ * (BSD license). http://pajhome.org.uk/\r
+ *\r
+ * I encapsulated the functions and wrote one additional method to fix\r
+ * a hex conversion bug. - Rick Ellis\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Encryption\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/general/encryption.html\r
+ */\r
+class CI_SHA {\r
+\r
+       function CI_SHA()\r
+       {\r
+               log_message('debug', "SHA1 Class Initialized");\r
+       }\r
+\r
+       /**\r
+        * Generate the Hash\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function generate($str)\r
+       {\r
+               $n = ((strlen($str) + 8) >> 6) + 1;\r
+\r
+               for ($i = 0; $i < $n * 16; $i++)\r
+               {\r
+                       $x[$i] = 0;\r
+               }\r
+\r
+               for ($i = 0; $i < strlen($str); $i++)\r
+               {\r
+                       $x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);\r
+               }\r
+\r
+               $x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);\r
+\r
+               $x[$n * 16 - 1] = strlen($str) * 8;\r
+\r
+               $a =  1732584193;\r
+               $b = -271733879;\r
+               $c = -1732584194;\r
+               $d =  271733878;\r
+               $e = -1009589776;\r
+\r
+               for ($i = 0; $i < sizeof($x); $i += 16)\r
+               {\r
+                       $olda = $a;\r
+                       $oldb = $b;\r
+                       $oldc = $c;\r
+                       $oldd = $d;\r
+                       $olde = $e;\r
+\r
+                       for($j = 0; $j < 80; $j++)\r
+                       {\r
+                               if ($j < 16)\r
+                               {\r
+                                       $w[$j] = $x[$i + $j];\r
+                               }\r
+                               else\r
+                               {\r
+                                       $w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);\r
+                               }\r
+\r
+                               $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)));\r
+\r
+                               $e = $d;\r
+                               $d = $c;\r
+                               $c = $this->_rol($b, 30);\r
+                               $b = $a;\r
+                               $a = $t;\r
+                       }\r
+\r
+                       $a = $this->_safe_add($a, $olda);\r
+                       $b = $this->_safe_add($b, $oldb);\r
+                       $c = $this->_safe_add($c, $oldc);\r
+                       $d = $this->_safe_add($d, $oldd);\r
+                       $e = $this->_safe_add($e, $olde);\r
+               }\r
+\r
+               return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Convert a decimal to hex\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _hex($str)\r
+       {\r
+               $str = dechex($str);\r
+\r
+               if (strlen($str) == 7)\r
+               {\r
+                       $str = '0'.$str;\r
+               }\r
+\r
+               return $str;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        *  Return result based on iteration\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _ft($t, $b, $c, $d)\r
+       {\r
+               if ($t < 20)\r
+                       return ($b & $c) | ((~$b) & $d);\r
+               if ($t < 40)\r
+                       return $b ^ $c ^ $d;\r
+               if ($t < 60)\r
+                       return ($b & $c) | ($b & $d) | ($c & $d);\r
+\r
+               return $b ^ $c ^ $d;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Determine the additive constant\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _kt($t)\r
+       {\r
+               if ($t < 20)\r
+               {\r
+                       return 1518500249;\r
+               }\r
+               else if ($t < 40)\r
+               {\r
+                       return 1859775393;\r
+               }\r
+               else if ($t < 60)\r
+               {\r
+                       return -1894007588;\r
+               }\r
+               else\r
+               {\r
+                       return -899497514;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add integers, wrapping at 2^32\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _safe_add($x, $y)\r
+       {\r
+               $lsw = ($x & 0xFFFF) + ($y & 0xFFFF);\r
+               $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);\r
+\r
+               return ($msw << 16) | ($lsw & 0xFFFF);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Bitwise rotate a 32-bit number\r
+        *\r
+        * @access      private\r
+        * @return      integer\r
+        */     \r
+       function _rol($num, $cnt)\r
+       {\r
+               return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Pad string with zero\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _zero_fill($a, $b)\r
+       {\r
+               $bin = decbin($a);\r
+\r
+               if (strlen($bin) < $b)\r
+               {\r
+                       $bin = 0;\r
+               }\r
+               else\r
+               {\r
+                       $bin = substr($bin, 0, strlen($bin) - $b);\r
+               }\r
+\r
+               for ($i=0; $i < $b; $i++)\r
+               {\r
+                       $bin = "0".$bin;\r
+               }\r
+\r
+               return bindec($bin);\r
+       }\r
+}\r
+// END CI_SHA\r
+\r
+/* End of file Sha1.php */\r
+/* Location: ./system/libraries/Sha1.php */
\ No newline at end of file
diff --git a/libraries/Table.php b/libraries/Table.php
new file mode 100644 (file)
index 0000000..6940ece
--- /dev/null
@@ -0,0 +1,440 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.3.1\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * HTML Table Generating Class\r
+ *\r
+ * Lets you create tables manually or from database result objects, or arrays.\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   HTML Tables\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/uri.html\r
+ */\r
+class CI_Table {\r
+\r
+       var $rows                               = array();\r
+       var $heading                    = array();\r
+       var $auto_heading               = TRUE; \r
+       var $caption                    = NULL; \r
+       var $template                   = NULL;\r
+       var $newline                    = "\n";\r
+       var $empty_cells                = "";\r
+       \r
+       \r
+       function CI_Table()\r
+       {\r
+               log_message('debug', "Table Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set the template\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function set_template($template)\r
+       {\r
+               if ( ! is_array($template))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               $this->template = $template;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set the table heading\r
+        *\r
+        * Can be passed as an array or discreet params\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @return      void\r
+        */\r
+       function set_heading()\r
+       {\r
+               $args = func_get_args();\r
+               $this->heading = (is_array($args[0])) ? $args[0] : $args;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set columns.  Takes a one-dimensional array as input and creates\r
+        * a multi-dimensional array with a depth equal to the number of\r
+        * columns.  This allows a single array with many elements to  be\r
+        * displayed in a table that has a fixed column count.\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @param       int\r
+        * @return      void\r
+        */\r
+       function make_columns($array = array(), $col_limit = 0)\r
+       {\r
+               if ( ! is_array($array) OR count($array) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Turn off the auto-heading feature since it's doubtful we \r
+               // will want headings from a one-dimensional array\r
+               $this->auto_heading = FALSE;\r
+               \r
+               if ($col_limit == 0)\r
+               {\r
+                       return $array;\r
+               }\r
+       \r
+               $new = array();\r
+               while(count($array) > 0)\r
+               {       \r
+                       $temp = array_splice($array, 0, $col_limit);\r
+                       \r
+                       if (count($temp) < $col_limit)\r
+                       {\r
+                               for ($i = count($temp); $i < $col_limit; $i++)\r
+                               {\r
+                                       $temp[] = '&nbsp;';\r
+                               }\r
+                       }\r
+                       \r
+                       $new[] = $temp;\r
+               }\r
+               \r
+               return $new;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set "empty" cells\r
+        *\r
+        * Can be passed as an array or discreet params\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @return      void\r
+        */\r
+       function set_empty($value)\r
+       {\r
+               $this->empty_cells = $value;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add a table row\r
+        *\r
+        * Can be passed as an array or discreet params\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @return      void\r
+        */\r
+       function add_row()\r
+       {\r
+               $args = func_get_args();\r
+               $this->rows[] = (is_array($args[0])) ? $args[0] : $args;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add a table caption\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_caption($caption)\r
+       {\r
+               $this->caption = $caption;\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate the table\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @return      string\r
+        */\r
+       function generate($table_data = NULL)\r
+       {\r
+               // The table data can optionally be passed to this function\r
+               // either as a database result object or an array\r
+               if ( ! is_null($table_data))\r
+               {\r
+                       if (is_object($table_data))\r
+                       {\r
+                               $this->_set_from_object($table_data);\r
+                       }\r
+                       elseif (is_array($table_data))\r
+                       {\r
+                               $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;\r
+                               $this->_set_from_array($table_data, $set_heading);\r
+                       }\r
+               }\r
+       \r
+               // Is there anything to display?  No?  Smite them!\r
+               if (count($this->heading) == 0 AND count($this->rows) == 0)\r
+               {\r
+                       return 'Undefined table data';\r
+               }\r
+       \r
+               // Compile and validate the template date\r
+               $this->_compile_template();\r
+       \r
+       \r
+               // Build the table!\r
+               \r
+               $out = $this->template['table_open'];\r
+               $out .= $this->newline;         \r
+\r
+               // Add any caption here\r
+               if ($this->caption)\r
+               {\r
+                       $out .= $this->newline;\r
+                       $out .= '<caption>' . $this->caption . '</caption>';\r
+                       $out .= $this->newline;\r
+               }\r
+\r
+               // Is there a table heading to display?\r
+               if (count($this->heading) > 0)\r
+               {\r
+                       $out .= $this->template['heading_row_start'];\r
+                       $out .= $this->newline;         \r
+\r
+                       foreach($this->heading as $heading)\r
+                       {\r
+                               $out .= $this->template['heading_cell_start'];\r
+                               $out .= $heading;\r
+                               $out .= $this->template['heading_cell_end'];\r
+                       }\r
+\r
+                       $out .= $this->template['heading_row_end'];\r
+                       $out .= $this->newline;                         \r
+               }\r
+\r
+               // Build the table rows\r
+               if (count($this->rows) > 0)\r
+               {\r
+                       $i = 1;\r
+                       foreach($this->rows as $row)\r
+                       {\r
+                               if ( ! is_array($row))\r
+                               {\r
+                                       break;\r
+                               }\r
+                       \r
+                               // We use modulus to alternate the row colors\r
+                               $name = (fmod($i++, 2)) ? '' : 'alt_';\r
+                       \r
+                               $out .= $this->template['row_'.$name.'start'];\r
+                               $out .= $this->newline;         \r
+       \r
+                               foreach($row as $cell)\r
+                               {\r
+                                       $out .= $this->template['cell_'.$name.'start'];\r
+                                       \r
+                                       if ($cell === "")\r
+                                       {\r
+                                               $out .= $this->empty_cells;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $out .= $cell;\r
+                                       }\r
+                                       \r
+                                       $out .= $this->template['cell_'.$name.'end'];\r
+                               }\r
+       \r
+                               $out .= $this->template['row_'.$name.'end'];\r
+                               $out .= $this->newline; \r
+                       }\r
+               }\r
+\r
+               $out .= $this->template['table_close'];\r
+       \r
+               return $out;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Clears the table arrays.  Useful if multiple tables are being generated\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */\r
+       function clear()\r
+       {\r
+               $this->rows                             = array();\r
+               $this->heading                  = array();\r
+               $this->auto_heading             = TRUE; \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set table data from a database result object\r
+        *\r
+        * @access      public\r
+        * @param       object\r
+        * @return      void\r
+        */\r
+       function _set_from_object($query)\r
+       {\r
+               if ( ! is_object($query))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // First generate the headings from the table column names\r
+               if (count($this->heading) == 0)\r
+               {\r
+                       if ( ! method_exists($query, 'list_fields'))\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       $this->heading = $query->list_fields();\r
+               }\r
+                               \r
+               // Next blast through the result array and build out the rows\r
+               \r
+               if ($query->num_rows() > 0)\r
+               {\r
+                       foreach ($query->result_array() as $row)\r
+                       {\r
+                               $this->rows[] = $row;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Set table data from an array\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */\r
+       function _set_from_array($data, $set_heading = TRUE)\r
+       {\r
+               if ( ! is_array($data) OR count($data) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $i = 0;\r
+               foreach ($data as $row)\r
+               {\r
+                       if ( ! is_array($row))\r
+                       {\r
+                               $this->rows[] = $data;\r
+                               break;\r
+                       }\r
+                                               \r
+                       // If a heading hasn't already been set we'll use the first row of the array as the heading\r
+                       if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE)\r
+                       {\r
+                               $this->heading = $row;\r
+                       }\r
+                       else\r
+                       {\r
+                               $this->rows[] = $row;\r
+                       }\r
+                       \r
+                       $i++;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Compile Template\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _compile_template()\r
+       {       \r
+               if ($this->template == NULL)\r
+               {\r
+                       $this->template = $this->_default_template();\r
+                       return;\r
+               }\r
+               \r
+               $this->temp = $this->_default_template();\r
+               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)\r
+               {\r
+                       if ( ! isset($this->template[$val]))\r
+                       {\r
+                               $this->template[$val] = $this->temp[$val];\r
+                       }\r
+               }       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Default Template\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _default_template()\r
+       {\r
+               return  array (\r
+                                               'table_open'                    => '<table border="0" cellpadding="4" cellspacing="0">',\r
+\r
+                                               'heading_row_start'     => '<tr>',\r
+                                               'heading_row_end'               => '</tr>',\r
+                                               'heading_cell_start'    => '<th>',\r
+                                               'heading_cell_end'              => '</th>',\r
+\r
+                                               'row_start'                     => '<tr>',\r
+                                               'row_end'                               => '</tr>',\r
+                                               'cell_start'                    => '<td>',\r
+                                               'cell_end'                              => '</td>',\r
+\r
+                                               'row_alt_start'                 => '<tr>',\r
+                                               'row_alt_end'                   => '</tr>',\r
+                                               'cell_alt_start'                => '<td>',\r
+                                               'cell_alt_end'                  => '</td>',\r
+\r
+                                               'table_close'                   => '</table>'\r
+                                       );      \r
+       }\r
+       \r
+\r
+}\r
+\r
+\r
+/* End of file Table.php */\r
+/* Location: ./system/libraries/Table.php */
\ No newline at end of file
diff --git a/libraries/Trackback.php b/libraries/Trackback.php
new file mode 100644 (file)
index 0000000..9988492
--- /dev/null
@@ -0,0 +1,550 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Trackback Class\r
+ *\r
+ * Trackback Sending/Receiving Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Trackbacks\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/trackback.html\r
+ */\r
+class CI_Trackback {\r
+               \r
+       var $time_format        = 'local';\r
+       var $charset            = 'UTF-8';\r
+       var $data                       = array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => '');\r
+       var $convert_ascii      = TRUE;\r
+       var $response           = '';\r
+       var $error_msg          = array();\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Trackback()\r
+       {\r
+               log_message('debug', "Trackback Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Send Trackback\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      bool\r
+        */     \r
+       function send($tb_data)\r
+       {               \r
+               if ( ! is_array($tb_data))\r
+               {\r
+                       $this->set_error('The send() method must be passed an array');\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Pre-process the Trackback Data\r
+               foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item)\r
+               {\r
+                       if ( ! isset($tb_data[$item]))\r
+                       {\r
+                               $this->set_error('Required item missing: '.$item);\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       switch ($item)\r
+                       {\r
+                               case 'ping_url' : $$item = $this->extract_urls($tb_data[$item]);\r
+                                       break;\r
+                               case 'excerpt'  : $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));\r
+                                       break;\r
+                               case 'url'              : $$item = str_replace('&#45;', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));\r
+                                       break;\r
+                               default                 : $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item])));\r
+                                       break;\r
+                       }\r
+\r
+                       // Convert High ASCII Characters\r
+                       if ($this->convert_ascii == TRUE)\r
+                       {\r
+                               if ($item == 'excerpt')\r
+                               {\r
+                                       $$item = $this->convert_ascii($$item);\r
+                               }\r
+                               elseif ($item == 'title')\r
+                               {\r
+                                       $$item = $this->convert_ascii($$item);\r
+                               }\r
+                               elseif($item == 'blog_name')\r
+                               {\r
+                                       $$item = $this->convert_ascii($$item);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Build the Trackback data string\r
+               $charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];\r
+               \r
+               $data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);\r
+                               \r
+               // Send Trackback(s)\r
+               $return = TRUE;\r
+               if (count($ping_url) > 0)\r
+               {\r
+                       foreach ($ping_url as $url)\r
+                       {\r
+                               if ($this->process($url, $data) == FALSE)\r
+                               {\r
+                                       $return = FALSE;\r
+                               }\r
+                       }       \r
+               }\r
+\r
+               return $return;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Receive Trackback  Data\r
+        *\r
+        * This function simply validates the incoming TB data.\r
+        * It returns false on failure and true on success.\r
+        * If the data is valid it is set to the $this->data array\r
+        * so that it can be inserted into a database.\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function receive()\r
+       {                                       \r
+               foreach (array('url', 'title', 'blog_name', 'excerpt') as $val)\r
+               {\r
+                       if ( ! isset($_POST[$val]) OR $_POST[$val] == '')\r
+                       {\r
+                               $this->set_error('The following required POST variable is missing: '.$val);\r
+                               return FALSE;\r
+                       }\r
+                       \r
+                       $this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));\r
+       \r
+                       if ($val != 'url' && function_exists('mb_convert_encoding'))\r
+                       {\r
+                               $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);\r
+                       }\r
+                       \r
+                       $_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);\r
+                       \r
+                       if ($val == 'excerpt')\r
+                       {\r
+                               $_POST['excerpt'] = $this->limit_characters($_POST['excerpt']);\r
+                       }\r
+                       \r
+                       $this->data[$val] = $_POST[$val];\r
+               }\r
+\r
+               return TRUE;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Send Trackback Error Message\r
+        *\r
+        * Allows custom errors to be set.  By default it\r
+        * sends the "incomplete information" error, as that's\r
+        * the most common one.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function send_error($message = 'Incomplete Information')\r
+       {\r
+               echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";\r
+               exit;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Send Trackback Success Message\r
+        *\r
+        * This should be called when a trackback has been\r
+        * successfully received and inserted.\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function send_success()\r
+       {\r
+               echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";\r
+               exit;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a particular item\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function data($item)\r
+       {\r
+               return ( ! isset($this->data[$item])) ? '' : $this->data[$item];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Process Trackback\r
+        *\r
+        * Opens a socket connection and passes the data to\r
+        * the server.  Returns true on success, false on failure\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function process($url, $data)\r
+       {\r
+               $target = parse_url($url);\r
+       \r
+               // Open the socket\r
+               if ( ! $fp = @fsockopen($target['host'], 80))\r
+               {\r
+                       $this->set_error('Invalid Connection: '.$url);\r
+                       return FALSE;\r
+               }\r
+\r
+               // Build the path\r
+               $ppath = ( ! isset($target['path'])) ? $url : $target['path'];\r
+               \r
+               $path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;\r
+\r
+               // Add the Trackback ID to the data string\r
+               if ($id = $this->get_id($url))\r
+               {\r
+                       $data = "tb_id=".$id."&".$data;\r
+               }\r
+\r
+               // Transfer the data\r
+               fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );\r
+               fputs ($fp, "Host: " . $target['host'] . "\r\n" );\r
+               fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );\r
+               fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );\r
+               fputs ($fp, "Connection: close\r\n\r\n" );\r
+               fputs ($fp, $data);\r
+\r
+               // Was it successful?\r
+               $this->response = "";\r
+               \r
+               while( ! feof($fp))\r
+               {\r
+                       $this->response .= fgets($fp, 128);\r
+               }\r
+               @fclose($fp);\r
+               \r
+               if ( ! eregi("<error>0</error>", $this->response))\r
+               {\r
+                       $message = 'An unknown error was encountered';\r
+                       \r
+                       if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))\r
+                       {\r
+                               $message = trim($match['1']);\r
+                       }\r
+                       \r
+                       $this->set_error($message);\r
+                       return FALSE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Extract Trackback URLs\r
+        *\r
+        * This function lets multiple trackbacks be sent.\r
+        * It takes a string of URLs (separated by comma or\r
+        * space) and puts each URL into an array\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function extract_urls($urls)\r
+       {               \r
+               // Remove the pesky white space and replace with a comma.\r
+               $urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);\r
+               \r
+               // If they use commas get rid of the doubles.\r
+               $urls = str_replace(",,", ",", $urls);\r
+               \r
+               // Remove any comma that might be at the end\r
+               if (substr($urls, -1) == ",")\r
+               {\r
+                       $urls = substr($urls, 0, -1);\r
+               }\r
+                               \r
+               // Break into an array via commas\r
+               $urls = preg_split('/[,]/', $urls);\r
+               \r
+               // Removes duplicates\r
+               $urls = array_unique($urls);\r
+               \r
+               array_walk($urls, array($this, 'validate_url'));\r
+               \r
+               return $urls;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validate URL\r
+        *\r
+        * Simply adds "http://" if missing\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function validate_url($url)\r
+       {\r
+               $url = trim($url);\r
+\r
+               if (substr($url, 0, 4) != "http")\r
+               {\r
+                       $url = "http://".$url;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Find the Trackback URL's ID\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function get_id($url)\r
+       {       \r
+               $tb_id = "";\r
+               \r
+               if (strstr($url, '?'))\r
+               {\r
+                       $tb_array = explode('/', $url);\r
+                       $tb_end   = $tb_array[count($tb_array)-1];\r
+                       \r
+                       if ( ! is_numeric($tb_end))\r
+                       {\r
+                               $tb_end  = $tb_array[count($tb_array)-2];\r
+                       }\r
+                       \r
+                       $tb_array = explode('=', $tb_end);\r
+                       $tb_id  = $tb_array[count($tb_array)-1];\r
+               }\r
+               else\r
+               {\r
+                       if (ereg("/$", $url))\r
+                       {\r
+                               $url = substr($url, 0, -1);\r
+                       }\r
+                               \r
+                       $tb_array = explode('/', $url);\r
+                       $tb_id  = $tb_array[count($tb_array)-1];\r
+                       \r
+                       if ( ! is_numeric($tb_id))\r
+                       {\r
+                               $tb_id  = $tb_array[count($tb_array)-2];\r
+                       }\r
+               }       \r
+                               \r
+               if ( ! preg_match ("/^([0-9]+)$/", $tb_id))\r
+               {\r
+                       return false;\r
+               }\r
+               else\r
+               {\r
+                       return $tb_id;\r
+               }               \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Convert Reserved XML characters to Entities\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function convert_xml($str)\r
+       {\r
+               $temp = '__TEMP_AMPERSANDS__';\r
+               \r
+               $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);\r
+               $str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);\r
+               \r
+               $str = str_replace(array("&","<",">","\"", "'", "-"),\r
+                                                  array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),\r
+                                                  $str);\r
+                       \r
+               $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);\r
+               $str = preg_replace("/$temp(\w+);/","&\\1;", $str);\r
+                       \r
+               return $str;\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Character limiter\r
+        *\r
+        * Limits the string based on the character count. Will preserve complete words.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       integer\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function limit_characters($str, $n = 500, $end_char = '&#8230;')\r
+       {\r
+               if (strlen($str) < $n)\r
+               {\r
+                       return $str;\r
+               }\r
+\r
+               $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));\r
+       \r
+               if (strlen($str) <= $n)\r
+               {\r
+                       return $str;\r
+               }\r
+                                                                               \r
+               $out = "";\r
+               foreach (explode(' ', trim($str)) as $val)\r
+               {\r
+                       $out .= $val.' ';                       \r
+                       if (strlen($out) >= $n)\r
+                       {\r
+                               return trim($out).$end_char;\r
+                       }               \r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * High ASCII to Entities\r
+        *\r
+        * Converts Hight ascii text and MS Word special chars\r
+        * to character entities\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function convert_ascii($str)\r
+       {\r
+          $count       = 1;\r
+          $out = '';\r
+          $temp        = array();\r
+               \r
+          for ($i = 0, $s = strlen($str); $i < $s; $i++)\r
+          {\r
+                  $ordinal = ord($str[$i]);\r
+               \r
+                  if ($ordinal < 128)\r
+                  {\r
+                          $out .= $str[$i];                    \r
+                  }\r
+                  else\r
+                  {\r
+                          if (count($temp) == 0)\r
+                          {\r
+                                  $count = ($ordinal < 224) ? 2 : 3;\r
+                          }\r
+                       \r
+                          $temp[] = $ordinal;\r
+                       \r
+                          if (count($temp) == $count)\r
+                          {\r
+                                  $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);\r
+       \r
+                                  $out .= '&#'.$number.';';\r
+                                  $count = 1;\r
+                                  $temp = array();\r
+                          }\r
+                  }\r
+          }\r
+       \r
+          return $out;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_error($msg)\r
+       {\r
+               log_message('error', $msg);\r
+               $this->error_msg[] = $msg;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Show error messages\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function display_errors($open = '<p>', $close = '</p>')\r
+       {       \r
+               $str = '';\r
+               foreach ($this->error_msg as $val)\r
+               {\r
+                       $str .= $open.$val.$close;\r
+               }\r
+       \r
+               return $str;\r
+       }\r
+\r
+}\r
+// END Trackback Class\r
+\r
+/* End of file Trackback.php */\r
+/* Location: ./system/libraries/Trackback.php */
\ No newline at end of file
diff --git a/libraries/Typography.php b/libraries/Typography.php
new file mode 100644 (file)
index 0000000..0ee6a24
--- /dev/null
@@ -0,0 +1,342 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package            CodeIgniter
+ * @author             ExpressionEngine Dev Team
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.
+ * @license            http://codeigniter.com/user_guide/license.html
+ * @link               http://codeigniter.com
+ * @since              Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Typography Class
+ *
+ *
+ * @access             private
+ * @category   Helpers
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/helpers/
+ */
+class CI_Typography {
+
+       // Block level elements that should not be wrapped inside <p> tags
+       var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul';
+       
+       // Elements that should not have <p> and <br /> tags within them.
+       var $skip_elements      = 'p|pre|ol|ul|dl|object|table';
+       
+       // Tags we want the parser to completely ignore when splitting the string.
+       var $inline_elements = 'a|abbr|acronym|b|bdo|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|samp|select|span|strong|sub|sup|textarea|var';
+
+       // whether or not to protect quotes within { curly braces }
+       var $protect_braced_quotes = FALSE;
+       
+       /**
+        * Nothing to do here...
+        *
+        */
+       function CI_Typography()
+       {
+       }
+
+       /**
+        * Auto Typography
+        *
+        * This function converts text, making it typographically correct:
+        *      - Converts double spaces into paragraphs.
+        *      - Converts single line breaks into <br /> tags
+        *      - Converts single and double quotes into correctly facing curly quote entities.
+        *      - Converts three dots into ellipsis.
+        *      - Converts double dashes into em-dashes.
+        *  - Converts two spaces into entities
+        *
+        * @access      public
+        * @param       string
+        * @param       bool    whether to strip javascript event handlers for security
+        * @param       bool    whether to reduce more then two consecutive newlines to two
+        * @return      string
+        */
+       function auto_typography($str, $strip_js_event_handlers = TRUE, $reduce_linebreaks = FALSE)
+       {
+               if ($str == '')
+               {
+                       return '';
+               }
+
+               // Standardize Newlines to make matching easier
+               if (strpos($str, "\r") !== FALSE)
+               {
+                       $str = str_replace(array("\r\n", "\r"), "\n", $str);                    
+               }
+                       
+               // Reduce line breaks.  If there are more than two consecutive linebreaks
+               // we'll compress them down to a maximum of two since there's no benefit to more.
+               if ($reduce_linebreaks === TRUE)
+               {
+                       $str = preg_replace("/\n\n+/", "\n\n", $str);
+               }
+               
+                // Do we allow JavaScript event handlers? If not, we strip them from within all tags
+               if ($strip_js_event_handlers === TRUE)
+               {
+                       $str = preg_replace("#<([^><]+?)([^a-z_\-]on\w*|xmlns)(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str);
+               }       
+
+               // Convert quotes within tags to temporary markers. 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);
+                       }
+               }
+
+               if ($this->protect_braced_quotes === TRUE)
+               {
+                       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);
+                               }
+                       }                       
+               }
+                       
+               // 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 bracket < temporarily to: {@TAG}
+               $str = preg_replace("#<(/*)(".$this->inline_elements.")([ >])#i", "{@TAG}\\1\\2\\3", $str);
+
+               // Split the string at every tag.  This expression creates an array with this prototype:
+               // 
+               //      [array]
+               //      {
+               //              [0] = <opening tag>
+               //              [1] = Content...
+               //              [2] = <closing tag>
+               //              Etc...
+               //      }       
+               $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
+               
+               // Build our finalized string.  We cycle through the array, skipping tags, and processing the contained text    
+               $str = '';
+               $process = TRUE;
+               $paragraph = FALSE;
+               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 <pre> 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 <p> and <br /> tags
+                       $str .= $this->_format_newlines($chunk);
+               }
+
+               // is the whole of the content inside a block level element?
+               if ( ! preg_match("/^<(?:".$this->block_elements.")/i", $str, $match))
+               {
+                       $str = "<p>{$str}</p>";
+               }
+
+               // Convert quotes, elipsis, and em-dashes
+               $str = $this->format_characters($str);
+       
+               // Final clean up
+               $table = array(
+               
+                                               // If the user submitted their own paragraph tags within the text
+                                               // we will retain them instead of using our tags.
+                                               '/(<p.*?>)<p>/'         => '$1', // <?php BBEdit syntax coloring bug fix
+                                               
+                                               // Reduce multiple instances of opening/closing paragraph tags to a single one
+                                               '#(</p>)+#'                     => '</p>',
+                                               '/(<p><p>)+/'           => '<p>',
+                                               
+                                               // Clean up stray paragraph tags that appear before block level elements
+                                               '#<p></p><('.$this->block_elements.')#' => '<$1',
+                       
+                                               // Replace the temporary markers we added earlier
+                                               '/\{@TAG\}/'            => '<',
+                                               '/\{@DQ\}/'                     => '"',
+                                               '/\{@SQ\}/'                     => "'"
+
+                                               );
+       
+               // Do we need to reduce empty lines?
+               if ($reduce_linebreaks === TRUE)
+               {
+                       $table['#<p>\n*</p>#'] = '';
+               }
+               else
+               {
+                       // If we have empty paragraph tags we add a non-breaking space
+                       // otherwise most browsers won't treat them as true paragraphs
+                       $table['#<p></p>#'] = '<p>&nbsp;</p>';
+               }
+       
+               return preg_replace(array_keys($table), $table, $str);
+
+       }
+       
+       // --------------------------------------------------------------------
+
+       /**
+        * Format Characters
+        *
+        * This function mainly converts double and single quotes
+        * to curly entities, but it also converts em-dashes,
+        * double spaces, and ampersands
+        *
+        * @access      public
+        * @param       string
+        * @return      string
+        */
+       function format_characters($str)
+       {
+               static $table;
+               
+               if ( ! isset($table))
+               {
+               $table = array(                                 
+                                                       // nested smart quotes, opening and closing
+                                                       // note that rules for grammar (English) allow only for two levels deep
+                                                       // and that single quotes are _supposed_ to always be on the outside
+                                                       // but we'll accommodate both
+                                                       '/(^|\W|\s)\'"/'                                => '$1&#8216;&#8220;',
+                                                       '/\'"(\s|\W|$)/'                                => '&#8217;&#8221;$1',
+                                                       '/(^|\W|\s)"\'/'                                => '$1&#8220;&#8216;',
+                                                       '/"\'(\s|\W|$)/'                                => '&#8221;&#8217;$1',
+
+                                                       // single quote smart quotes
+                                                       '/\'(\s|\W|$)/'                                 => '&#8217;$1',
+                                                       '/(^|\W|\s)\'/'                                 => '$1&#8216;',
+
+                                                       // double quote smart quotes
+                                                       '/"(\s|\W|$)/'                                  => '&#8221;$1',
+                                                       '/(^|\W|\s)"/'                                  => '$1&#8220;',
+
+                                                       // apostrophes
+                                                       "/(\w)'(\w)/"                   => '$1&#8217;$2',
+
+                                                       // Em dash and ellipses dots
+                                                       '/\s?\-\-\s?/'                                  => '&#8212;',
+                                                       '/(\w)\.{3}/'                                   => '$1&#8230;',
+
+                                                       // double space after sentences
+                                                       '/(\W)  /'                                              => '$1&nbsp; ',
+
+                                                       // ampersands, if not a character entity
+                                                       '/&(?!#?[a-zA-Z0-9]{2,};)/'             => '&amp;'
+                                       );                      
+               }       
+
+               return preg_replace(array_keys($table), $table, $str);
+       }
+       
+       // --------------------------------------------------------------------
+
+       /**
+        * Format Newlines
+        *
+        * Converts newline characters into either <p> tags or <br />
+        *
+        * @access      public
+        * @param       string
+        * @return      string
+        */     
+       function _format_newlines($str)
+       {
+               if ($str == '')
+               {
+                       return $str;
+               }
+
+               if (strpos($str, "\n") === FALSE)
+               {
+                       return $str;
+               }
+               
+               // Convert two consecutive newlines to paragraphs
+               $str = str_replace("\n\n", "</p>\n\n<p>", $str);
+               
+               // Convert single spaces to <br /> tags
+               $str = preg_replace("/([^\n])(\n)([^\n])/", "\\1<br />\\2\\3", $str);
+               
+               // Wrap the whole enchilada in enclosing paragraphs
+               if ($str != "\n")
+               {
+                       $str =  '<p>'.$str.'</p>';
+               }
+
+               // Remove empty paragraphs if they are on the first line, as this
+               // is a potential unintended consequence of the previous code
+               $str = preg_replace("/<p><\/p>(.*)/", "\\1", $str, 1);
+               
+               return $str;
+       }
+       
+       // ------------------------------------------------------------------------
+       
+       /**
+        * Convert newlines to HTML line breaks except within PRE tags
+        *
+        * @access      public
+        * @param       string
+        * @return      string
+        */             
+       function nl2br_except_pre($str)
+       {
+               $ex = explode("pre>",$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;
+       }
+       
+}
+// END Typography Class
+
+/* End of file Typography.php */
+/* Location: ./system/libraries/Typography.php */
\ No newline at end of file
diff --git a/libraries/URI.php b/libraries/URI.php
new file mode 100644 (file)
index 0000000..0e4ff50
--- /dev/null
@@ -0,0 +1,584 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * URI Class\r
+ *\r
+ * Parses URIs and determines routing\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   URI\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/uri.html\r
+ */\r
+class CI_URI {\r
+\r
+       var     $keyval = array();\r
+       var $uri_string;\r
+       var $segments           = array();\r
+       var $rsegments          = array();\r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        * Simply globalizes the $RTR object.  The front\r
+        * loads the Router class early on so it's not available\r
+        * normally as other classes are.\r
+        *\r
+        * @access      public\r
+        */             \r
+       function CI_URI()\r
+       {\r
+               $this->config =& load_class('Config');\r
+               log_message('debug', "URI Class Initialized");\r
+       }\r
+       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the URI String\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _fetch_uri_string()\r
+       {\r
+               if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')\r
+               {\r
+                       // If the URL has a question mark then it's simplest to just\r
+                       // build the URI string from the zero index of the $_GET array.\r
+                       // This avoids having to deal with $_SERVER variables, which\r
+                       // can be unreliable in some environments\r
+                       if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')\r
+                       {\r
+                               $this->uri_string = key($_GET);\r
+                               return;\r
+                       }\r
+               \r
+                       // Is there a PATH_INFO variable?\r
+                       // Note: some servers seem to have trouble with getenv() so we'll test it two ways              \r
+                       $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');                  \r
+                       if (trim($path, '/') != '' && $path != "/".SELF)\r
+                       {\r
+                               $this->uri_string = $path;\r
+                               return;\r
+                       }\r
+                                       \r
+                       // No PATH_INFO?... What about QUERY_STRING?\r
+                       $path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');        \r
+                       if (trim($path, '/') != '')\r
+                       {\r
+                               $this->uri_string = $path;\r
+                               return;\r
+                       }\r
+                       \r
+                       // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?\r
+                       $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');   \r
+                       if (trim($path, '/') != '' && $path != "/".SELF)\r
+                       {\r
+                               // remove path and script information so we have good URI data\r
+                               $this->uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $path);\r
+                               return;\r
+                       }\r
+\r
+                       // We've exhausted all our options...\r
+                       $this->uri_string = '';\r
+               }\r
+               else\r
+               {\r
+                       $uri = strtoupper($this->config->item('uri_protocol'));\r
+                       \r
+                       if ($uri == 'REQUEST_URI')\r
+                       {\r
+                               $this->uri_string = $this->_parse_request_uri();\r
+                               return;\r
+                       }\r
+                       \r
+                       $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);\r
+               }\r
+               \r
+               // If the URI contains only a slash we'll kill it\r
+               if ($this->uri_string == '/')\r
+               {\r
+                       $this->uri_string = '';\r
+               }               \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Parse the REQUEST_URI\r
+        *\r
+        * Due to the way REQUEST_URI works it usually contains path info\r
+        * that makes it unusable as URI data.  We'll trim off the unnecessary\r
+        * data, hopefully arriving at a valid URI that we can use.\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */     \r
+       function _parse_request_uri()\r
+       {\r
+               if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));\r
+\r
+               if ($request_uri == '' OR $request_uri == SELF)\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               $fc_path = FCPATH;              \r
+               if (strpos($request_uri, '?') !== FALSE)\r
+               {\r
+                       $fc_path .= '?';\r
+               }\r
+               \r
+               $parsed_uri = explode("/", $request_uri);\r
+                               \r
+               $i = 0;\r
+               foreach(explode("/", $fc_path) as $segment)\r
+               {\r
+                       if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])\r
+                       {\r
+                               $i++;\r
+                       }\r
+               }\r
+               \r
+               $parsed_uri = implode("/", array_slice($parsed_uri, $i));\r
+               \r
+               if ($parsed_uri != '')\r
+               {\r
+                       $parsed_uri = '/'.$parsed_uri;\r
+               }\r
+\r
+               return $parsed_uri;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Filter segments for malicious characters\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function _filter_uri($str)\r
+       {\r
+               if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)\r
+               {\r
+                       if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str))\r
+                       {\r
+                               exit('The URI you submitted has disallowed characters.');\r
+                       }\r
+               }       \r
+               \r
+               // Convert programatic characters to entities\r
+               $bad    = array('$',            '(',            ')',            '%28',          '%29');\r
+               $good   = array('&#36;',        '&#40;',        '&#41;',        '&#40;',        '&#41;');\r
+               \r
+               return str_replace($bad, $good, $str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Remove the suffix from the URL if needed\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _remove_url_suffix()\r
+       {\r
+               if  ($this->config->item('url_suffix') != "")\r
+               {\r
+                       $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Explode the URI Segments. The individual segments will\r
+        * be stored in the $this->segments array.      \r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */             \r
+       function _explode_segments()\r
+       {\r
+               foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)\r
+               {\r
+                       // Filter segments for security\r
+                       $val = trim($this->_filter_uri($val));\r
+                       \r
+                       if ($val != '')\r
+                       {\r
+                               $this->segments[] = $val;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // -------------------------------------------------------------------- \r
+       /**\r
+        * Re-index Segments\r
+        *\r
+        * This function re-indexes the $this->segment array so that it\r
+        * starts at 1 rather than 0.  Doing so makes it simpler to\r
+        * use functions like $this->uri->segment(n) since there is\r
+        * a 1:1 relationship between the segment array and the actual segments.\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */     \r
+       function _reindex_segments()\r
+       {\r
+               array_unshift($this->segments, NULL);\r
+               array_unshift($this->rsegments, NULL);\r
+               unset($this->segments[0]);\r
+               unset($this->rsegments[0]);\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a URI Segment\r
+        *\r
+        * This function returns the URI segment based on the number provided.\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function segment($n, $no_result = FALSE)\r
+       {\r
+               return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a URI "routed" Segment\r
+        *\r
+        * This function returns the re-routed URI segment (assuming routing rules are used)\r
+        * based on the number provided.  If there is no routing this function returns the\r
+        * same result as $this->segment()\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @param       bool\r
+        * @return      string\r
+        */\r
+       function rsegment($n, $no_result = FALSE)\r
+       {\r
+               return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate a key value pair from the URI string\r
+        *\r
+        * This function generates and associative array of URI data starting\r
+        * at the supplied segment. For example, if this is your URI:\r
+        *\r
+        *      example.com/user/search/name/joe/location/UK/gender/male\r
+        *\r
+        * You can use this function to generate an array with this prototype:\r
+        *\r
+        * array (\r
+        *                      name => joe\r
+        *                      location => UK\r
+        *                      gender => male\r
+        *               )\r
+        *\r
+        * @access      public\r
+        * @param       integer the starting segment number\r
+        * @param       array   an array of default values\r
+        * @return      array\r
+        */\r
+       function uri_to_assoc($n = 3, $default = array())\r
+       {\r
+               return $this->_uri_to_assoc($n, $default, 'segment');\r
+       }\r
+       /**\r
+        * Identical to above only it uses the re-routed segment array\r
+        *\r
+        */\r
+       function ruri_to_assoc($n = 3, $default = array())\r
+       {\r
+               return $this->_uri_to_assoc($n, $default, 'rsegment');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate a key value pair from the URI string or Re-routed URI string\r
+        *\r
+        * @access      private\r
+        * @param       integer the starting segment number\r
+        * @param       array   an array of default values\r
+        * @param       string  which array we should use\r
+        * @return      array\r
+        */\r
+       function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')\r
+       {\r
+               if ($which == 'segment')\r
+               {\r
+                       $total_segments = 'total_segments';\r
+                       $segment_array = 'segment_array';\r
+               }\r
+               else\r
+               {\r
+                       $total_segments = 'total_rsegments';\r
+                       $segment_array = 'rsegment_array';\r
+               }\r
+               \r
+               if ( ! is_numeric($n))\r
+               {\r
+                       return $default;\r
+               }\r
+       \r
+               if (isset($this->keyval[$n]))\r
+               {\r
+                       return $this->keyval[$n];\r
+               }\r
+       \r
+               if ($this->$total_segments() < $n)\r
+               {\r
+                       if (count($default) == 0)\r
+                       {\r
+                               return array();\r
+                       }\r
+                       \r
+                       $retval = array();\r
+                       foreach ($default as $val)\r
+                       {\r
+                               $retval[$val] = FALSE;\r
+                       }               \r
+                       return $retval;\r
+               }\r
+\r
+               $segments = array_slice($this->$segment_array(), ($n - 1));\r
+\r
+               $i = 0;\r
+               $lastval = '';\r
+               $retval  = array();\r
+               foreach ($segments as $seg)\r
+               {\r
+                       if ($i % 2)\r
+                       {\r
+                               $retval[$lastval] = $seg;\r
+                       }\r
+                       else\r
+                       {\r
+                               $retval[$seg] = FALSE;\r
+                               $lastval = $seg;\r
+                       }\r
+               \r
+                       $i++;\r
+               }\r
+\r
+               if (count($default) > 0)\r
+               {\r
+                       foreach ($default as $val)\r
+                       {\r
+                               if ( ! array_key_exists($val, $retval))\r
+                               {\r
+                                       $retval[$val] = FALSE;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Cache the array for reuse\r
+               $this->keyval[$n] = $retval;\r
+               return $retval;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Generate a URI string from an associative array\r
+        *\r
+        *\r
+        * @access      public\r
+        * @param       array   an associative array of key/values\r
+        * @return      array\r
+        */     \r
+       function assoc_to_uri($array)\r
+       {       \r
+               $temp = array();\r
+               foreach ((array)$array as $key => $val)\r
+               {\r
+                       $temp[] = $key;\r
+                       $temp[] = $val;\r
+               }\r
+               \r
+               return implode('/', $temp);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a URI Segment and add a trailing slash\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function slash_segment($n, $where = 'trailing')\r
+       {\r
+               return $this->_slash_segment($n, $where, 'segment');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a URI Segment and add a trailing slash\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function slash_rsegment($n, $where = 'trailing')\r
+       {\r
+               return $this->_slash_segment($n, $where, 'rsegment');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch a URI Segment and add a trailing slash - helper function\r
+        *\r
+        * @access      private\r
+        * @param       integer\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _slash_segment($n, $where = 'trailing', $which = 'segment')\r
+       {       \r
+               if ($where == 'trailing')\r
+               {\r
+                       $trailing       = '/';\r
+                       $leading        = '';\r
+               }\r
+               elseif ($where == 'leading')\r
+               {\r
+                       $leading        = '/';\r
+                       $trailing       = '';\r
+               }\r
+               else\r
+               {\r
+                       $leading        = '/';\r
+                       $trailing       = '/';\r
+               }\r
+               return $leading.$this->$which($n).$trailing;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Segment Array\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function segment_array()\r
+       {\r
+               return $this->segments;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Routed Segment Array\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function rsegment_array()\r
+       {\r
+               return $this->rsegments;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Total number of segments\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function total_segments()\r
+       {\r
+               return count($this->segments);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Total number of routed segments\r
+        *\r
+        * @access      public\r
+        * @return      integer\r
+        */\r
+       function total_rsegments()\r
+       {\r
+               return count($this->rsegments);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch the entire URI string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function uri_string()\r
+       {\r
+               return $this->uri_string;\r
+       }\r
+\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Fetch the entire Re-routed URI string\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function ruri_string()\r
+       {\r
+               return '/'.implode('/', $this->rsegment_array()).'/';\r
+       }\r
+\r
+}\r
+// END URI Class\r
+\r
+/* End of file URI.php */\r
+/* Location: ./system/libraries/URI.php */
\ No newline at end of file
diff --git a/libraries/Unit_test.php b/libraries/Unit_test.php
new file mode 100644 (file)
index 0000000..5ed048b
--- /dev/null
@@ -0,0 +1,347 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.3.1\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Unit Testing Class\r
+ *\r
+ * Simple testing class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   UnitTesting\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/uri.html\r
+ */\r
+class CI_Unit_test {\r
+\r
+       var $active                     = TRUE;\r
+       var $results            = array();\r
+       var $strict                     = FALSE;\r
+       var $_template          = NULL;\r
+       var $_template_rows     = NULL;\r
+\r
+       function CI_Unit_test()\r
+       {\r
+               log_message('debug', "Unit Testing Class Initialized");\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Run the tests\r
+        *\r
+        * Runs the supplied tests\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function run($test, $expected = TRUE, $test_name = 'undefined')\r
+       {\r
+               if ($this->active == FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               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))\r
+               {\r
+                       $expected = str_replace('is_float', 'is_double', $expected);\r
+                       $result = ($expected($test)) ? TRUE : FALSE;    \r
+                       $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));\r
+               }\r
+               else\r
+               {\r
+                       if ($this->strict == TRUE)\r
+                               $result = ($test === $expected) ? TRUE : FALSE; \r
+                       else\r
+                               $result = ($test == $expected) ? TRUE : FALSE;  \r
+                       \r
+                       $extype = gettype($expected);\r
+               }\r
+                               \r
+               $back = $this->_backtrace();\r
+       \r
+               $report[] = array (\r
+                                                       'test_name'                     => $test_name,\r
+                                                       'test_datatype'         => gettype($test),\r
+                                                       'res_datatype'          => $extype,\r
+                                                       'result'                        => ($result === TRUE) ? 'passed' : 'failed',\r
+                                                       'file'                          => $back['file'],\r
+                                                       'line'                          => $back['line']\r
+                                               );\r
+\r
+               $this->results[] = $report;             \r
+                               \r
+               return($this->report($this->result($report)));\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate a report\r
+        *\r
+        * Displays a table with the test data\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */\r
+       function report($result = array())\r
+       {\r
+               if (count($result) == 0)\r
+               {\r
+                       $result = $this->result();\r
+               }\r
+\r
+               $CI =& get_instance();\r
+               $CI->load->language('unit_test');\r
+\r
+               $this->_parse_template();\r
+\r
+               $r = '';\r
+               foreach ($result as $res)\r
+               {\r
+                       $table = '';\r
+\r
+                       foreach ($res as $key => $val)\r
+                       {\r
+\r
+                               if ($key == $CI->lang->line('ut_result'))\r
+                               {\r
+                                       if ($val == $CI->lang->line('ut_passed'))\r
+                                       {\r
+                                               $val = '<span style="color: #0C0;">'.$val.'</span>';\r
+                                       }\r
+                                       elseif ($val == $CI->lang->line('ut_failed'))\r
+                                       {\r
+                                               $val = '<span style="color: #C00;">'.$val.'</span>';\r
+                                       }\r
+                               }\r
+\r
+                               $temp = $this->_template_rows;\r
+                               $temp = str_replace('{item}', $key, $temp);\r
+                               $temp = str_replace('{result}', $val, $temp);\r
+                               $table .= $temp;\r
+                       }\r
+\r
+                       $r .= str_replace('{rows}', $table, $this->_template);\r
+               }\r
+\r
+               return $r;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Use strict comparison\r
+        *\r
+        * Causes the evaluation to use === rather than ==\r
+        *\r
+        * @access      public\r
+        * @param       bool\r
+        * @return      null\r
+        */\r
+       function use_strict($state = TRUE)\r
+       {\r
+               $this->strict = ($state == FALSE) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Make Unit testing active\r
+        *\r
+        * Enables/disables unit testing\r
+        *\r
+        * @access      public\r
+        * @param       bool\r
+        * @return      null\r
+        */\r
+       function active($state = TRUE)\r
+       {\r
+               $this->active = ($state == FALSE) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Result Array\r
+        *\r
+        * Returns the raw result data\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */\r
+       function result($results = array())\r
+       {       \r
+               $CI =& get_instance();\r
+               $CI->load->language('unit_test');\r
+               \r
+               if (count($results) == 0)\r
+               {\r
+                       $results = $this->results;\r
+               }\r
+               \r
+               $retval = array();\r
+               foreach ($results as $result)\r
+               {\r
+                       $temp = array();\r
+                       foreach ($result as $key => $val)\r
+                       {\r
+                               if (is_array($val))\r
+                               {\r
+                                       foreach ($val as $k => $v)\r
+                                       {\r
+                                               if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))\r
+                                               {\r
+                                                       $v = $line;\r
+                                               }                               \r
+                                               $temp[$CI->lang->line('ut_'.$k)] = $v;                                  \r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val))))\r
+                                       {\r
+                                               $val = $line;\r
+                                       }                               \r
+                                       $temp[$CI->lang->line('ut_'.$key)] = $val;\r
+                               }\r
+                       }\r
+                       \r
+                       $retval[] = $temp;\r
+               }\r
+       \r
+               return $retval;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the template\r
+        *\r
+        * This lets us set the template to be used to display results\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_template($template)\r
+       {\r
+               $this->_template = $template;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Generate a backtrace\r
+        *\r
+        * This lets us show file names and line numbers\r
+        *\r
+        * @access      private\r
+        * @return      array\r
+        */\r
+       function _backtrace()\r
+       {\r
+               if (function_exists('debug_backtrace'))\r
+               {\r
+                       $back = debug_backtrace();\r
+                       \r
+                       $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];\r
+                       $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];\r
+                                               \r
+                       return array('file' => $file, 'line' => $line);\r
+               }\r
+               return array('file' => 'Unknown', 'line' => 'Unknown');\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get Default Template\r
+        *\r
+        * @access      private\r
+        * @return      string\r
+        */\r
+       function _default_template()\r
+       {       \r
+               $this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">';\r
+               $this->_template .= '{rows}';\r
+               $this->_template .= "\n".'</table>';\r
+               \r
+               $this->_template_rows = "\n\t".'<tr>';\r
+               $this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>';\r
+               $this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>';\r
+               $this->_template_rows .= "\n\t".'</tr>';        \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Parse Template\r
+        *\r
+        * Harvests the data within the template {pseudo-variables}\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */\r
+       function _parse_template()\r
+       {\r
+               if ( ! is_null($this->_template_rows))\r
+               {\r
+                       return;\r
+               }\r
+               \r
+               if (is_null($this->_template))\r
+               {\r
+                       $this->_default_template();\r
+                       return;\r
+               }\r
+               \r
+               if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))\r
+               {\r
+                       $this->_default_template();\r
+                       return;\r
+               }\r
+\r
+               $this->_template_rows = $match['1'];\r
+               $this->_template = str_replace($match['0'], '{rows}', $this->_template);        \r
+       }\r
+       \r
+}\r
+// END Unit_test Class\r
+\r
+/**\r
+ * Helper functions to test boolean true/false\r
+ *\r
+ *\r
+ * @access     private\r
+ * @return     bool\r
+ */\r
+function is_true($test)\r
+{\r
+       return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;\r
+}\r
+function is_false($test)\r
+{\r
+       return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;\r
+}\r
+\r
+\r
+/* End of file Unit_test.php */\r
+/* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file
diff --git a/libraries/Upload.php b/libraries/Upload.php
new file mode 100644 (file)
index 0000000..3832dab
--- /dev/null
@@ -0,0 +1,931 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * File Uploading Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Uploads\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/file_uploading.html\r
+ */\r
+class CI_Upload {\r
+       \r
+       var $max_size           = 0;\r
+       var $max_width          = 0;\r
+       var $max_height         = 0;\r
+       var $max_filename       = 0;\r
+       var $allowed_types      = "";\r
+       var $file_temp          = "";\r
+       var $file_name          = "";\r
+       var $orig_name          = "";\r
+       var $file_type          = "";\r
+       var $file_size          = "";\r
+       var $file_ext           = "";\r
+       var $upload_path        = "";\r
+       var $overwrite          = FALSE;\r
+       var $encrypt_name       = FALSE;\r
+       var $is_image           = FALSE;\r
+       var $image_width        = '';\r
+       var $image_height       = '';\r
+       var $image_type         = '';\r
+       var $image_size_str     = '';\r
+       var $error_msg          = array();\r
+       var $mimes                      = array();\r
+       var $remove_spaces      = TRUE;\r
+       var $xss_clean          = FALSE;\r
+       var $temp_prefix        = "temp_file_";\r
+               \r
+       /**\r
+        * Constructor\r
+        *\r
+        * @access      public\r
+        */\r
+       function CI_Upload($props = array())\r
+       {\r
+               if (count($props) > 0)\r
+               {\r
+                       $this->initialize($props);\r
+               }\r
+               \r
+               log_message('debug', "Upload Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Initialize preferences\r
+        *\r
+        * @access      public\r
+        * @param       array\r
+        * @return      void\r
+        */     \r
+       function initialize($config = array())\r
+       {\r
+               $defaults = array(\r
+                                                       'max_size'                      => 0,\r
+                                                       'max_width'                     => 0,\r
+                                                       'max_height'            => 0,\r
+                                                       'max_filename'          => 0,\r
+                                                       'allowed_types'         => "",\r
+                                                       'file_temp'                     => "",\r
+                                                       'file_name'                     => "",\r
+                                                       'orig_name'                     => "",\r
+                                                       'file_type'                     => "",\r
+                                                       'file_size'                     => "",\r
+                                                       'file_ext'                      => "",\r
+                                                       'upload_path'           => "",\r
+                                                       'overwrite'                     => FALSE,\r
+                                                       'encrypt_name'          => FALSE,\r
+                                                       'is_image'                      => FALSE,\r
+                                                       'image_width'           => '',\r
+                                                       'image_height'          => '',\r
+                                                       'image_type'            => '',\r
+                                                       'image_size_str'        => '',\r
+                                                       'error_msg'                     => array(),\r
+                                                       'mimes'                         => array(),\r
+                                                       'remove_spaces'         => TRUE,\r
+                                                       'xss_clean'                     => FALSE,\r
+                                                       'temp_prefix'           => "temp_file_"\r
+                                               );      \r
+       \r
+       \r
+               foreach ($defaults as $key => $val)\r
+               {\r
+                       if (isset($config[$key]))\r
+                       {\r
+                               $method = 'set_'.$key;\r
+                               if (method_exists($this, $method))\r
+                               {\r
+                                       $this->$method($config[$key]);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $this->$key = $config[$key];\r
+                               }                       \r
+                       }\r
+                       else\r
+                       {\r
+                               $this->$key = $val;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Perform the file upload\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function do_upload($field = 'userfile')\r
+       {\r
+               // Is $_FILES[$field] set? If not, no reason to continue.\r
+               if ( ! isset($_FILES[$field]))\r
+               {\r
+                       $this->set_error('upload_no_file_selected');\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Is the upload path valid?\r
+               if ( ! $this->validate_upload_path())\r
+               {\r
+                       // errors will already be set by validate_upload_path() so just return FALSE\r
+                       return FALSE;\r
+               }\r
+\r
+               // Was the file able to be uploaded? If not, determine the reason why.\r
+               if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))\r
+               {\r
+                       $error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];\r
+\r
+                       switch($error)\r
+                       {\r
+                               case 1: // UPLOAD_ERR_INI_SIZE\r
+                                       $this->set_error('upload_file_exceeds_limit');\r
+                                       break;\r
+                               case 2: // UPLOAD_ERR_FORM_SIZE\r
+                                       $this->set_error('upload_file_exceeds_form_limit');\r
+                                       break;\r
+                               case 3: // UPLOAD_ERR_PARTIAL\r
+                                  $this->set_error('upload_file_partial');\r
+                                       break;\r
+                               case 4: // UPLOAD_ERR_NO_FILE\r
+                                  $this->set_error('upload_no_file_selected');\r
+                                       break;\r
+                               case 6: // UPLOAD_ERR_NO_TMP_DIR\r
+                                       $this->set_error('upload_no_temp_directory');\r
+                                       break;\r
+                               case 7: // UPLOAD_ERR_CANT_WRITE\r
+                                       $this->set_error('upload_unable_to_write_file');\r
+                                       break;\r
+                               case 8: // UPLOAD_ERR_EXTENSION\r
+                                       $this->set_error('upload_stopped_by_extension');\r
+                                       break;\r
+                               default :   $this->set_error('upload_no_file_selected');\r
+                                       break;\r
+                       }\r
+\r
+                       return FALSE;\r
+               }\r
+\r
+               // Set the uploaded data as class variables\r
+               $this->file_temp = $_FILES[$field]['tmp_name'];         \r
+               $this->file_name = $this->_prep_filename($_FILES[$field]['name']);\r
+               $this->file_size = $_FILES[$field]['size'];             \r
+               $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);\r
+               $this->file_type = strtolower($this->file_type);\r
+               $this->file_ext  = $this->get_extension($_FILES[$field]['name']);\r
+               \r
+               // Convert the file size to kilobytes\r
+               if ($this->file_size > 0)\r
+               {\r
+                       $this->file_size = round($this->file_size/1024, 2);\r
+               }\r
+\r
+               // Is the file type allowed to be uploaded?\r
+               if ( ! $this->is_allowed_filetype())\r
+               {\r
+                       $this->set_error('upload_invalid_filetype');\r
+                       return FALSE;\r
+               }\r
+\r
+               // Is the file size within the allowed maximum?\r
+               if ( ! $this->is_allowed_filesize())\r
+               {\r
+                       $this->set_error('upload_invalid_filesize');\r
+                       return FALSE;\r
+               }\r
+\r
+               // Are the image dimensions within the allowed size?\r
+               // Note: This can fail if the server has an open_basdir restriction.\r
+               if ( ! $this->is_allowed_dimensions())\r
+               {\r
+                       $this->set_error('upload_invalid_dimensions');\r
+                       return FALSE;\r
+               }\r
+\r
+               // Sanitize the file name for security\r
+               $this->file_name = $this->clean_file_name($this->file_name);\r
+               \r
+               // Truncate the file name if it's too long\r
+               if ($this->max_filename > 0)\r
+               {\r
+                       $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);\r
+               }\r
+\r
+               // Remove white spaces in the name\r
+               if ($this->remove_spaces == TRUE)\r
+               {\r
+                       $this->file_name = preg_replace("/\s+/", "_", $this->file_name);\r
+               }\r
+\r
+               /*\r
+                * Validate the file name\r
+                * This function appends an number onto the end of\r
+                * the file if one with the same name already exists.\r
+                * If it returns false there was a problem.\r
+                */\r
+               $this->orig_name = $this->file_name;\r
+\r
+               if ($this->overwrite == FALSE)\r
+               {\r
+                       $this->file_name = $this->set_filename($this->upload_path, $this->file_name);\r
+                       \r
+                       if ($this->file_name === FALSE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+\r
+               /*\r
+                * Move the file to the final destination\r
+                * To deal with different server configurations\r
+                * we'll attempt to use copy() first.  If that fails\r
+                * we'll use move_uploaded_file().  One of the two should\r
+                * reliably work in most environments\r
+                */\r
+               if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))\r
+               {\r
+                       if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))\r
+                       {\r
+                                $this->set_error('upload_destination_error');\r
+                                return FALSE;\r
+                       }\r
+               }\r
+               \r
+               /*\r
+                * Run the file through the XSS hacking filter\r
+                * This helps prevent malicious code from being\r
+                * embedded within a file.  Scripts can easily\r
+                * be disguised as images or other file types.\r
+                */\r
+               if ($this->xss_clean == TRUE)\r
+               {\r
+                       $this->do_xss_clean();\r
+               }\r
+\r
+               /*\r
+                * Set the finalized image dimensions\r
+                * This sets the image width/height (assuming the\r
+                * file was an image).  We use this information\r
+                * in the "data" function.\r
+                */\r
+               $this->set_image_properties($this->upload_path.$this->file_name);\r
+\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Finalized Data Array\r
+        *      \r
+        * Returns an associative array containing all of the information\r
+        * related to the upload, allowing the developer easy access in one array.\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */     \r
+       function data()\r
+       {\r
+               return array (\r
+                                               'file_name'                     => $this->file_name,\r
+                                               'file_type'                     => $this->file_type,\r
+                                               'file_path'                     => $this->upload_path,\r
+                                               'full_path'                     => $this->upload_path.$this->file_name,\r
+                                               'raw_name'                      => str_replace($this->file_ext, '', $this->file_name),\r
+                                               'orig_name'                     => $this->orig_name,\r
+                                               'file_ext'                      => $this->file_ext,\r
+                                               'file_size'                     => $this->file_size,\r
+                                               'is_image'                      => $this->is_image(),\r
+                                               'image_width'           => $this->image_width,\r
+                                               'image_height'          => $this->image_height,\r
+                                               'image_type'            => $this->image_type,\r
+                                               'image_size_str'        => $this->image_size_str,\r
+                                       );\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Upload Path\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_upload_path($path)\r
+       {\r
+               // Make sure it has a trailing slash\r
+               $this->upload_path = rtrim($path, '/').'/';\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the file name\r
+        *\r
+        * This function takes a filename/path as input and looks for the\r
+        * existence of a file with the same name. If found, it will append a\r
+        * number to the end of the filename to avoid overwriting a pre-existing file.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_filename($path, $filename)\r
+       {\r
+               if ($this->encrypt_name == TRUE)\r
+               {               \r
+                       mt_srand();\r
+                       $filename = md5(uniqid(mt_rand())).$this->file_ext;     \r
+               }\r
+       \r
+               if ( ! file_exists($path.$filename))\r
+               {\r
+                       return $filename;\r
+               }\r
+       \r
+               $filename = str_replace($this->file_ext, '', $filename);\r
+               \r
+               $new_filename = '';\r
+               for ($i = 1; $i < 100; $i++)\r
+               {                       \r
+                       if ( ! file_exists($path.$filename.$i.$this->file_ext))\r
+                       {\r
+                               $new_filename = $filename.$i.$this->file_ext;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if ($new_filename == '')\r
+               {\r
+                       $this->set_error('upload_bad_filename');\r
+                       return FALSE;\r
+               }\r
+               else\r
+               {\r
+                       return $new_filename;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Maximum File Size\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function set_max_filesize($n)\r
+       {\r
+               $this->max_size = ((int) $n < 0) ? 0: (int) $n;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Maximum File Name Length\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function set_max_filename($n)\r
+       {\r
+               $this->max_filename = ((int) $n < 0) ? 0: (int) $n;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Maximum Image Width\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function set_max_width($n)\r
+       {\r
+               $this->max_width = ((int) $n < 0) ? 0: (int) $n;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Maximum Image Height\r
+        *\r
+        * @access      public\r
+        * @param       integer\r
+        * @return      void\r
+        */     \r
+       function set_max_height($n)\r
+       {\r
+               $this->max_height = ((int) $n < 0) ? 0: (int) $n;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Allowed File Types\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_allowed_types($types)\r
+       {\r
+               $this->allowed_types = explode('|', $types);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Image Properties\r
+        *\r
+        * Uses GD to determine the width/height/type of image\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_image_properties($path = '')\r
+       {\r
+               if ( ! $this->is_image())\r
+               {\r
+                       return;\r
+               }\r
+\r
+               if (function_exists('getimagesize'))\r
+               {\r
+                       if (FALSE !== ($D = @getimagesize($path)))\r
+                       {       \r
+                               $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');\r
+\r
+                               $this->image_width              = $D['0'];\r
+                               $this->image_height             = $D['1'];\r
+                               $this->image_type               = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];\r
+                               $this->image_size_str   = $D['3'];  // string containing height and width\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set XSS Clean\r
+        *\r
+        * Enables the XSS flag so that the file that was uploaded\r
+        * will be run through the XSS filter.\r
+        *\r
+        * @access      public\r
+        * @param       bool\r
+        * @return      void\r
+        */\r
+       function set_xss_clean($flag = FALSE)\r
+       {\r
+               $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validate the image\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function is_image()\r
+       {\r
+               // IE will sometimes return odd mime-types during upload, so here we just standardize all\r
+               // jpegs or pngs to the same file type.\r
+\r
+               $png_mimes  = array('image/x-png');\r
+               $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');\r
+               \r
+               if (in_array($this->file_type, $png_mimes))\r
+               {\r
+                       $this->file_type = 'image/png';\r
+               }\r
+               \r
+               if (in_array($this->file_type, $jpeg_mimes))\r
+               {\r
+                       $this->file_type = 'image/jpeg';\r
+               }\r
+\r
+               $img_mimes = array(\r
+                                                       'image/gif',\r
+                                                       'image/jpeg',\r
+                                                       'image/png',\r
+                                                  );\r
+\r
+               return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Verify that the filetype is allowed\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function is_allowed_filetype()\r
+       {\r
+               if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))\r
+               {\r
+                       $this->set_error('upload_no_file_types');\r
+                       return FALSE;\r
+               }\r
+                               \r
+               foreach ($this->allowed_types as $val)\r
+               {\r
+                       $mime = $this->mimes_types(strtolower($val));\r
+               \r
+                       if (is_array($mime))\r
+                       {\r
+                               if (in_array($this->file_type, $mime, TRUE))\r
+                               {\r
+                                       return TRUE;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               if ($mime == $this->file_type)\r
+                               {\r
+                                       return TRUE;\r
+                               }       \r
+                       }               \r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Verify that the file is within the allowed size\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function is_allowed_filesize()\r
+       {\r
+               if ($this->max_size != 0  AND  $this->file_size > $this->max_size)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               else\r
+               {\r
+                       return TRUE;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Verify that the image is within the allowed width/height\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function is_allowed_dimensions()\r
+       {\r
+               if ( ! $this->is_image())\r
+               {\r
+                       return TRUE;\r
+               }\r
+\r
+               if (function_exists('getimagesize'))\r
+               {\r
+                       $D = @getimagesize($this->file_temp);\r
+\r
+                       if ($this->max_width > 0 AND $D['0'] > $this->max_width)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+\r
+                       if ($this->max_height > 0 AND $D['1'] > $this->max_height)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+\r
+                       return TRUE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validate Upload Path\r
+        *\r
+        * Verifies that it is a valid upload path with proper permissions.\r
+        *\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function validate_upload_path()\r
+       {\r
+               if ($this->upload_path == '')\r
+               {\r
+                       $this->set_error('upload_no_filepath');\r
+                       return FALSE;\r
+               }\r
+               \r
+               if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)\r
+               {\r
+                       $this->upload_path = str_replace("\\", "/", realpath($this->upload_path));\r
+               }\r
+\r
+               if ( ! @is_dir($this->upload_path))\r
+               {\r
+                       $this->set_error('upload_no_filepath');\r
+                       return FALSE;\r
+               }\r
+\r
+               if ( ! is_really_writable($this->upload_path))\r
+               {\r
+                       $this->set_error('upload_not_writable');\r
+                       return FALSE;\r
+               }\r
+\r
+               $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/",  $this->upload_path);\r
+               return TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Extract the file extension\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function get_extension($filename)\r
+       {\r
+               $x = explode('.', $filename);\r
+               return '.'.end($x);\r
+       }       \r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Clean the file name for security\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */             \r
+       function clean_file_name($filename)\r
+       {\r
+               $bad = array(\r
+                                               "<!--",\r
+                                               "-->",\r
+                                               "'",\r
+                                               "<",\r
+                                               ">",\r
+                                               '"',\r
+                                               '&',\r
+                                               '$',\r
+                                               '=',\r
+                                               ';',\r
+                                               '?',\r
+                                               '/',\r
+                                               "%20",\r
+                                               "%22",\r
+                                               "%3c",          // <\r
+                                               "%253c",        // <\r
+                                               "%3e",          // >\r
+                                               "%0e",          // >\r
+                                               "%28",          // (\r
+                                               "%29",          // )\r
+                                               "%2528",        // (\r
+                                               "%26",          // &\r
+                                               "%24",          // $\r
+                                               "%3f",          // ?\r
+                                               "%3b",          // ;\r
+                                               "%3d"           // =\r
+                                       );\r
+                                       \r
+               $filename = str_replace($bad, '', $filename);\r
+\r
+               return stripslashes($filename);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Limit the File Name Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */             \r
+       function limit_filename_length($filename, $length)\r
+       {\r
+               if (strlen($filename) < $length)\r
+               {\r
+                       return $filename;\r
+               }\r
+       \r
+               $ext = '';\r
+               if (strpos($filename, '.') !== FALSE)\r
+               {\r
+                       $parts          = explode('.', $filename);\r
+                       $ext            = '.'.array_pop($parts);\r
+                       $filename       = implode('.', $parts);\r
+               }\r
+       \r
+               return substr($filename, 0, ($length - strlen($ext))).$ext;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Runs the file through the XSS clean function\r
+        *\r
+        * This prevents people from embedding malicious code in their files.\r
+        * I'm not sure that it won't negatively affect certain files in unexpected ways,\r
+        * but so far I haven't found that it causes trouble.\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */     \r
+       function do_xss_clean()\r
+       {               \r
+               $file = $this->upload_path.$this->file_name;\r
+               \r
+               if (filesize($file) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (($data = @file_get_contents($file)) === FALSE)\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if ( ! $fp = @fopen($file, FOPEN_READ_WRITE))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $CI =& get_instance();  \r
+               $data = $CI->input->xss_clean($data);\r
+               \r
+               flock($fp, LOCK_EX);\r
+               fwrite($fp, $data);\r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set an error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_error($msg)\r
+       {\r
+               $CI =& get_instance();  \r
+               $CI->lang->load('upload');\r
+               \r
+               if (is_array($msg))\r
+               {\r
+                       foreach ($msg as $val)\r
+                       {\r
+                               $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);                         \r
+                               $this->error_msg[] = $msg;\r
+                               log_message('error', $msg);\r
+                       }               \r
+               }\r
+               else\r
+               {\r
+                       $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);\r
+                       $this->error_msg[] = $msg;\r
+                       log_message('error', $msg);\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Display the error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function display_errors($open = '<p>', $close = '</p>')\r
+       {\r
+               $str = '';\r
+               foreach ($this->error_msg as $val)\r
+               {\r
+                       $str .= $open.$val.$close;\r
+               }\r
+       \r
+               return $str;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * List of Mime Types\r
+        *\r
+        * This is a list of mime types.  We use it to validate\r
+        * the "allowed types" set by the developer\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function mimes_types($mime)\r
+       {\r
+               global $mimes;\r
+       \r
+               if (count($this->mimes) == 0)\r
+               {\r
+                       if (@require_once(APPPATH.'config/mimes'.EXT))\r
+                       {\r
+                               $this->mimes = $mimes;\r
+                               unset($mimes);\r
+                       }\r
+               }\r
+       \r
+               return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep Filename\r
+        *\r
+        * Prevents possible script execution from Apache's handling of files multiple extensions\r
+        * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext\r
+        *\r
+        * @access      private\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function _prep_filename($filename)\r
+       {\r
+               if (strpos($filename, '.') === FALSE)\r
+               {\r
+                       return $filename;\r
+               }\r
+               \r
+               $parts          = explode('.', $filename);\r
+               $ext            = array_pop($parts);\r
+               $filename       = array_shift($parts);\r
+                               \r
+               foreach ($parts as $part)\r
+               {\r
+                       if ($this->mimes_types(strtolower($part)) === FALSE)\r
+                       {\r
+                               $filename .= '.'.$part.'_';\r
+                       }\r
+                       else\r
+                       {\r
+                               $filename .= '.'.$part;\r
+                       }\r
+               }\r
+               \r
+               $filename .= '.'.$ext;\r
+               \r
+               return $filename;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+}\r
+// END Upload Class\r
+\r
+/* End of file Upload.php */\r
+/* Location: ./system/libraries/Upload.php */
\ No newline at end of file
diff --git a/libraries/User_agent.php b/libraries/User_agent.php
new file mode 100644 (file)
index 0000000..c7cf870
--- /dev/null
@@ -0,0 +1,502 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * User Agent Class\r
+ *\r
+ * Identifies the platform, browser, robot, or mobile devise of the browsing agent\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   User Agent\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/user_agent.html\r
+ */\r
+class CI_User_agent {\r
+\r
+       var $agent              = NULL;\r
+       \r
+       var $is_browser = FALSE;\r
+       var $is_robot   = FALSE;\r
+       var $is_mobile  = FALSE;\r
+\r
+       var $languages  = array();\r
+       var $charsets   = array();\r
+       \r
+       var $platforms  = array();\r
+       var $browsers   = array();\r
+       var $mobiles    = array();\r
+       var $robots             = array();\r
+       \r
+       var $platform   = '';\r
+       var $browser    = '';\r
+       var $version    = '';\r
+       var $mobile             = '';\r
+       var $robot              = '';\r
+       \r
+       /**\r
+        * Constructor\r
+        *\r
+        * Sets the User Agent and runs the compilation routine\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function CI_User_agent()\r
+       {\r
+               if (isset($_SERVER['HTTP_USER_AGENT']))\r
+               {\r
+                       $this->agent = trim($_SERVER['HTTP_USER_AGENT']);\r
+               }\r
+               \r
+               if ( ! is_null($this->agent))\r
+               {\r
+                       if ($this->_load_agent_file())\r
+                       {\r
+                               $this->_compile_data();\r
+                       }\r
+               }\r
+               \r
+               log_message('debug', "User Agent Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Compile the User Agent Data\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */             \r
+       function _load_agent_file()\r
+       {\r
+               if ( ! @include(APPPATH.'config/user_agents'.EXT))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $return = FALSE;\r
+               \r
+               if (isset($platforms))\r
+               {\r
+                       $this->platforms = $platforms;\r
+                       unset($platforms);\r
+                       $return = TRUE;\r
+               }\r
+\r
+               if (isset($browsers))\r
+               {\r
+                       $this->browsers = $browsers;\r
+                       unset($browsers);\r
+                       $return = TRUE;\r
+               }\r
+\r
+               if (isset($mobiles))\r
+               {\r
+                       $this->mobiles = $mobiles;\r
+                       unset($mobiles);\r
+                       $return = TRUE;\r
+               }\r
+               \r
+               if (isset($robots))\r
+               {\r
+                       $this->robots = $robots;\r
+                       unset($robots);\r
+                       $return = TRUE;\r
+               }\r
+\r
+               return $return;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Compile the User Agent Data\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */             \r
+       function _compile_data()\r
+       {\r
+               $this->_set_platform();\r
+       \r
+               foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function)\r
+               {\r
+                       if ($this->$function() === TRUE)\r
+                       {\r
+                               break;\r
+                       }\r
+               }       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Platform\r
+        *\r
+        * @access      private\r
+        * @return      mixed\r
+        */             \r
+       function _set_platform()\r
+       {\r
+               if (is_array($this->platforms) AND count($this->platforms) > 0)\r
+               {\r
+                       foreach ($this->platforms as $key => $val)\r
+                       {\r
+                               if (preg_match("|".preg_quote($key)."|i", $this->agent))\r
+                               {\r
+                                       $this->platform = $val;\r
+                                       return TRUE;\r
+                               }\r
+                       }\r
+               }\r
+               $this->platform = 'Unknown Platform';\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Browser\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */             \r
+       function _set_browser()\r
+       {\r
+               if (is_array($this->browsers) AND count($this->browsers) > 0)\r
+               {\r
+                       foreach ($this->browsers as $key => $val)\r
+                       {               \r
+                               if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match))\r
+                               {\r
+                                       $this->is_browser = TRUE;\r
+                                       $this->version = $match[1];\r
+                                       $this->browser = $val;\r
+                                       $this->_set_mobile();\r
+                                       return TRUE;\r
+                               }\r
+                       }\r
+               }\r
+               return FALSE;\r
+       }\r
+                       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Robot\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */             \r
+       function _set_robot()\r
+       {\r
+               if (is_array($this->robots) AND count($this->robots) > 0)\r
+               {               \r
+                       foreach ($this->robots as $key => $val)\r
+                       {\r
+                               if (preg_match("|".preg_quote($key)."|i", $this->agent))\r
+                               {\r
+                                       $this->is_robot = TRUE;\r
+                                       $this->robot = $val;\r
+                                       return TRUE;\r
+                               }\r
+                       }\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the Mobile Device\r
+        *\r
+        * @access      private\r
+        * @return      bool\r
+        */             \r
+       function _set_mobile()\r
+       {\r
+               if (is_array($this->mobiles) AND count($this->mobiles) > 0)\r
+               {               \r
+                       foreach ($this->mobiles as $key => $val)\r
+                       {\r
+                               if (FALSE !== (strpos(strtolower($this->agent), $key)))\r
+                               {\r
+                                       $this->is_mobile = TRUE;\r
+                                       $this->mobile = $val;\r
+                                       return TRUE;\r
+                               }\r
+                       }\r
+               }       \r
+               return FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the accepted languages\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */                     \r
+       function _set_languages()\r
+       {\r
+               if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')\r
+               {\r
+                       $languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])));\r
+                       \r
+                       $this->languages = explode(',', $languages);\r
+               }\r
+               \r
+               if (count($this->languages) == 0)\r
+               {\r
+                       $this->languages = array('Undefined');\r
+               }       \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set the accepted character sets\r
+        *\r
+        * @access      private\r
+        * @return      void\r
+        */                     \r
+       function _set_charsets()\r
+       {       \r
+               if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')\r
+               {\r
+                       $charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])));\r
+                       \r
+                       $this->charsets = explode(',', $charsets);\r
+               }\r
+               \r
+               if (count($this->charsets) == 0)\r
+               {\r
+                       $this->charsets = array('Undefined');\r
+               }       \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Is Browser\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function is_browser()\r
+       {\r
+               return $this->is_browser;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Is Robot\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function is_robot()\r
+       {\r
+               return $this->is_robot;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Is Mobile\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function is_mobile()\r
+       {\r
+               return $this->is_mobile;\r
+       }       \r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Is this a referral from another site?\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function is_referral()\r
+       {\r
+               return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Agent String\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                     \r
+       function agent_string()\r
+       {\r
+               return $this->agent;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get Platform\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                     \r
+       function platform()\r
+       {\r
+               return $this->platform;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get Browser Name\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                     \r
+       function browser()\r
+       {\r
+               return $this->browser;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the Browser Version\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                     \r
+       function version()\r
+       {\r
+               return $this->version;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get The Robot Name\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                             \r
+       function robot()\r
+       {\r
+               return $this->robot;\r
+       }\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the Mobile Device\r
+        *\r
+        * @access      public\r
+        * @return      string\r
+        */                     \r
+       function mobile()\r
+       {\r
+               return $this->mobile;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the referrer\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function referrer()\r
+       {\r
+               return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the accepted languages\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */                     \r
+       function languages()\r
+       {\r
+               if (count($this->languages) == 0)\r
+               {\r
+                       $this->_set_languages();\r
+               }\r
+       \r
+               return $this->languages;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Get the accepted Character Sets\r
+        *\r
+        * @access      public\r
+        * @return      array\r
+        */                     \r
+       function charsets()\r
+       {\r
+               if (count($this->charsets) == 0)\r
+               {\r
+                       $this->_set_charsets();\r
+               }\r
+       \r
+               return $this->charsets;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Test for a particular language\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function accept_lang($lang = 'en')\r
+       {\r
+               return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Test for a particular character set\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */                     \r
+       function accept_charset($charset = 'utf-8')\r
+       {\r
+               return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE;\r
+       }\r
+       \r
+       \r
+}\r
+\r
+\r
+/* End of file User_agent.php */\r
+/* Location: ./system/libraries/User_agent.php */
\ No newline at end of file
diff --git a/libraries/Validation.php b/libraries/Validation.php
new file mode 100644 (file)
index 0000000..a463202
--- /dev/null
@@ -0,0 +1,875 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Validation Class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Validation\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/validation.html\r
+ */\r
+class CI_Validation {\r
+       \r
+       var $CI;\r
+       var $error_string               = '';\r
+       var $_error_array               = array();\r
+       var $_rules                             = array();\r
+       var $_fields                    = array();\r
+       var $_error_messages    = array();\r
+       var $_current_field     = '';\r
+       var $_safe_form_data    = FALSE;\r
+       var $_error_prefix              = '<p>';\r
+       var $_error_suffix              = '</p>';\r
+\r
+       \r
+\r
+       /**\r
+        * Constructor\r
+        *\r
+        */     \r
+       function CI_Validation()\r
+       {       \r
+               $this->CI =& get_instance();\r
+               \r
+               if (function_exists('mb_internal_encoding'))\r
+               {\r
+                       mb_internal_encoding($this->CI->config->item('charset'));\r
+               }\r
+               \r
+               log_message('debug', "Validation Class Initialized");\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Fields\r
+        *\r
+        * This function takes an array of field names as input\r
+        * and generates class variables with the same name, which will\r
+        * either be blank or contain the $_POST value corresponding to it\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_fields($data = '', $field = '')\r
+       {       \r
+               if ($data == '')\r
+               {\r
+                       if (count($this->_fields) == 0)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if ( ! is_array($data))\r
+                       {\r
+                               $data = array($data => $field);\r
+                       }\r
+                       \r
+                       if (count($data) > 0)\r
+                       {\r
+                               $this->_fields = $data;\r
+                       }\r
+               }               \r
+                       \r
+               foreach($this->_fields as $key => $val)\r
+               {\r
+                       $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);\r
+                       \r
+                       $error = $key.'_error';\r
+                       if ( ! isset($this->$error))\r
+                       {\r
+                               $this->$error = '';\r
+                       }\r
+               }               \r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Rules\r
+        *\r
+        * This function takes an array of field names and validation\r
+        * rules as input ad simply stores is for use later.\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      void\r
+        */\r
+       function set_rules($data, $rules = '')\r
+       {\r
+               if ( ! is_array($data))\r
+               {\r
+                       if ($rules == '')\r
+                               return;\r
+                               \r
+                       $data = array($data => $rules);\r
+               }\r
+       \r
+               foreach ($data as $key => $val)\r
+               {\r
+                       $this->_rules[$key] = $val;\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Error Message\r
+        *\r
+        * Lets users set their own error messages on the fly.  Note:  The key\r
+        * name has to match the  function name that it corresponds to.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function set_message($lang, $val = '')\r
+       {\r
+               if ( ! is_array($lang))\r
+               {\r
+                       $lang = array($lang => $val);\r
+               }\r
+       \r
+               $this->_error_messages = array_merge($this->_error_messages, $lang);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set The Error Delimiter\r
+        *\r
+        * Permits a prefix/suffix to be added to each error message\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function set_error_delimiters($prefix = '<p>', $suffix = '</p>')\r
+       {\r
+               $this->_error_prefix = $prefix;\r
+               $this->_error_suffix = $suffix;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Run the Validator\r
+        *\r
+        * This function does all the work.\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */             \r
+       function run()\r
+       {\r
+               // Do we even have any data to process?  Mm?\r
+               if (count($_POST) == 0 OR count($this->_rules) == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               // Load the language file containing error messages\r
+               $this->CI->lang->load('validation');\r
+                                                       \r
+               // Cycle through the rules and test for errors\r
+               foreach ($this->_rules as $field => $rules)\r
+               {\r
+                       //Explode out the rules!\r
+                       $ex = explode('|', $rules);\r
+\r
+                       // Is the field required?  If not, if the field is blank  we'll move on to the next test\r
+                       if ( ! in_array('required', $ex, TRUE))\r
+                       {\r
+                               if ( ! isset($_POST[$field]) OR $_POST[$field] == '')\r
+                               {\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       \r
+                       /*\r
+                        * Are we dealing with an "isset" rule?\r
+                        *\r
+                        * Before going further, we'll see if one of the rules\r
+                        * is to check whether the item is set (typically this\r
+                        * applies only to checkboxes).  If so, we'll\r
+                        * test for it here since there's not reason to go\r
+                        * further\r
+                        */\r
+                       if ( ! isset($_POST[$field]))\r
+                       {                       \r
+                               if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))\r
+                               {\r
+                                       if ( ! isset($this->_error_messages['isset']))\r
+                                       {\r
+                                               if (FALSE === ($line = $this->CI->lang->line('isset')))\r
+                                               {\r
+                                                       $line = 'The field was not set';\r
+                                               }                                                       \r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $line = $this->_error_messages['isset'];\r
+                                       }\r
+                                       \r
+                                       // Build the error message\r
+                                       $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];\r
+                                       $message = sprintf($line, $mfield);\r
+\r
+                                       // Set the error variable.  Example: $this->username_error\r
+                                       $error = $field.'_error';\r
+                                       $this->$error = $this->_error_prefix.$message.$this->_error_suffix;\r
+                                       $this->_error_array[] = $message;\r
+                               }\r
+                                               \r
+                               continue;\r
+                       }\r
+       \r
+                       /*\r
+                        * Set the current field\r
+                        *\r
+                        * The various prepping functions need to know the\r
+                        * current field name so they can do this:\r
+                        *\r
+                        * $_POST[$this->_current_field] == 'bla bla';\r
+                        */\r
+                       $this->_current_field = $field;\r
+\r
+                       // Cycle through the rules!\r
+                       foreach ($ex As $rule)\r
+                       {\r
+                               // Is the rule a callback?                      \r
+                               $callback = FALSE;\r
+                               if (substr($rule, 0, 9) == 'callback_')\r
+                               {\r
+                                       $rule = substr($rule, 9);\r
+                                       $callback = TRUE;\r
+                               }\r
+                               \r
+                               // Strip the parameter (if exists) from the rule\r
+                               // Rules can contain a parameter: max_length[5]\r
+                               $param = FALSE;\r
+                               if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))\r
+                               {\r
+                                       $rule   = $match[1];\r
+                                       $param  = $match[2];\r
+                               }\r
+                               \r
+                               // Call the function that corresponds to the rule\r
+                               if ($callback === TRUE)\r
+                               {\r
+                                       if ( ! method_exists($this->CI, $rule))\r
+                                       {               \r
+                                               continue;\r
+                                       }\r
+                                       \r
+                                       $result = $this->CI->$rule($_POST[$field], $param);     \r
+                                       \r
+                                       // If the field isn't required and we just processed a callback we'll move on...\r
+                                       if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)\r
+                                       {\r
+                                               continue 2;\r
+                                       }\r
+                                       \r
+                               }\r
+                               else\r
+                               {                               \r
+                                       if ( ! method_exists($this, $rule))\r
+                                       {\r
+                                               /*\r
+                                                * Run the native PHP function if called for\r
+                                                *\r
+                                                * If our own wrapper function doesn't exist we see\r
+                                                * if a native PHP function does. Users can use\r
+                                                * any native PHP function call that has one param.\r
+                                                */\r
+                                               if (function_exists($rule))\r
+                                               {\r
+                                                       $_POST[$field] = $rule($_POST[$field]);\r
+                                                       $this->$field = $_POST[$field];\r
+                                               }\r
+                                                                                       \r
+                                               continue;\r
+                                       }\r
+                                       \r
+                                       $result = $this->$rule($_POST[$field], $param);\r
+                               }\r
+                                                               \r
+                               // Did the rule test negatively?  If so, grab the error.\r
+                               if ($result === FALSE)\r
+                               {\r
+                                       if ( ! isset($this->_error_messages[$rule]))\r
+                                       {\r
+                                               if (FALSE === ($line = $this->CI->lang->line($rule)))\r
+                                               {\r
+                                                       $line = 'Unable to access an error message corresponding to your field name.';\r
+                                               }                                               \r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $line = $this->_error_messages[$rule];\r
+                                       }                               \r
+\r
+                                       // Build the error message\r
+                                       $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];\r
+                                       $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];\r
+                                       $message = sprintf($line, $mfield, $mparam);\r
+                                       \r
+                                       // Set the error variable.  Example: $this->username_error\r
+                                       $error = $field.'_error';\r
+                                       $this->$error = $this->_error_prefix.$message.$this->_error_suffix;\r
+\r
+                                       // Add the error to the error array\r
+                                       $this->_error_array[] = $message;                               \r
+                                       continue 2;\r
+                               }                               \r
+                       }\r
+                       \r
+               }\r
+               \r
+               $total_errors = count($this->_error_array);\r
+\r
+               /*\r
+                * Recompile the class variables\r
+                *\r
+                * If any prepping functions were called the $_POST data\r
+                * might now be different then the corresponding class\r
+                * variables so we'll set them anew.\r
+                */     \r
+               if ($total_errors > 0)\r
+               {\r
+                       $this->_safe_form_data = TRUE;\r
+               }\r
+               \r
+               $this->set_fields();\r
+\r
+               // Did we end up with any errors?\r
+               if ($total_errors == 0)\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               // Generate the error string\r
+               foreach ($this->_error_array as $val)\r
+               {\r
+                       $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";\r
+               }\r
+\r
+               return FALSE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Required\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function required($str)\r
+       {\r
+               if ( ! is_array($str))\r
+               {\r
+                       return (trim($str) == '') ? FALSE : TRUE;\r
+               }\r
+               else\r
+               {\r
+                       return ( ! empty($str));\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Match one field to another\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       field\r
+        * @return      bool\r
+        */\r
+       function matches($str, $field)\r
+       {\r
+               if ( ! isset($_POST[$field]))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return ($str !== $_POST[$field]) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Minimum Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function min_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) < $val) ? FALSE : TRUE;         \r
+               }\r
+\r
+               return (strlen($str) < $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Max Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function max_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) > $val) ? FALSE : TRUE;         \r
+               }\r
+\r
+               return (strlen($str) > $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Exact Length\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       value\r
+        * @return      bool\r
+        */     \r
+       function exact_length($str, $val)\r
+       {\r
+               if (preg_match("/[^0-9]/", $val))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               if (function_exists('mb_strlen'))\r
+               {\r
+                       return (mb_strlen($str) != $val) ? FALSE : TRUE;                \r
+               }\r
+\r
+               return (strlen($str) != $val) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Email\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function valid_email($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Emails\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function valid_emails($str)\r
+       {\r
+               if (strpos($str, ',') === FALSE)\r
+               {\r
+                       return $this->valid_email(trim($str));\r
+               }\r
+               \r
+               foreach(explode(',', $str) as $email)\r
+               {\r
+                       if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Validate IP Address\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function valid_ip($ip)\r
+       {\r
+               return $this->CI->input->valid_ip($ip);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */             \r
+       function alpha($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha-numeric\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function alpha_numeric($str)\r
+       {\r
+               return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Alpha-numeric with underscores and dashes\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function alpha_dash($str)\r
+       {\r
+               return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Numeric\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function numeric($str)\r
+       {\r
+               return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);\r
+\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Is Numeric\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function is_numeric($str)\r
+       {\r
+               return ( ! is_numeric($str)) ? FALSE : TRUE;\r
+       } \r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Integer\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */     \r
+       function integer($str)\r
+       {\r
+               return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Is a Natural number  (0,1,2,3, etc.)\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function is_natural($str)\r
+       {   \r
+               return (bool)preg_match( '/^[0-9]+$/', $str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Is a Natural number, but not a zero  (1,2,3, etc.)\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function is_natural_no_zero($str)\r
+       {   \r
+               if ( ! preg_match( '/^[0-9]+$/', $str))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       \r
+               if ($str == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Valid Base64\r
+        *\r
+        * Tests a string for characters outside of the Base64 alphabet\r
+        * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      bool\r
+        */\r
+       function valid_base64($str)\r
+       {\r
+               return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Select\r
+        *\r
+        * Enables pull-down lists to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_select($field = '', $value = '')\r
+       {\r
+               if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))\r
+               {\r
+                       return '';\r
+               }\r
+                       \r
+               if ($_POST[$field] == $value)\r
+               {\r
+                       return ' selected="selected"';\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Radio\r
+        *\r
+        * Enables radio buttons to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_radio($field = '', $value = '')\r
+       {\r
+               if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))\r
+               {\r
+                       return '';\r
+               }\r
+                       \r
+               if ($_POST[$field] == $value)\r
+               {\r
+                       return ' checked="checked"';\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Set Checkbox\r
+        *\r
+        * Enables checkboxes to be set to the value the user\r
+        * selected in the event of an error\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function set_checkbox($field = '', $value = '')\r
+       {\r
+               if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))\r
+               {\r
+                       return '';\r
+               }\r
+                       \r
+               if ($_POST[$field] == $value)\r
+               {\r
+                       return ' checked="checked"';\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep data for form\r
+        *\r
+        * This function allows HTML to be safely shown in a form.\r
+        * Special characters are converted.\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */\r
+       function prep_for_form($data = '')\r
+       {\r
+               if (is_array($data))\r
+               {\r
+                       foreach ($data as $key => $val)\r
+                       {\r
+                               $data[$key] = $this->prep_for_form($val);\r
+                       }\r
+                       \r
+                       return $data;\r
+               }\r
+               \r
+               if ($this->_safe_form_data == FALSE OR $data == '')\r
+               {\r
+                       return $data;\r
+               }\r
+\r
+               return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Prep URL\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function prep_url($str = '')\r
+       {\r
+               if ($str == 'http://' OR $str == '')\r
+               {\r
+                       $_POST[$this->_current_field] = '';\r
+                       return;\r
+               }\r
+               \r
+               if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')\r
+               {\r
+                       $str = 'http://'.$str;\r
+               }\r
+               \r
+               $_POST[$this->_current_field] = $str;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Strip Image Tags\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function strip_image_tags($str)\r
+       {\r
+               $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * XSS Clean\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function xss_clean($str)\r
+       {\r
+               $_POST[$this->_current_field] = $this->CI->input->xss_clean($str);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Convert PHP tags to entities\r
+        *\r
+        * @access      public\r
+        * @param       string\r
+        * @return      string\r
+        */     \r
+       function encode_php_tags($str)\r
+       {\r
+               $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);\r
+       }\r
+\r
+}\r
+// END Validation Class\r
+\r
+/* End of file Validation.php */\r
+/* Location: ./system/libraries/Validation.php */
\ No newline at end of file
diff --git a/libraries/Xmlrpc.php b/libraries/Xmlrpc.php
new file mode 100644 (file)
index 0000000..c9e7972
--- /dev/null
@@ -0,0 +1,1421 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+if ( ! function_exists('xml_parser_create'))\r
+{      \r
+       show_error('Your PHP installation does not support XML');\r
+}\r
+\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * XML-RPC request handler class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class CI_Xmlrpc {\r
+\r
+       var $debug                      = FALSE;        // Debugging on or off  \r
+       var $xmlrpcI4           = 'i4';\r
+       var $xmlrpcInt          = 'int';\r
+       var $xmlrpcBoolean      = 'boolean';\r
+       var $xmlrpcDouble       = 'double';     \r
+       var $xmlrpcString       = 'string';\r
+       var $xmlrpcDateTime     = 'datetime.iso8601';\r
+       var $xmlrpcBase64       = 'base64';\r
+       var $xmlrpcArray        = 'array';\r
+       var $xmlrpcStruct       = 'struct';\r
+       \r
+       var $xmlrpcTypes        = array();\r
+       var $valid_parents      = array();\r
+       var $xmlrpcerr          = array();      // Response numbers\r
+       var $xmlrpcstr          = array();  // Response strings\r
+       \r
+       var $xmlrpc_defencoding = 'UTF-8';\r
+       var $xmlrpcName                 = 'XML-RPC for CodeIgniter';\r
+       var $xmlrpcVersion              = '1.1';\r
+       var $xmlrpcerruser              = 800; // Start of user errors\r
+       var $xmlrpcerrxml               = 100; // Start of XML Parse errors\r
+       var $xmlrpc_backslash   = ''; // formulate backslashes for escaping regexp\r
+       \r
+       var $client;\r
+       var $method;\r
+       var $data;\r
+       var $message                    = '';\r
+       var $error                              = '';           // Error string for request\r
+       var $result;\r
+       var $response                   = array();  // Response from remote server\r
+\r
+\r
+       //-------------------------------------\r
+       //  VALUES THAT MULTIPLE CLASSES NEED\r
+       //-------------------------------------\r
+\r
+       function CI_Xmlrpc ($config = array())\r
+       {\r
+               $this->xmlrpcName               = $this->xmlrpcName;\r
+               $this->xmlrpc_backslash = chr(92).chr(92);\r
+               \r
+               // Types for info sent back and forth\r
+               $this->xmlrpcTypes = array(\r
+                       $this->xmlrpcI4    => '1',\r
+                       $this->xmlrpcInt          => '1',\r
+                       $this->xmlrpcBoolean  => '1',\r
+                       $this->xmlrpcString   => '1',\r
+                       $this->xmlrpcDouble   => '1',\r
+                       $this->xmlrpcDateTime => '1',\r
+                       $this->xmlrpcBase64   => '1',\r
+                       $this->xmlrpcArray      => '2',\r
+                       $this->xmlrpcStruct   => '3'\r
+                       );\r
+                       \r
+               // Array of Valid Parents for Various XML-RPC elements\r
+               $this->valid_parents = array('BOOLEAN'                  => array('VALUE'),\r
+                                                                        'I4'                           => array('VALUE'),\r
+                                                                        'INT'                          => array('VALUE'),\r
+                                                                        'STRING'                       => array('VALUE'),\r
+                                                                        'DOUBLE'                       => array('VALUE'),\r
+                                                                        'DATETIME.ISO8601'     => array('VALUE'),\r
+                                                                        'BASE64'                       => array('VALUE'),\r
+                                                                        'ARRAY'                        => array('VALUE'),\r
+                                                                        'STRUCT'                       => array('VALUE'),\r
+                                                                        'PARAM'                        => array('PARAMS'),\r
+                                                                        'METHODNAME'           => array('METHODCALL'),\r
+                                                                        'PARAMS'                       => array('METHODCALL', 'METHODRESPONSE'),\r
+                                                                        'MEMBER'                       => array('STRUCT'),\r
+                                                                        'NAME'                         => array('MEMBER'),\r
+                                                                        'DATA'                         => array('ARRAY'),\r
+                                                                        'FAULT'                        => array('METHODRESPONSE'),\r
+                                                                        'VALUE'                        => array('MEMBER', 'DATA', 'PARAM', 'FAULT')\r
+                                                                        );\r
+                       \r
+                       \r
+               // XML-RPC Responses\r
+               $this->xmlrpcerr['unknown_method'] = '1';\r
+               $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';\r
+               $this->xmlrpcerr['invalid_return'] = '2';\r
+               $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.';\r
+               $this->xmlrpcerr['incorrect_params'] = '3';\r
+               $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';\r
+               $this->xmlrpcerr['introspect_unknown'] = '4';\r
+               $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";\r
+               $this->xmlrpcerr['http_error'] = '5';\r
+               $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";\r
+               $this->xmlrpcerr['no_data'] = '6';\r
+               $this->xmlrpcstr['no_data'] ='No data received from server.';\r
+               \r
+               $this->initialize($config);\r
+               \r
+               log_message('debug', "XML-RPC Class Initialized");\r
+       }\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Initialize Prefs\r
+       //-------------------------------------\r
+\r
+       function initialize($config = array())\r
+       {\r
+               if (sizeof($config) > 0)\r
+               {\r
+                       foreach ($config as $key => $val)\r
+                       {\r
+                               if (isset($this->$key))\r
+                               {\r
+                                       $this->$key = $val;                     \r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Take URL and parse it\r
+       //-------------------------------------\r
+\r
+       function server($url, $port=80)\r
+       {\r
+               if (substr($url, 0, 4) != "http")\r
+               {\r
+                       $url = "http://".$url;\r
+               }\r
+               \r
+               $parts = parse_url($url);\r
+               \r
+               $path = ( ! isset($parts['path'])) ? '/' : $parts['path'];\r
+               \r
+               if (isset($parts['query']) && $parts['query'] != '')\r
+               {\r
+                       $path .= '?'.$parts['query'];\r
+               }       \r
+               \r
+               $this->client = new XML_RPC_Client($path, $parts['host'], $port);\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Set Timeout\r
+       //-------------------------------------\r
+\r
+       function timeout($seconds=5)\r
+       {\r
+               if ( ! is_null($this->client) && is_int($seconds))\r
+               {\r
+                       $this->client->timeout = $seconds;\r
+               }\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Set Methods\r
+       //-------------------------------------\r
+\r
+       function method($function)\r
+       {\r
+               $this->method = $function;\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Take Array of Data and Create Objects\r
+       //-------------------------------------\r
+\r
+       function request($incoming)\r
+       {\r
+               if ( ! is_array($incoming))\r
+               {\r
+                       // Send Error\r
+               }\r
+               \r
+               $this->data = array();\r
+               \r
+               foreach($incoming as $key => $value)\r
+               {\r
+                       $this->data[$key] = $this->values_parsing($value);\r
+               }\r
+       }\r
+       // END\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Set Debug\r
+       //-------------------------------------\r
+\r
+       function set_debug($flag = TRUE)\r
+       {\r
+               $this->debug = ($flag == TRUE) ? TRUE : FALSE;\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Values Parsing\r
+       //-------------------------------------\r
+\r
+       function values_parsing($value, $return = FALSE)\r
+       {\r
+               if (is_array($value) && isset($value['0']))\r
+               {\r
+                       if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])]))\r
+                       {\r
+                               if (is_array($value[0]))\r
+                               {\r
+                                       $temp = new XML_RPC_Values($value['0'], 'array');\r
+                               }\r
+                               else\r
+                               {\r
+                                       $temp = new XML_RPC_Values($value['0'], 'string');\r
+                               }\r
+                       }\r
+                       elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))\r
+                       {\r
+                               while (list($k) = each($value['0']))\r
+                               {\r
+                                       $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);\r
+                               }\r
+                               \r
+                               $temp = new XML_RPC_Values($value['0'], $value['1']);\r
+                       }\r
+                       else\r
+                       {\r
+                               $temp = new XML_RPC_Values($value['0'], $value['1']);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $temp = new XML_RPC_Values($value, 'string');\r
+               }\r
+\r
+               return $temp;\r
+       }\r
+       // END\r
+\r
+\r
+       //-------------------------------------\r
+       //  Sends XML-RPC Request\r
+       //-------------------------------------\r
+\r
+       function send_request()\r
+       {\r
+               $this->message = new XML_RPC_Message($this->method,$this->data);\r
+               $this->message->debug = $this->debug;\r
+       \r
+               if ( ! $this->result = $this->client->send($this->message))\r
+               {\r
+                       $this->error = $this->result->errstr;\r
+                       return FALSE;\r
+               }\r
+               elseif( ! is_object($this->result->val))\r
+               {\r
+                       $this->error = $this->result->errstr;\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->response = $this->result->decode();\r
+               \r
+               return TRUE;\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Returns Error\r
+       //-------------------------------------\r
+\r
+       function display_error()\r
+       {\r
+               return $this->error;\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Returns Remote Server Response\r
+       //-------------------------------------\r
+\r
+       function display_response()\r
+       {\r
+               return $this->response;\r
+       }\r
+       // END\r
+       \r
+       //-------------------------------------\r
+       //  Sends an Error Message for Server Request\r
+       //-------------------------------------\r
+       \r
+       function send_error_message($number, $message)\r
+       {\r
+               return new XML_RPC_Response('0',$number, $message);\r
+       }\r
+       // END\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Send Response for Server Request\r
+       //-------------------------------------\r
+       \r
+       function send_response($response)\r
+       {\r
+               // $response should be array of values, which will be parsed\r
+               // based on their data and type into a valid group of XML-RPC values\r
+               \r
+               $response = $this->values_parsing($response);\r
+       \r
+               return new XML_RPC_Response($response);\r
+       }\r
+       // END\r
+       \r
+} // END XML_RPC Class\r
+\r
+       \r
+       \r
+/**\r
+ * XML-RPC Client class\r
+ *\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class XML_RPC_Client extends CI_Xmlrpc\r
+{\r
+       var $path                       = '';\r
+       var $server                     = '';\r
+       var $port                       = 80;\r
+       var $errno                      = '';\r
+       var $errstring          = '';\r
+       var $timeout            = 5;\r
+       var $no_multicall       = false;\r
+\r
+       function XML_RPC_Client($path, $server, $port=80)\r
+       {\r
+               parent::CI_Xmlrpc();\r
+               \r
+               $this->port = $port;\r
+               $this->server = $server;\r
+               $this->path = $path;\r
+       }\r
+       \r
+       function send($msg)\r
+       {\r
+               if (is_array($msg))\r
+               {\r
+                       // Multi-call disabled\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);\r
+                       return $r;\r
+               }\r
+\r
+               return $this->sendPayload($msg);\r
+       }\r
+\r
+       function sendPayload($msg)\r
+       {       \r
+               $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);\r
+               \r
+               if ( ! is_resource($fp))\r
+               {\r
+                       error_log($this->xmlrpcstr['http_error']);\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);\r
+                       return $r;\r
+               }\r
+               \r
+               if(empty($msg->payload))\r
+               {\r
+                       // $msg = XML_RPC_Messages\r
+                       $msg->createPayload();\r
+               }\r
+               \r
+               $r = "\r\n";\r
+               $op  = "POST {$this->path} HTTP/1.0$r";\r
+               $op .= "Host: {$this->server}$r";\r
+               $op .= "Content-Type: text/xml$r";\r
+               $op .= "User-Agent: {$this->xmlrpcName}$r";\r
+               $op .= "Content-Length: ".strlen($msg->payload). "$r$r";\r
+               $op .= $msg->payload;\r
+               \r
+\r
+               if ( ! fputs($fp, $op, strlen($op)))\r
+               {\r
+                       error_log($this->xmlrpcstr['http_error']);\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);\r
+                       return $r;\r
+               }\r
+               $resp = $msg->parseResponse($fp);\r
+               fclose($fp);\r
+               return $resp;\r
+       }\r
+\r
+} // end class XML_RPC_Client\r
+\r
+\r
+/**\r
+ * XML-RPC Response class\r
+ *\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class XML_RPC_Response\r
+{\r
+       var $val = 0;\r
+       var $errno = 0;\r
+       var $errstr = '';\r
+       var $headers = array();\r
+\r
+       function XML_RPC_Response($val, $code = 0, $fstr = '')\r
+       {       \r
+               if ($code != 0)\r
+               {\r
+                       // error\r
+                       $this->errno = $code;\r
+                       $this->errstr = htmlentities($fstr);\r
+               }\r
+               else if ( ! is_object($val))\r
+               {\r
+                       // programmer error, not an object\r
+                       error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");\r
+                       $this->val = new XML_RPC_Values();\r
+               }\r
+               else\r
+               {\r
+                       $this->val = $val;\r
+               }\r
+       }\r
+\r
+       function faultCode()\r
+       {\r
+               return $this->errno;\r
+       }\r
+\r
+       function faultString()\r
+       {\r
+               return $this->errstr;\r
+       }\r
+\r
+       function value()\r
+       {\r
+               return $this->val;\r
+       }\r
+       \r
+       function prepare_response()\r
+       {\r
+               $result = "<methodResponse>\n";\r
+               if ($this->errno)\r
+               {\r
+                       $result .= '<fault>\r
+       <value>\r
+               <struct>\r
+                       <member>\r
+                               <name>faultCode</name>\r
+                               <value><int>' . $this->errno . '</int></value>\r
+                       </member>\r
+                       <member>\r
+                               <name>faultString</name>\r
+                               <value><string>' . $this->errstr . '</string></value>\r
+                       </member>\r
+               </struct>\r
+       </value>\r
+</fault>';\r
+               }\r
+               else\r
+               {\r
+                       $result .= "<params>\n<param>\n" .\r
+                                       $this->val->serialize_class() .\r
+                                       "</param>\n</params>";\r
+               }\r
+               $result .= "\n</methodResponse>";\r
+               return $result;\r
+       }\r
+       \r
+       function decode($array=FALSE)\r
+       {\r
+               $CI =& get_instance();\r
+\r
+               if ($array !== FALSE && is_array($array))\r
+               {\r
+                       while (list($key) = each($array))\r
+                       {\r
+                               if (is_array($array[$key]))\r
+                               {\r
+                                       $array[$key] = $this->decode($array[$key]);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $array[$key] = $CI->input->xss_clean($array[$key]);\r
+                               }\r
+                       }\r
+                       \r
+                       $result = $array;\r
+               }\r
+               else\r
+               {\r
+                       $result = $this->xmlrpc_decoder($this->val);\r
+                       \r
+                       if (is_array($result))\r
+                       {\r
+                               $result = $this->decode($result);\r
+                       }\r
+                       else\r
+                       {\r
+                               $result = $CI->input->xss_clean($result);\r
+                       }\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  XML-RPC Object to PHP Types\r
+       //-------------------------------------\r
+\r
+       function xmlrpc_decoder($xmlrpc_val)\r
+       {\r
+               $kind = $xmlrpc_val->kindOf();\r
+\r
+               if($kind == 'scalar')\r
+               {\r
+                       return $xmlrpc_val->scalarval();\r
+               }\r
+               elseif($kind == 'array')\r
+               {\r
+                       reset($xmlrpc_val->me);\r
+                       list($a,$b) = each($xmlrpc_val->me);\r
+                       $size = sizeof($b);\r
+                       \r
+                       $arr = array();\r
+\r
+                       for($i = 0; $i < $size; $i++)\r
+                       {\r
+                               $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);\r
+                       }\r
+                       return $arr;\r
+               }\r
+               elseif($kind == 'struct')\r
+               {\r
+                       reset($xmlrpc_val->me['struct']);\r
+                       $arr = array();\r
+\r
+                       while(list($key,$value) = each($xmlrpc_val->me['struct']))\r
+                       {\r
+                               $arr[$key] = $this->xmlrpc_decoder($value);\r
+                       }\r
+                       return $arr;\r
+               }\r
+       }\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  ISO-8601 time to server or UTC time\r
+       //-------------------------------------\r
+\r
+       function iso8601_decode($time, $utc=0)\r
+       {\r
+               // return a timet in the localtime, or UTC\r
+               $t = 0;\r
+               if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))\r
+               {\r
+                       if ($utc == 1)\r
+                               $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);\r
+                       else\r
+                               $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);\r
+               }\r
+               return $t;\r
+       }\r
+       \r
+} // End Response Class\r
+\r
+\r
+\r
+/**\r
+ * XML-RPC Message class\r
+ *\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class XML_RPC_Message extends CI_Xmlrpc\r
+{\r
+       var $payload;\r
+       var $method_name;\r
+       var $params                     = array();\r
+       var $xh                         = array();\r
+\r
+       function XML_RPC_Message($method, $pars=0)\r
+       {\r
+               parent::CI_Xmlrpc();\r
+               \r
+               $this->method_name = $method;\r
+               if (is_array($pars) && sizeof($pars) > 0)\r
+               {\r
+                       for($i=0; $i<sizeof($pars); $i++)\r
+                       {\r
+                               // $pars[$i] = XML_RPC_Values\r
+                               $this->params[] = $pars[$i];\r
+                       }\r
+               }\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Create Payload to Send\r
+       //-------------------------------------\r
+       \r
+       function createPayload()\r
+       {\r
+               $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";\r
+               $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";\r
+               $this->payload .= "<params>\r\n";\r
+               \r
+               for($i=0; $i<sizeof($this->params); $i++)\r
+               {\r
+                       // $p = XML_RPC_Values\r
+                       $p = $this->params[$i];\r
+                       $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";\r
+               }\r
+               \r
+               $this->payload .= "</params>\r\n</methodCall>\r\n";\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Parse External XML-RPC Server's Response\r
+       //-------------------------------------\r
+       \r
+       function parseResponse($fp)\r
+       {\r
+               $data = '';\r
+               \r
+               while($datum = fread($fp, 4096))\r
+               {\r
+                       $data .= $datum;\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  DISPLAY HTTP CONTENT for DEBUGGING\r
+               //-------------------------------------\r
+               \r
+               if ($this->debug === TRUE)\r
+               {\r
+                       echo "<pre>";\r
+                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";\r
+                       echo "</pre>";\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  Check for data\r
+               //-------------------------------------\r
+\r
+               if($data == "")\r
+               {\r
+                       error_log($this->xmlrpcstr['no_data']);\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);\r
+                       return $r;\r
+               }\r
+               \r
+               \r
+               //-------------------------------------\r
+               //  Check for HTTP 200 Response\r
+               //-------------------------------------\r
+               \r
+               if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))\r
+               {\r
+                       $errstr= substr($data, 0, strpos($data, "\n")-1);\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');\r
+                       return $r;\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  Create and Set Up XML Parser\r
+               //-------------------------------------\r
+       \r
+               $parser = xml_parser_create($this->xmlrpc_defencoding);\r
+\r
+               $this->xh[$parser]                               = array();\r
+               $this->xh[$parser]['isf']                = 0;\r
+               $this->xh[$parser]['ac']                 = '';\r
+               $this->xh[$parser]['headers']    = array();\r
+               $this->xh[$parser]['stack']              = array();\r
+               $this->xh[$parser]['valuestack'] = array();\r
+               $this->xh[$parser]['isf_reason'] = 0;\r
+\r
+               xml_set_object($parser, $this);\r
+               xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
+               xml_set_element_handler($parser, 'open_tag', 'closing_tag');\r
+               xml_set_character_data_handler($parser, 'character_data');\r
+               //xml_set_default_handler($parser, 'default_handler');\r
+\r
+\r
+               //-------------------------------------\r
+               //  GET HEADERS\r
+               //-------------------------------------\r
+               \r
+               $lines = explode("\r\n", $data);\r
+               while (($line = array_shift($lines)))\r
+               {\r
+                       if (strlen($line) < 1)\r
+                       {\r
+                               break;\r
+                       }\r
+                       $this->xh[$parser]['headers'][] = $line;\r
+               }\r
+               $data = implode("\r\n", $lines);\r
+               \r
+               \r
+               //-------------------------------------\r
+               //  PARSE XML DATA\r
+               //-------------------------------------         \r
+\r
+               if ( ! xml_parse($parser, $data, sizeof($data)))\r
+               {\r
+                       $errstr = sprintf('XML error: %s at line %d',\r
+                                       xml_error_string(xml_get_error_code($parser)),\r
+                                       xml_get_current_line_number($parser));\r
+                       //error_log($errstr);\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);\r
+                       xml_parser_free($parser);\r
+                       return $r;\r
+               }\r
+               xml_parser_free($parser);\r
+               \r
+               // ---------------------------------------\r
+               //  Got Ourselves Some Badness, It Seems\r
+               // ---------------------------------------\r
+               \r
+               if ($this->xh[$parser]['isf'] > 1)\r
+               {\r
+                       if ($this->debug === TRUE)\r
+                       {\r
+                               echo "---Invalid Return---\n";\r
+                               echo $this->xh[$parser]['isf_reason'];\r
+                               echo "---Invalid Return---\n\n";\r
+                       }\r
+                               \r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);\r
+                       return $r;\r
+               }\r
+               elseif ( ! is_object($this->xh[$parser]['value']))\r
+               {\r
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);\r
+                       return $r;\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  DISPLAY XML CONTENT for DEBUGGING\r
+               //-------------------------------------         \r
+               \r
+               if ($this->debug === TRUE)\r
+               {\r
+                       echo "<pre>";\r
+                       \r
+                       if (count($this->xh[$parser]['headers'] > 0))\r
+                       {\r
+                               echo "---HEADERS---\n";\r
+                               foreach ($this->xh[$parser]['headers'] as $header)\r
+                               {\r
+                                       echo "$header\n";\r
+                               }\r
+                               echo "---END HEADERS---\n\n";\r
+                       }\r
+                       \r
+                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";\r
+                       \r
+                       echo "---PARSED---\n" ;\r
+                       var_dump($this->xh[$parser]['value']);\r
+                       echo "\n---END PARSED---</pre>";\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  SEND RESPONSE\r
+               //-------------------------------------\r
+               \r
+               $v = $this->xh[$parser]['value'];\r
+                       \r
+               if ($this->xh[$parser]['isf'])\r
+               {\r
+                       $errno_v = $v->me['struct']['faultCode'];\r
+                       $errstr_v = $v->me['struct']['faultString'];\r
+                       $errno = $errno_v->scalarval();\r
+\r
+                       if ($errno == 0)\r
+                       {\r
+                               // FAULT returned, errno needs to reflect that\r
+                               $errno = -1;\r
+                       }\r
+\r
+                       $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());\r
+               }\r
+               else\r
+               {\r
+                       $r = new XML_RPC_Response($v);\r
+               }\r
+\r
+               $r->headers = $this->xh[$parser]['headers'];\r
+               return $r;\r
+       }\r
+       \r
+       // ------------------------------------\r
+       //  Begin Return Message Parsing section\r
+       // ------------------------------------\r
+       \r
+       // quick explanation of components:\r
+       //   ac - used to accumulate values\r
+       //   isf - used to indicate a fault\r
+       //   lv - used to indicate "looking for a value": implements\r
+       //              the logic to allow values with no types to be strings\r
+       //   params - used to store parameters in method calls\r
+       //   method - used to store method name\r
+       //       stack - array with parent tree of the xml element,\r
+       //                       used to validate the nesting of elements\r
+\r
+       //-------------------------------------\r
+       //  Start Element Handler\r
+       //-------------------------------------\r
+\r
+       function open_tag($the_parser, $name, $attrs)\r
+       {\r
+               // If invalid nesting, then return\r
+               if ($this->xh[$the_parser]['isf'] > 1) return;\r
+               \r
+               // Evaluate and check for correct nesting of XML elements\r
+               \r
+               if (count($this->xh[$the_parser]['stack']) == 0)\r
+               {\r
+                       if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')\r
+                       {\r
+                               $this->xh[$the_parser]['isf'] = 2;\r
+                               $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';\r
+                               return;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // not top level element: see if parent is OK\r
+                       if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))\r
+                       {\r
+                               $this->xh[$the_parser]['isf'] = 2;\r
+                               $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];\r
+                               return;\r
+                       }\r
+               }\r
+               \r
+               switch($name)\r
+               {\r
+                       case 'STRUCT':\r
+                       case 'ARRAY':\r
+                               // Creates array for child elements\r
+                               \r
+                               $cur_val = array('value' => array(),\r
+                                                                'type'  => $name);\r
+                                                               \r
+                               array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);\r
+                       break;\r
+                       case 'METHODNAME':\r
+                       case 'NAME':\r
+                               $this->xh[$the_parser]['ac'] = '';\r
+                       break;\r
+                       case 'FAULT':\r
+                               $this->xh[$the_parser]['isf'] = 1;\r
+                       break;\r
+                       case 'PARAM':\r
+                               $this->xh[$the_parser]['value'] = null;\r
+                       break;\r
+                       case 'VALUE':\r
+                               $this->xh[$the_parser]['vt'] = 'value';\r
+                               $this->xh[$the_parser]['ac'] = '';\r
+                               $this->xh[$the_parser]['lv'] = 1;\r
+                       break;\r
+                       case 'I4':\r
+                       case 'INT':\r
+                       case 'STRING':\r
+                       case 'BOOLEAN':\r
+                       case 'DOUBLE':\r
+                       case 'DATETIME.ISO8601':\r
+                       case 'BASE64':\r
+                               if ($this->xh[$the_parser]['vt'] != 'value')\r
+                               {\r
+                                       //two data elements inside a value: an error occurred!\r
+                                       $this->xh[$the_parser]['isf'] = 2;\r
+                                       $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";\r
+                                       return;\r
+                               }\r
+                               \r
+                               $this->xh[$the_parser]['ac'] = '';\r
+                       break;\r
+                       case 'MEMBER':\r
+                               // Set name of <member> to nothing to prevent errors later if no <name> is found\r
+                               $this->xh[$the_parser]['valuestack'][0]['name'] = '';\r
+                               \r
+                               // Set NULL value to check to see if value passed for this param/member\r
+                               $this->xh[$the_parser]['value'] = null;\r
+                       break;\r
+                       case 'DATA':\r
+                       case 'METHODCALL':\r
+                       case 'METHODRESPONSE':\r
+                       case 'PARAMS':\r
+                               // valid elements that add little to processing\r
+                       break;\r
+                       default:\r
+                               /// An Invalid Element is Found, so we have trouble\r
+                               $this->xh[$the_parser]['isf'] = 2;\r
+                               $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";\r
+                       break;\r
+               }\r
+               \r
+               // Add current element name to stack, to allow validation of nesting\r
+               array_unshift($this->xh[$the_parser]['stack'], $name);\r
+\r
+               if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;\r
+       }\r
+       // END\r
+\r
+\r
+       //-------------------------------------\r
+       //  End Element Handler\r
+       //-------------------------------------\r
+\r
+       function closing_tag($the_parser, $name)\r
+       {\r
+               if ($this->xh[$the_parser]['isf'] > 1) return;\r
+               \r
+               // Remove current element from stack and set variable\r
+               // NOTE: If the XML validates, then we do not have to worry about\r
+               // the opening and closing of elements.  Nesting is checked on the opening\r
+               // tag so we be safe there as well.\r
+               \r
+               $curr_elem = array_shift($this->xh[$the_parser]['stack']);\r
+       \r
+               switch($name)\r
+               {\r
+                       case 'STRUCT':\r
+                       case 'ARRAY':\r
+                               $cur_val = array_shift($this->xh[$the_parser]['valuestack']);\r
+                               $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];\r
+                               $this->xh[$the_parser]['vt']    = strtolower($name);\r
+                       break;\r
+                       case 'NAME':\r
+                               $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];\r
+                       break;\r
+                       case 'BOOLEAN':\r
+                       case 'I4':\r
+                       case 'INT':\r
+                       case 'STRING':\r
+                       case 'DOUBLE':\r
+                       case 'DATETIME.ISO8601':\r
+                       case 'BASE64':\r
+                               $this->xh[$the_parser]['vt'] = strtolower($name);\r
+                               \r
+                               if ($name == 'STRING')\r
+                               {\r
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
+                               }\r
+                               elseif ($name=='DATETIME.ISO8601')\r
+                               {\r
+                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcDateTime;\r
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
+                               }\r
+                               elseif ($name=='BASE64')\r
+                               {\r
+                                       $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);\r
+                               }\r
+                               elseif ($name=='BOOLEAN')\r
+                               {\r
+                                       // Translated BOOLEAN values to TRUE AND FALSE\r
+                                       if ($this->xh[$the_parser]['ac'] == '1')\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = TRUE;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = FALSE;\r
+                                       }\r
+                               }\r
+                               elseif ($name=='DOUBLE')\r
+                               {\r
+                                       // we have a DOUBLE\r
+                                       // we must check that only 0123456789-.<space> are characters here\r
+                                       if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       // we have an I4/INT\r
+                                       // we must check that only 0123456789-<space> are characters here\r
+                                       if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];\r
+                                       }\r
+                               }\r
+                               $this->xh[$the_parser]['ac'] = '';\r
+                               $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value\r
+                       break;\r
+                       case 'VALUE':\r
+                               // This if() detects if no scalar was inside <VALUE></VALUE>\r
+                               if ($this->xh[$the_parser]['vt']=='value')\r
+                               {\r
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
+                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcString;\r
+                               }\r
+                               \r
+                               // build the XML-RPC value out of the data received, and substitute it\r
+                               $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);\r
+                               \r
+                               if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')\r
+                               {\r
+                                       // Array\r
+                                       $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;\r
+                               }\r
+                               else\r
+                               {\r
+                                       // Struct\r
+                                       $this->xh[$the_parser]['value'] = $temp;\r
+                               }\r
+                       break;\r
+                       case 'MEMBER':\r
+                               $this->xh[$the_parser]['ac']='';\r
+                               \r
+                               // If value add to array in the stack for the last element built\r
+                               if ($this->xh[$the_parser]['value'])\r
+                               {\r
+                                       $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];\r
+                               }\r
+                       break;\r
+                       case 'DATA':\r
+                               $this->xh[$the_parser]['ac']='';\r
+                       break;\r
+                       case 'PARAM':\r
+                               if ($this->xh[$the_parser]['value'])\r
+                               {\r
+                                       $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];\r
+                               }\r
+                       break;\r
+                       case 'METHODNAME':\r
+                               $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);\r
+                       break;\r
+                       case 'PARAMS':\r
+                       case 'FAULT':\r
+                       case 'METHODCALL':\r
+                       case 'METHORESPONSE':\r
+                               // We're all good kids with nuthin' to do\r
+                       break;\r
+                       default:\r
+                               // End of an Invalid Element.  Taken care of during the opening tag though\r
+                       break;\r
+               }\r
+       }\r
+\r
+       //-------------------------------------\r
+       //  Parses Character Data\r
+       //-------------------------------------\r
+\r
+       function character_data($the_parser, $data)\r
+       {\r
+               if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already\r
+               \r
+               // If a value has not been found\r
+               if ($this->xh[$the_parser]['lv'] != 3)\r
+               {\r
+                       if ($this->xh[$the_parser]['lv'] == 1)\r
+                       {\r
+                               $this->xh[$the_parser]['lv'] = 2; // Found a value\r
+                       }\r
+                               \r
+                       if( ! @isset($this->xh[$the_parser]['ac']))\r
+                       {\r
+                               $this->xh[$the_parser]['ac'] = '';\r
+                       }\r
+                               \r
+                       $this->xh[$the_parser]['ac'] .= $data;\r
+               }\r
+       }\r
+       \r
+       \r
+       function addParam($par) { $this->params[]=$par; }\r
+       \r
+       function output_parameters($array=FALSE)\r
+       {\r
+               $CI =& get_instance();  \r
+\r
+               if ($array !== FALSE && is_array($array))\r
+               {\r
+                       while (list($key) = each($array))\r
+                       {\r
+                               if (is_array($array[$key]))\r
+                               {\r
+                                       $array[$key] = $this->output_parameters($array[$key]);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $array[$key] = $CI->input->xss_clean($array[$key]);\r
+                               }\r
+                       }\r
+                       \r
+                       $parameters = $array;\r
+               }\r
+               else\r
+               {\r
+                       $parameters = array();\r
+               \r
+                       for ($i = 0; $i < sizeof($this->params); $i++)\r
+                       {\r
+                               $a_param = $this->decode_message($this->params[$i]);\r
+                               \r
+                               if (is_array($a_param))\r
+                               {\r
+                                       $parameters[] = $this->output_parameters($a_param);\r
+                               }\r
+                               else\r
+                               {\r
+                                       $parameters[] = $CI->input->xss_clean($a_param);\r
+                               }\r
+                       }       \r
+               }\r
+               \r
+               return $parameters;\r
+       }\r
+       \r
+       \r
+       function decode_message($param)\r
+       {\r
+               $kind = $param->kindOf();\r
+\r
+               if($kind == 'scalar')\r
+               {\r
+                       return $param->scalarval();\r
+               }\r
+               elseif($kind == 'array')\r
+               {\r
+                       reset($param->me);\r
+                       list($a,$b) = each($param->me);\r
+                       \r
+                       $arr = array();\r
+\r
+                       for($i = 0; $i < sizeof($b); $i++)\r
+                       {\r
+                               $arr[] = $this->decode_message($param->me['array'][$i]);\r
+                       }\r
+                       \r
+                       return $arr;\r
+               }\r
+               elseif($kind == 'struct')\r
+               {\r
+                       reset($param->me['struct']);\r
+                       \r
+                       $arr = array();\r
+\r
+                       while(list($key,$value) = each($param->me['struct']))\r
+                       {\r
+                               $arr[$key] = $this->decode_message($value);\r
+                       }\r
+                       \r
+                       return $arr;\r
+               }\r
+       }\r
+       \r
+} // End XML_RPC_Messages class\r
+\r
+\r
+\r
+/**\r
+ * XML-RPC Values class\r
+ *\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class XML_RPC_Values extends CI_Xmlrpc\r
+{\r
+       var $me         = array();\r
+       var $mytype     = 0;\r
+\r
+       function XML_RPC_Values($val=-1, $type='')\r
+       {       \r
+               parent::CI_Xmlrpc();\r
+               \r
+               if ($val != -1 OR $type != '')\r
+               {\r
+                       $type = $type == '' ? 'string' : $type;\r
+                       \r
+                       if ($this->xmlrpcTypes[$type] == 1)\r
+                       {\r
+                               $this->addScalar($val,$type);\r
+                       }\r
+                       elseif ($this->xmlrpcTypes[$type] == 2)\r
+                       {\r
+                               $this->addArray($val);\r
+                       }\r
+                       elseif ($this->xmlrpcTypes[$type] == 3)\r
+                       {\r
+                               $this->addStruct($val);\r
+                       }\r
+               }\r
+       }\r
+\r
+       function addScalar($val, $type='string')\r
+       {\r
+               $typeof = $this->xmlrpcTypes[$type];\r
+               \r
+               if ($this->mytype==1)\r
+               {\r
+                       echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';\r
+                       return 0;\r
+               }\r
+               \r
+               if ($typeof != 1)\r
+               {\r
+                       echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';\r
+                       return 0;\r
+               }\r
+\r
+               if ($type == $this->xmlrpcBoolean)\r
+               {\r
+                       if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))\r
+                       {\r
+                               $val = 1;\r
+                       }\r
+                       else\r
+                       {\r
+                               $val=0;\r
+                       }\r
+               }\r
+\r
+               if ($this->mytype == 2)\r
+               {\r
+                       // adding to an array here\r
+                       $ar = $this->me['array'];\r
+                       $ar[] = new XML_RPC_Values($val, $type);\r
+                       $this->me['array'] = $ar;\r
+               }\r
+               else\r
+               {\r
+                       // a scalar, so set the value and remember we're scalar\r
+                       $this->me[$type] = $val;\r
+                       $this->mytype = $typeof;\r
+               }\r
+               return 1;\r
+       }\r
+\r
+       function addArray($vals)\r
+       {\r
+               if ($this->mytype != 0)\r
+               {\r
+                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';\r
+                       return 0;\r
+               }\r
+\r
+               $this->mytype = $this->xmlrpcTypes['array'];\r
+               $this->me['array'] = $vals;\r
+               return 1;\r
+       }\r
+\r
+       function addStruct($vals)\r
+       {\r
+               if ($this->mytype != 0)\r
+               {\r
+                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';\r
+                       return 0;\r
+               }\r
+               $this->mytype = $this->xmlrpcTypes['struct'];\r
+               $this->me['struct'] = $vals;\r
+               return 1;\r
+       }\r
+\r
+       function kindOf()\r
+       {\r
+               switch($this->mytype)\r
+               {\r
+                       case 3:\r
+                               return 'struct';\r
+                               break;\r
+                       case 2:\r
+                               return 'array';\r
+                               break;\r
+                       case 1:\r
+                               return 'scalar';\r
+                               break;\r
+                       default:\r
+                               return 'undef';\r
+               }\r
+       }\r
+\r
+       function serializedata($typ, $val)\r
+       {\r
+               $rs = '';\r
+               \r
+               switch($this->xmlrpcTypes[$typ])\r
+               {\r
+                       case 3:\r
+                               // struct\r
+                               $rs .= "<struct>\n";\r
+                               reset($val);\r
+                               while(list($key2, $val2) = each($val))\r
+                               {\r
+                                       $rs .= "<member>\n<name>{$key2}</name>\n";\r
+                                       $rs .= $this->serializeval($val2);\r
+                                       $rs .= "</member>\n";\r
+                               }\r
+                               $rs .= '</struct>';\r
+                       break;\r
+                       case 2:\r
+                               // array\r
+                               $rs .= "<array>\n<data>\n";\r
+                               for($i=0; $i < sizeof($val); $i++)\r
+                               {\r
+                                       $rs .= $this->serializeval($val[$i]);\r
+                               }\r
+                               $rs.="</data>\n</array>\n";\r
+                               break;\r
+                       case 1:\r
+                               // others\r
+                               switch ($typ)\r
+                               {\r
+                                       case $this->xmlrpcBase64:\r
+                                               $rs .= "<{$typ}>" . base64_encode($val) . "</{$typ}>\n";\r
+                                       break;\r
+                                       case $this->xmlrpcBoolean:\r
+                                               $rs .= "<{$typ}>" . ($val ? '1' : '0') . "</{$typ}>\n";\r
+                                       break;\r
+                                       case $this->xmlrpcString:\r
+                                               $rs .= "<{$typ}>" . htmlspecialchars($val). "</{$typ}>\n";\r
+                                       break;\r
+                                       default:\r
+                                               $rs .= "<{$typ}>{$val}</{$typ}>\n";\r
+                                       break;\r
+                               }\r
+                       default:\r
+                       break;\r
+               }\r
+               return $rs;\r
+       }\r
+\r
+       function serialize_class()\r
+       {\r
+               return $this->serializeval($this);\r
+       }\r
+\r
+       function serializeval($o)\r
+       {\r
+               $ar = $o->me;\r
+               reset($ar);\r
+               \r
+               list($typ, $val) = each($ar);\r
+               $rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";\r
+               return $rs;\r
+       }\r
+       \r
+       function scalarval()\r
+       {\r
+               reset($this->me);\r
+               list($a,$b) = each($this->me);\r
+               return $b;\r
+       }\r
+\r
+\r
+       //-------------------------------------\r
+       // Encode time in ISO-8601 form.\r
+       //-------------------------------------\r
+       \r
+       // Useful for sending time in XML-RPC\r
+\r
+       function iso8601_encode($time, $utc=0)\r
+       {       \r
+               if ($utc == 1)\r
+               {\r
+                       $t = strftime("%Y%m%dT%H:%M:%S", $time);\r
+               }\r
+               else\r
+               {\r
+                       if (function_exists('gmstrftime'))\r
+                               $t = gmstrftime("%Y%m%dT%H:%M:%S", $time);\r
+                       else\r
+                               $t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z'));\r
+               }\r
+               return $t;\r
+       }\r
+       \r
+}\r
+// END XML_RPC_Values Class\r
+\r
+/* End of file Xmlrpc.php */\r
+/* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file
diff --git a/libraries/Xmlrpcs.php b/libraries/Xmlrpcs.php
new file mode 100644 (file)
index 0000000..a210183
--- /dev/null
@@ -0,0 +1,536 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+if ( ! function_exists('xml_parser_create'))\r
+{      \r
+       show_error('Your PHP installation does not support XML');\r
+}\r
+\r
+if ( ! class_exists('CI_Xmlrpc'))\r
+{\r
+       show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');\r
+}\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * XML-RPC server class\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   XML-RPC\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
+ */\r
+class CI_Xmlrpcs extends CI_Xmlrpc\r
+{\r
+       var $methods            = array();      //array of methods mapped to function names and signatures\r
+       var $debug_msg          = '';           // Debug Message\r
+       var $system_methods = array(); // XML RPC Server methods\r
+       var $controller_obj;\r
+\r
+       var $object                     = FALSE;\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Constructor, more or less\r
+       //-------------------------------------\r
+\r
+       function CI_Xmlrpcs($config=array())\r
+       {       \r
+               parent::CI_Xmlrpc();\r
+               $this->set_system_methods();\r
+       \r
+               if (isset($config['functions']) && is_array($config['functions']))\r
+               {\r
+                       $this->methods = array_merge($this->methods, $config['functions']);\r
+               }\r
+               \r
+               log_message('debug', "XML-RPC Server Class Initialized");\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Initialize Prefs and Serve\r
+       //-------------------------------------\r
+       \r
+       function initialize($config=array())\r
+       {       \r
+               if (isset($config['functions']) && is_array($config['functions']))\r
+               {\r
+                       $this->methods = array_merge($this->methods, $config['functions']);\r
+               }\r
+               \r
+               if (isset($config['debug']))\r
+               {\r
+                       $this->debug = $config['debug'];\r
+               }\r
+               \r
+               if (isset($config['object']) && is_object($config['object']))\r
+               {\r
+                       $this->object = $config['object'];\r
+               }\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Setting of System Methods\r
+       //-------------------------------------\r
+       \r
+       function set_system_methods ()\r
+       {\r
+               $this->methods = array(\r
+                                       'system.listMethods'     => array(\r
+                                                                                                       'function' => 'this.listMethods',\r
+                                                                                                       'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),\r
+                                                                                                       'docstring' => 'Returns an array of available methods on this server'),\r
+                                       'system.methodHelp'              => array(\r
+                                                                                                       'function' => 'this.methodHelp',\r
+                                                                                                       'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),\r
+                                                                                                       'docstring' => 'Returns a documentation string for the specified method'),\r
+                                       'system.methodSignature' => array(\r
+                                                                                                       'function' => 'this.methodSignature',\r
+                                                                                                       'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),\r
+                                                                                                       'docstring' => 'Returns an array describing the return type and required parameters of a method'),\r
+                                       'system.multicall'               => array(\r
+                                                                                               'function' => 'this.multicall',\r
+                                                                                               'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),\r
+                                                                                               'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')\r
+                                       );\r
+       }\r
+\r
+\r
+       //-------------------------------------\r
+       //  Main Server Function\r
+       //-------------------------------------\r
+       \r
+       function serve()\r
+       {\r
+               $r = $this->parseRequest();\r
+               $payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";\r
+               $payload .= $this->debug_msg;\r
+               $payload .= $r->prepare_response();\r
+               \r
+               header("Content-Type: text/xml");\r
+               header("Content-Length: ".strlen($payload));\r
+               echo $payload;\r
+       }\r
+\r
+       //-------------------------------------\r
+       //  Add Method to Class\r
+       //-------------------------------------\r
+       \r
+       function add_to_map($methodname,$function,$sig,$doc)\r
+       {\r
+               $this->methods[$methodname] = array(\r
+                       'function'  => $function,\r
+                       'signature' => $sig,\r
+                       'docstring' => $doc\r
+               );\r
+       }\r
+\r
+\r
+       //-------------------------------------\r
+       //  Parse Server Request\r
+       //-------------------------------------\r
+       \r
+       function parseRequest($data='')\r
+       {\r
+               global $HTTP_RAW_POST_DATA;\r
+               \r
+               //-------------------------------------\r
+               //  Get Data\r
+               //-------------------------------------\r
+\r
+               if ($data == '')\r
+               {\r
+                       $data = $HTTP_RAW_POST_DATA;\r
+               }\r
+\r
+               //-------------------------------------\r
+               //  Set up XML Parser\r
+               //-------------------------------------\r
+               \r
+               $parser = xml_parser_create($this->xmlrpc_defencoding);\r
+               $parser_object = new XML_RPC_Message("filler");\r
+               \r
+               $parser_object->xh[$parser]                                     = array();\r
+               $parser_object->xh[$parser]['isf']                      = 0;\r
+               $parser_object->xh[$parser]['isf_reason']       = '';\r
+               $parser_object->xh[$parser]['params']           = array();\r
+               $parser_object->xh[$parser]['stack']            = array();\r
+               $parser_object->xh[$parser]['valuestack']       = array();\r
+               $parser_object->xh[$parser]['method']           = '';\r
+\r
+               xml_set_object($parser, $parser_object);\r
+               xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
+               xml_set_element_handler($parser, 'open_tag', 'closing_tag');\r
+               xml_set_character_data_handler($parser, 'character_data');\r
+               //xml_set_default_handler($parser, 'default_handler');\r
+               \r
+               \r
+               //-------------------------------------\r
+               //  PARSE + PROCESS XML DATA\r
+               //-------------------------------------         \r
+               \r
+               if ( ! xml_parse($parser, $data, 1))\r
+               {\r
+                       // return XML error as a faultCode\r
+                       $r = new XML_RPC_Response(0,\r
+                       $this->xmlrpcerrxml + xml_get_error_code($parser),\r
+                       sprintf('XML error: %s at line %d',\r
+                               xml_error_string(xml_get_error_code($parser)),\r
+                               xml_get_current_line_number($parser)));\r
+                       xml_parser_free($parser);\r
+               }\r
+               elseif($parser_object->xh[$parser]['isf'])\r
+               {\r
+                       return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);\r
+               }\r
+               else\r
+               {\r
+                       xml_parser_free($parser);\r
+                       \r
+                       $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);\r
+                       $plist='';\r
+                       \r
+                       for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++)\r
+                       {\r
+                               if ($this->debug === TRUE)\r
+                               {\r
+                                       $plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";\r
+                               }\r
+                               \r
+                               $m->addParam($parser_object->xh[$parser]['params'][$i]);\r
+                       }\r
+                       \r
+                       if ($this->debug === TRUE)\r
+                       {\r
+                               echo "<pre>";\r
+                               echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";\r
+                               echo "</pre>";\r
+                       }\r
+                       \r
+                       $r = $this->_execute($m);\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  SET DEBUGGING MESSAGE\r
+               //-------------------------------------         \r
+               \r
+               if ($this->debug === TRUE)\r
+               {\r
+                       $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";\r
+               }\r
+               \r
+               return $r;\r
+       }\r
+\r
+       //-------------------------------------\r
+       //  Executes the Method\r
+       //-------------------------------------\r
+       \r
+       function _execute($m)\r
+       {\r
+               $methName = $m->method_name;\r
+               \r
+               // Check to see if it is a system call\r
+               $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;\r
+               \r
+               //-------------------------------------\r
+               //  Valid Method\r
+               //-------------------------------------\r
+               \r
+               if ( ! isset($this->methods[$methName]['function']))\r
+               {\r
+                       return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  Check for Method (and Object)\r
+               //-------------------------------------\r
+                       \r
+               $method_parts = explode(".", $this->methods[$methName]['function']);\r
+               $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;\r
+               \r
+               if ($system_call === TRUE)\r
+               {\r
+                       if ( ! is_callable(array($this,$method_parts['1'])))\r
+                       {\r
+                               return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))\r
+                       {\r
+                               return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);\r
+                       }\r
+                       elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))\r
+                       {\r
+                               return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);\r
+                       }\r
+               }\r
+               \r
+               //-------------------------------------\r
+               //  Checking Methods Signature\r
+               //-------------------------------------\r
+               \r
+               if (isset($this->methods[$methName]['signature']))\r
+               {\r
+                       $sig = $this->methods[$methName]['signature'];\r
+                       for($i=0; $i<sizeof($sig); $i++)\r
+                       {\r
+                               $current_sig = $sig[$i];\r
+               \r
+                               if (sizeof($current_sig) == sizeof($m->params)+1)\r
+                               {\r
+                                       for($n=0; $n < sizeof($m->params); $n++)\r
+                                       {\r
+                                               $p = $m->params[$n];\r
+                                               $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();\r
+                                               \r
+                                               if ($pt != $current_sig[$n+1])\r
+                                               {\r
+                                                       $pno = $n+1;\r
+                                                       $wanted = $current_sig[$n+1];\r
+                                                       \r
+                                                       return new XML_RPC_Response(0,\r
+                                                               $this->xmlrpcerr['incorrect_params'],\r
+                                                               $this->xmlrpcstr['incorrect_params'] .\r
+                                                               ": Wanted {$wanted}, got {$pt} at param {$pno})");\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               //-------------------------------------\r
+               //  Calls the Function\r
+               //-------------------------------------\r
+\r
+               if ($objectCall === TRUE)\r
+               {\r
+                       if ($method_parts[0] == "this" && $system_call == TRUE)\r
+                       {\r
+                               return call_user_func(array($this, $method_parts[1]), $m);\r
+                       }\r
+                       else\r
+                       {\r
+                               if ($this->object === FALSE)\r
+                               {\r
+                                       $CI =& get_instance();\r
+                                       return $CI->$method_parts['1']($m);\r
+                               }\r
+                               else\r
+                               {\r
+                                       return $this->object->$method_parts['1']($m);\r
+                                       //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       return call_user_func($this->methods[$methName]['function'], $m);\r
+               }\r
+       }\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Server Function:  List Methods\r
+       //-------------------------------------\r
+       \r
+       function listMethods($m)\r
+       {\r
+               $v = new XML_RPC_Values();\r
+               $output = array();\r
+               \r
+               foreach($this->methods as $key => $value)\r
+               {\r
+                       $output[] = new XML_RPC_Values($key, 'string');\r
+               }\r
+               \r
+               foreach($this->system_methods as $key => $value)\r
+               {\r
+                       $output[]= new XML_RPC_Values($key, 'string');\r
+               }\r
+\r
+               $v->addArray($output);\r
+               return new XML_RPC_Response($v);\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Server Function:  Return Signature for Method\r
+       //-------------------------------------\r
+               \r
+       function methodSignature($m)\r
+       {\r
+               $parameters = $m->output_parameters();\r
+               $method_name = $parameters[0];\r
+               \r
+               if (isset($this->methods[$method_name]))\r
+               {\r
+                       if ($this->methods[$method_name]['signature'])\r
+                       {\r
+                               $sigs = array();\r
+                               $signature = $this->methods[$method_name]['signature'];\r
+                               \r
+                               for($i=0; $i < sizeof($signature); $i++)\r
+                               {\r
+                                       $cursig = array();\r
+                                       $inSig = $signature[$i];\r
+                                       for($j=0; $j<sizeof($inSig); $j++)\r
+                                       {\r
+                                               $cursig[]= new XML_RPC_Values($inSig[$j], 'string');\r
+                                       }\r
+                                       $sigs[]= new XML_RPC_Values($cursig, 'array');\r
+                               }\r
+                               $r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));\r
+                       }\r
+                       else\r
+                       {\r
+                               $r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);\r
+               }\r
+               return $r;\r
+       }\r
+       \r
+       //-------------------------------------\r
+       //  Server Function:  Doc String for Method\r
+       //-------------------------------------\r
+       \r
+       function methodHelp($m)\r
+       {\r
+               $parameters = $m->output_parameters();\r
+               $method_name = $parameters[0];\r
+       \r
+               if (isset($this->methods[$method_name]))\r
+               {\r
+                       $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';\r
+                       \r
+                       return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));\r
+               }\r
+               else\r
+               {\r
+                       return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);\r
+               }\r
+       }\r
+\r
+       //-------------------------------------\r
+       //  Server Function:  Multi-call\r
+       //-------------------------------------\r
+\r
+       function multicall($m)\r
+       {\r
+               // Disabled\r
+               return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);\r
+               \r
+               $parameters = $m->output_parameters();\r
+               $calls = $parameters[0];\r
+\r
+               $result = array();\r
+\r
+               foreach ($calls as $value)\r
+               {\r
+                       //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));\r
+                       \r
+                       $m = new XML_RPC_Message($value[0]);\r
+                       $plist='';\r
+                       \r
+                       for($i=0; $i < sizeof($value[1]); $i++)\r
+                       {\r
+                               $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));\r
+                       }\r
+                       \r
+                       $attempt = $this->_execute($m);\r
+\r
+                       if ($attempt->faultCode() != 0)\r
+                       {\r
+                               return $attempt;\r
+                       }\r
+\r
+                       $result[] = new XML_RPC_Values(array($attempt->value()), 'array');\r
+               }\r
+\r
+               return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));\r
+       }\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Multi-call Function:  Error Handling\r
+       //-------------------------------------\r
+\r
+       function multicall_error($err)\r
+       {\r
+               $str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();\r
+               $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();\r
+               \r
+               $struct['faultCode'] = new XML_RPC_Values($code, 'int');\r
+               $struct['faultString'] = new XML_RPC_Values($str, 'string');\r
+       \r
+               return new XML_RPC_Values($struct, 'struct');\r
+       }\r
+       \r
+       \r
+       //-------------------------------------\r
+       //  Multi-call Function:  Processes method\r
+       //-------------------------------------\r
+       \r
+       function do_multicall($call)\r
+       {\r
+               if ($call->kindOf() != 'struct')\r
+                       return $this->multicall_error('notstruct');\r
+               elseif ( ! $methName = $call->me['struct']['methodName'])\r
+                       return $this->multicall_error('nomethod');\r
+               \r
+               list($scalar_type,$scalar_value)=each($methName->me);\r
+               $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;\r
+                       \r
+               if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')\r
+                       return $this->multicall_error('notstring');\r
+               elseif ($scalar_value == 'system.multicall')\r
+                       return $this->multicall_error('recursion');\r
+               elseif ( ! $params = $call->me['struct']['params'])\r
+                       return $this->multicall_error('noparams');\r
+               elseif ($params->kindOf() != 'array')\r
+                       return $this->multicall_error('notarray');\r
+                       \r
+               list($a,$b)=each($params->me);\r
+               $numParams = sizeof($b);\r
+\r
+               $msg = new XML_RPC_Message($scalar_value);\r
+               for ($i = 0; $i < $numParams; $i++)\r
+               {\r
+                       $msg->params[] = $params->me['array'][$i];\r
+               }\r
+\r
+               $result = $this->_execute($msg);\r
+\r
+               if ($result->faultCode() != 0)\r
+               {\r
+                       return $this->multicall_error($result);\r
+               }\r
+\r
+               return new XML_RPC_Values(array($result->value()), 'array');\r
+       }       \r
+       \r
+}\r
+// END XML_RPC_Server class\r
+\r
+\r
+/* End of file Xmlrpcs.php */\r
+/* Location: ./system/libraries/Xmlrpcs.php */
\ No newline at end of file
diff --git a/libraries/Zip.php b/libraries/Zip.php
new file mode 100644 (file)
index 0000000..c15255a
--- /dev/null
@@ -0,0 +1,359 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Zip Compression Class\r
+ *\r
+ * This class is based on a library I found at Zend:\r
+ * http://www.zend.com/codex.php?id=696&single=1\r
+ *\r
+ * The original library is a little rough around the edges so I\r
+ * refactored it and added several additional methods -- Rick Ellis\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Libraries\r
+ * @category   Encryption\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/libraries/zip.html\r
+ */\r
+class CI_Zip  {\r
+\r
+       var $zipdata    = '';\r
+       var $directory  = '';\r
+       var $entries    = 0;\r
+       var $file_num   = 0;\r
+       var $offset             = 0;\r
+\r
+       function CI_Zip()\r
+       {\r
+               log_message('debug', "Zip Compression Class Initialized");\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Directory\r
+        *\r
+        * Lets you add a virtual directory into which you can place files.\r
+        *\r
+        * @access      public\r
+        * @param       mixed   the directory name. Can be string or array\r
+        * @return      void\r
+        */\r
+       function add_dir($directory)\r
+       {\r
+               foreach ((array)$directory as $dir)\r
+               {\r
+                       if ( ! preg_match("|.+/$|", $dir))\r
+                       {\r
+                               $dir .= '/';\r
+                       }\r
+\r
+                       $this->_add_dir($dir);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Directory\r
+        *\r
+        * @access      private\r
+        * @param       string  the directory name\r
+        * @return      void\r
+        */\r
+       function _add_dir($dir)\r
+       {\r
+               $dir = str_replace("\\", "/", $dir);\r
+\r
+               $this->zipdata .=\r
+                       "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"\r
+                       .pack('V', 0) // crc32\r
+                       .pack('V', 0) // compressed filesize\r
+                       .pack('V', 0) // uncompressed filesize\r
+                       .pack('v', strlen($dir)) // length of pathname\r
+                       .pack('v', 0) // extra field length\r
+                       .$dir\r
+                       // below is "data descriptor" segment\r
+                       .pack('V', 0) // crc32\r
+                       .pack('V', 0) // compressed filesize\r
+                       .pack('V', 0); // uncompressed filesize\r
+\r
+               $this->directory .=\r
+                       "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"\r
+                       .pack('V',0) // crc32\r
+                       .pack('V',0) // compressed filesize\r
+                       .pack('V',0) // uncompressed filesize\r
+                       .pack('v', strlen($dir)) // length of pathname\r
+                       .pack('v', 0) // extra field length\r
+                       .pack('v', 0) // file comment length\r
+                       .pack('v', 0) // disk number start\r
+                       .pack('v', 0) // internal file attributes\r
+                       .pack('V', 16) // external file attributes - 'directory' bit set\r
+                       .pack('V', $this->offset) // relative offset of local header\r
+                       .$dir;\r
+\r
+               $this->offset = strlen($this->zipdata);\r
+               $this->entries++;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Data to Zip\r
+        *\r
+        * Lets you add files to the archive. If the path is included\r
+        * in the filename it will be placed within a directory.  Make\r
+        * sure you use add_dir() first to create the folder.\r
+        *\r
+        * @access      public\r
+        * @param       mixed\r
+        * @param       string\r
+        * @return      void\r
+        */     \r
+       function add_data($filepath, $data = NULL)\r
+       {\r
+               if (is_array($filepath))\r
+               {\r
+                       foreach ($filepath as $path => $data)\r
+                       {\r
+                               $this->_add_data($path, $data);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       $this->_add_data($filepath, $data);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Add Data to Zip\r
+        *\r
+        * @access      private\r
+        * @param       string  the file name/path\r
+        * @param       string  the data to be encoded\r
+        * @return      void\r
+        */     \r
+       function _add_data($filepath, $data)\r
+       {\r
+               $filepath = str_replace("\\", "/", $filepath);\r
+\r
+               $uncompressed_size = strlen($data);\r
+               $crc32  = crc32($data);\r
+\r
+               $gzdata = gzcompress($data);\r
+               $gzdata = substr($gzdata, 2, -4);\r
+               $compressed_size = strlen($gzdata);\r
+\r
+               $this->zipdata .=\r
+                       "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"\r
+                       .pack('V', $crc32)\r
+                       .pack('V', $compressed_size)\r
+                       .pack('V', $uncompressed_size)\r
+                       .pack('v', strlen($filepath)) // length of filename\r
+                       .pack('v', 0) // extra field length\r
+                       .$filepath\r
+                       .$gzdata; // "file data" segment\r
+\r
+               $this->directory .=\r
+                       "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"\r
+                       .pack('V', $crc32)\r
+                       .pack('V', $compressed_size)\r
+                       .pack('V', $uncompressed_size)\r
+                       .pack('v', strlen($filepath)) // length of filename\r
+                       .pack('v', 0) // extra field length\r
+                       .pack('v', 0) // file comment length\r
+                       .pack('v', 0) // disk number start\r
+                       .pack('v', 0) // internal file attributes\r
+                       .pack('V', 32) // external file attributes - 'archive' bit set\r
+                       .pack('V', $this->offset) // relative offset of local header\r
+                       .$filepath;\r
+\r
+               $this->offset = strlen($this->zipdata);\r
+               $this->entries++;\r
+               $this->file_num++;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Read the contents of a file and add it to the zip\r
+        *\r
+        * @access      public\r
+        * @return      bool\r
+        */     \r
+       function read_file($path, $preserve_filepath = FALSE)\r
+       {\r
+               if ( ! file_exists($path))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               if (FALSE !== ($data = file_get_contents($path)))\r
+               {\r
+                       $name = str_replace("\\", "/", $path);\r
+                       \r
+                       if ($preserve_filepath === FALSE)\r
+                       {\r
+                               $name = preg_replace("|.*/(.+)|", "\\1", $name);\r
+                       }\r
+\r
+                       $this->add_data($name, $data);\r
+                       return TRUE;\r
+               }\r
+               return FALSE;\r
+       }\r
+\r
+       // ------------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Read a directory and add it to the zip.\r
+        *\r
+        * This function recursively reads a folder and everything it contains (including\r
+        * sub-folders) and creates a zip based on it.  Whatever directory structure\r
+        * is in the original file path will be recreated in the zip file.\r
+        *\r
+        * @access      public\r
+        * @param       string  path to source\r
+        * @return      bool\r
+        */     \r
+       function read_dir($path)\r
+       {       \r
+               if ($fp = @opendir($path))\r
+               {\r
+                       while (FALSE !== ($file = readdir($fp)))\r
+                       {\r
+                               if (@is_dir($path.$file) && substr($file, 0, 1) != '.')\r
+                               {                                       \r
+                                       $this->read_dir($path.$file."/");\r
+                               }\r
+                               elseif (substr($file, 0, 1) != ".")\r
+                               {\r
+                                       if (FALSE !== ($data = file_get_contents($path.$file)))\r
+                                       {                                               \r
+                                               $this->add_data(str_replace("\\", "/", $path).$file, $data);\r
+                                       }\r
+                               }\r
+                       }\r
+                       return TRUE;\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Get the Zip file\r
+        *\r
+        * @access      public\r
+        * @return      binary string\r
+        */     \r
+       function get_zip()\r
+       {\r
+               // Is there any data to return?\r
+               if ($this->entries == 0)\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               $zip_data = $this->zipdata;\r
+               $zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";\r
+               $zip_data .= pack('v', $this->entries); // total # of entries "on this disk"\r
+               $zip_data .= pack('v', $this->entries); // total # of entries overall\r
+               $zip_data .= pack('V', strlen($this->directory)); // size of central dir\r
+               $zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir\r
+               $zip_data .= "\x00\x00"; // .zip file comment length\r
+\r
+               return $zip_data;\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Write File to the specified directory\r
+        *\r
+        * Lets you write a file\r
+        *\r
+        * @access      public\r
+        * @param       string  the file name\r
+        * @return      bool\r
+        */     \r
+       function archive($filepath)\r
+       {\r
+               if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))\r
+               {\r
+                       return FALSE;\r
+               }\r
+\r
+               flock($fp, LOCK_EX);    \r
+               fwrite($fp, $this->get_zip());\r
+               flock($fp, LOCK_UN);\r
+               fclose($fp);\r
+\r
+               return TRUE;    \r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Download\r
+        *\r
+        * @access      public\r
+        * @param       string  the file name\r
+        * @param       string  the data to be encoded\r
+        * @return      bool\r
+        */\r
+       function download($filename = 'backup.zip')\r
+       {\r
+               if ( ! preg_match("|.+?\.zip$|", $filename))\r
+               {\r
+                       $filename .= '.zip';\r
+               }\r
+\r
+               $zip_content =& $this->get_zip();\r
+\r
+               $CI =& get_instance();\r
+               $CI->load->helper('download');\r
+\r
+               force_download($filename, $zip_content);\r
+       }\r
+\r
+       // --------------------------------------------------------------------\r
+\r
+       /**\r
+        * Initialize Data\r
+        *\r
+        * Lets you clear current zip data.  Useful if you need to create\r
+        * multiple zips with different data.\r
+        *\r
+        * @access      public\r
+        * @return      void\r
+        */             \r
+       function clear_data()\r
+       {\r
+               $this->zipdata          = '';\r
+               $this->directory        = '';\r
+               $this->entries          = 0;\r
+               $this->file_num         = 0;\r
+               $this->offset           = 0;\r
+       }\r
+       \r
+}\r
+\r
+/* End of file Zip.php */\r
+/* Location: ./system/libraries/Zip.php */
\ No newline at end of file
diff --git a/libraries/index.html b/libraries/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/logs/index.html b/logs/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/plugins/captcha_pi.php b/plugins/captcha_pi.php
new file mode 100644 (file)
index 0000000..0484a6f
--- /dev/null
@@ -0,0 +1,356 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/*\r
+Instructions:\r
+\r
+Load the plugin using:\r
+\r
+       $this->load->plugin('captcha');\r
+\r
+Once loaded you can generate a captcha like this:\r
+       \r
+       $vals = array(\r
+                                       'word'           => 'Random word',\r
+                                       'img_path'       => './captcha/',\r
+                                       'img_url'        => 'http://example.com/captcha/',\r
+                                       'font_path'      => './system/fonts/texb.ttf',\r
+                                       'img_width'      => '150',\r
+                                       'img_height' => 30,\r
+                                       'expiration' => 7200\r
+                               );\r
+       \r
+       $cap = create_captcha($vals);\r
+       echo $cap['image'];\r
+       \r
+\r
+NOTES:\r
+       \r
+       The captcha function requires the GD image library.\r
+       \r
+       Only the img_path and img_url are required.\r
+       \r
+       If a "word" is not supplied, the function will generate a random\r
+       ASCII string.  You might put together your own word library that\r
+       you can draw randomly from.\r
+       \r
+       If you do not specify a path to a TRUE TYPE font, the native ugly GD\r
+       font will be used.\r
+       \r
+       The "captcha" folder must be writable (666, or 777)\r
+       \r
+       The "expiration" (in seconds) signifies how long an image will\r
+       remain in the captcha folder before it will be deleted.  The default\r
+       is two hours.\r
+\r
+RETURNED DATA\r
+\r
+The create_captcha() function returns an associative array with this data:\r
+\r
+  [array]\r
+  (\r
+       'image' => IMAGE TAG\r
+       'time'  => TIMESTAMP (in microtime)\r
+       'word'  => CAPTCHA WORD\r
+  )\r
+\r
+The "image" is the actual image tag:\r
+<img src="http://example.com/captcha/12345.jpg" width="140" height="50" />\r
+\r
+The "time" is the micro timestamp used as the image name without the file\r
+extension.  It will be a number like this:  1139612155.3422\r
+\r
+The "word" is the word that appears in the captcha image, which if not\r
+supplied to the function, will be a random string.\r
+\r
+\r
+ADDING A DATABASE\r
+\r
+In order for the captcha function to prevent someone from posting, you will need\r
+to add the information returned from create_captcha() function to your database.\r
+Then, when the data from the form is submitted by the user you will need to verify\r
+that the data exists in the database and has not expired.\r
+\r
+Here is a table prototype:\r
+\r
+       CREATE TABLE captcha (\r
+        captcha_id bigint(13) unsigned NOT NULL auto_increment,\r
+        captcha_time int(10) unsigned NOT NULL,\r
+        ip_address varchar(16) default '0' NOT NULL,\r
+        word varchar(20) NOT NULL,\r
+        PRIMARY KEY `captcha_id` (`captcha_id`),\r
+        KEY `word` (`word`)\r
+       )\r
+\r
+\r
+Here is an example of usage with a DB.\r
+\r
+On the page where the captcha will be shown you'll have something like this:\r
+\r
+       $this->load->plugin('captcha');\r
+       $vals = array(\r
+                                       'img_path'       => './captcha/',\r
+                                       'img_url'        => 'http://example.com/captcha/'\r
+                               );\r
+       \r
+       $cap = create_captcha($vals);\r
+\r
+       $data = array(\r
+                                       'captcha_id'    => '',\r
+                                       'captcha_time'  => $cap['time'],\r
+                                       'ip_address'    => $this->input->ip_address(),\r
+                                       'word'                  => $cap['word']\r
+                               );\r
+\r
+       $query = $this->db->insert_string('captcha', $data);\r
+       $this->db->query($query);\r
+               \r
+       echo 'Submit the word you see below:';\r
+       echo $cap['image'];\r
+       echo '<input type="text" name="captcha" value="" />';\r
+\r
+\r
+Then, on the page that accepts the submission you'll have something like this:\r
+\r
+       // First, delete old captchas\r
+       $expiration = time()-7200; // Two hour limit\r
+       $DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration);            \r
+\r
+       // Then see if a captcha exists:\r
+       $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?";\r
+       $binds = array($_POST['captcha'], $this->input->ip_address(), $expiration);\r
+       $query = $this->db->query($sql, $binds);\r
+       $row = $query->row();\r
+\r
+       if ($row->count == 0)\r
+       {\r
+               echo "You must submit the word that appears in the image";\r
+       }\r
+\r
+*/\r
+\r
+\r
+       \r
+/**\r
+|==========================================================\r
+| Create Captcha\r
+|==========================================================\r
+|\r
+*/\r
+function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')\r
+{              \r
+       $defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);                \r
+       \r
+       foreach ($defaults as $key => $val)\r
+       {\r
+               if ( ! is_array($data))\r
+               {\r
+                       if ( ! isset($$key) OR $$key == '')\r
+                       {\r
+                               $$key = $val;\r
+                       }\r
+               }\r
+               else\r
+               {                       \r
+                       $$key = ( ! isset($data[$key])) ? $val : $data[$key];\r
+               }\r
+       }\r
+       \r
+       if ($img_path == '' OR $img_url == '')\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       if ( ! @is_dir($img_path))\r
+       {\r
+               return FALSE;\r
+       }\r
+       \r
+       if ( ! is_really_writable($img_path))\r
+       {\r
+               return FALSE;\r
+       }\r
+                       \r
+       if ( ! extension_loaded('gd'))\r
+       {\r
+               return FALSE;\r
+       }               \r
+       \r
+       // -----------------------------------\r
+       // Remove old images    \r
+       // -----------------------------------\r
+                       \r
+       list($usec, $sec) = explode(" ", microtime());\r
+       $now = ((float)$usec + (float)$sec);\r
+                       \r
+       $current_dir = @opendir($img_path);\r
+       \r
+       while($filename = @readdir($current_dir))\r
+       {\r
+               if ($filename != "." and $filename != ".." and $filename != "index.html")\r
+               {\r
+                       $name = str_replace(".jpg", "", $filename);\r
+               \r
+                       if (($name + $expiration) < $now)\r
+                       {\r
+                               @unlink($img_path.$filename);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       @closedir($current_dir);\r
+\r
+       // -----------------------------------\r
+       // Do we have a "word" yet?\r
+       // -----------------------------------\r
+       \r
+   if ($word == '')\r
+   {\r
+               $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\r
+\r
+               $str = '';\r
+               for ($i = 0; $i < 8; $i++)\r
+               {\r
+                       $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);\r
+               }\r
+               \r
+               $word = $str;\r
+   }\r
+       \r
+       // -----------------------------------\r
+       // Determine angle and position \r
+       // -----------------------------------\r
+       \r
+       $length = strlen($word);\r
+       $angle  = ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;\r
+       $x_axis = rand(6, (360/$length)-16);                    \r
+       $y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);\r
+       \r
+       // -----------------------------------\r
+       // Create image\r
+       // -----------------------------------\r
+                       \r
+       // PHP.net recommends imagecreatetruecolor(), but it isn't always available\r
+       if (function_exists('imagecreatetruecolor'))\r
+       {\r
+               $im = imagecreatetruecolor($img_width, $img_height);\r
+       }\r
+       else\r
+       {\r
+               $im = imagecreate($img_width, $img_height);\r
+       }\r
+                       \r
+       // -----------------------------------\r
+       //  Assign colors\r
+       // -----------------------------------\r
+       \r
+       $bg_color               = imagecolorallocate ($im, 255, 255, 255);\r
+       $border_color   = imagecolorallocate ($im, 153, 102, 102);\r
+       $text_color             = imagecolorallocate ($im, 204, 153, 153);\r
+       $grid_color             = imagecolorallocate($im, 255, 182, 182);\r
+       $shadow_color   = imagecolorallocate($im, 255, 240, 240);\r
+\r
+       // -----------------------------------\r
+       //  Create the rectangle\r
+       // -----------------------------------\r
+       \r
+       ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);\r
+       \r
+       // -----------------------------------\r
+       //  Create the spiral pattern\r
+       // -----------------------------------\r
+       \r
+       $theta          = 1;\r
+       $thetac         = 7;\r
+       $radius         = 16;\r
+       $circles        = 20;\r
+       $points         = 32;\r
+\r
+       for ($i = 0; $i < ($circles * $points) - 1; $i++)\r
+       {\r
+               $theta = $theta + $thetac;\r
+               $rad = $radius * ($i / $points );\r
+               $x = ($rad * cos($theta)) + $x_axis;\r
+               $y = ($rad * sin($theta)) + $y_axis;\r
+               $theta = $theta + $thetac;\r
+               $rad1 = $radius * (($i + 1) / $points);\r
+               $x1 = ($rad1 * cos($theta)) + $x_axis;\r
+               $y1 = ($rad1 * sin($theta )) + $y_axis;\r
+               imageline($im, $x, $y, $x1, $y1, $grid_color);\r
+               $theta = $theta - $thetac;\r
+       }\r
+\r
+       // -----------------------------------\r
+       //  Write the text\r
+       // -----------------------------------\r
+       \r
+       $use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE;\r
+               \r
+       if ($use_font == FALSE)\r
+       {\r
+               $font_size = 5;\r
+               $x = rand(0, $img_width/($length/3));\r
+               $y = 0;\r
+       }\r
+       else\r
+       {\r
+               $font_size      = 16;\r
+               $x = rand(0, $img_width/($length/1.5));\r
+               $y = $font_size+2;\r
+       }\r
+\r
+       for ($i = 0; $i < strlen($word); $i++)\r
+       {\r
+               if ($use_font == FALSE)\r
+               {\r
+                       $y = rand(0 , $img_height/2);\r
+                       imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);\r
+                       $x += ($font_size*2);\r
+               }\r
+               else\r
+               {               \r
+                       $y = rand($img_height/2, $img_height-3);\r
+                       imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));\r
+                       $x += $font_size;\r
+               }\r
+       }\r
+       \r
+\r
+       // -----------------------------------\r
+       //  Create the border\r
+       // -----------------------------------\r
+\r
+       imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);          \r
+\r
+       // -----------------------------------\r
+       //  Generate the image\r
+       // -----------------------------------\r
+       \r
+       $img_name = $now.'.jpg';\r
+\r
+       ImageJPEG($im, $img_path.$img_name);\r
+       \r
+       $img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";\r
+       \r
+       ImageDestroy($im);\r
+               \r
+       return array('word' => $word, 'time' => $now, 'image' => $img);\r
+}\r
+\r
+\r
+/* End of file captcha_pi.php */\r
+/* Location: ./system/plugins/captcha_pi.php */
\ No newline at end of file
diff --git a/plugins/index.html b/plugins/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/plugins/js_calendar_pi.php b/plugins/js_calendar_pi.php
new file mode 100644 (file)
index 0000000..e165c54
--- /dev/null
@@ -0,0 +1,629 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/*\r
+Instructions:\r
+\r
+Load the plugin using:\r
+\r
+       $this->load->plugin('js_calendar');\r
+\r
+Once loaded you'll add the calendar script to the <head> of your page like this:\r
+\r
+<?php echo js_calendar_script('my_form');  ?>\r
+\r
+The above function will be passed the name of your form.\r
+\r
+Then to show the actual calendar you'll do this:\r
+\r
+<?php echo js_calendar_write('entry_date', time(), true);?>\r
+<form name="my_form">\r
+<input type="text" name="entry_date" value="" onblur="update_calendar(this.name, this.value);" />\r
+<p><a href="javascript:void(0);" onClick="set_to_time('entry_date', '<?php echo time();?>')" >Today</a></p>\r
+</form>\r
+\r
+\r
+Note:  The first parameter is the name of the field containing your date, the second parameter contains the "now" time,\r
+and the third tells the calendar whether to highlight the current day or not.\r
+\r
+Lastly, you'll need some CSS for your calendar:\r
+\r
+.calendar {\r
+       border: 1px #6975A3 solid;\r
+       background-color: transparent;\r
+}\r
+.calheading {\r
+       background-color: #7C8BC0;\r
+       color: #fff;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 11px;\r
+       font-weight: bold;\r
+       text-align: center;\r
+}\r
+.calnavleft {\r
+       background-color: #7C8BC0;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 10px;\r
+       font-weight: bold;\r
+       color: #fff;\r
+       padding: 4px;\r
+       cursor: pointer;\r
+}\r
+.calnavright {\r
+       background-color: #7C8BC0;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 10px;\r
+       font-weight: bold;\r
+       color: #fff;\r
+       text-align:  right;\r
+       padding: 4px;\r
+       cursor: pointer;\r
+}\r
+.caldayheading {\r
+       background-color: #000;\r
+       color: #fff;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 10px;\r
+       text-align: center;\r
+       padding: 6px 2px 6px 2px;\r
+}\r
+.caldaycells{\r
+       color: #000;\r
+       background-color: #D1D7E6;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 11px;\r
+       text-align: center;\r
+       padding: 4px;\r
+       border: 1px #E0E5F1 solid;\r
+       cursor: pointer;\r
+}\r
+.caldaycellhover{\r
+       color: #fff;\r
+       background-color: #B3BCD4;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 11px;\r
+       text-align: center;\r
+       padding: 4px;\r
+       border: 1px #B3BCD4 solid;\r
+       cursor: pointer;\r
+}\r
+.caldayselected{\r
+       background-color: #737FAC;\r
+       color:  #fff;\r
+       font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+       font-size: 11px;\r
+       font-weight: bold;\r
+       text-align: center;\r
+       border: 1px #566188 solid;\r
+       padding: 3px;\r
+       cursor: pointer;\r
+}\r
+.calblanktop {\r
+       background-color: #fff;\r
+       padding: 4px;\r
+}\r
+.calblankbot {\r
+       background-color: #fff;\r
+       padding: 4px;\r
+}\r
+\r
+\r
+*/\r
+\r
+function js_calendar_script($form_name = 'entryform')\r
+{              \r
+$CI =& get_instance();\r
+$CI->load->language('calendar');\r
+ob_start();\r
+?>\r
+<script type="text/javascript">\r
+<!--\r
+var form_name  = "<?php echo $form_name; ?>";\r
+var format             = 'us'; // eu or us\r
+var days               = new Array(\r
+                                       '<?php echo $CI->lang->line('cal_su');?>', // Sunday, short name\r
+                                       '<?php echo $CI->lang->line('cal_mo');?>', // Monday, short name\r
+                                       '<?php echo $CI->lang->line('cal_tu');?>', // Tuesday, short name\r
+                                       '<?php echo $CI->lang->line('cal_wed');?>', // Wednesday, short name\r
+                                       '<?php echo $CI->lang->line('cal_thu');?>', // Thursday, short name\r
+                                       '<?php echo $CI->lang->line('cal_fri');?>', // Friday, short name\r
+                                       '<?php echo $CI->lang->line('cal_sat');?>' // Saturday, short name\r
+                               );\r
+var months             = new Array(\r
+                                       '<?php echo $CI->lang->line('cal_january');?>',\r
+                                       '<?php echo $CI->lang->line('cal_february');?>',\r
+                                       '<?php echo $CI->lang->line('cal_march');?>',\r
+                                       '<?php echo $CI->lang->line('cal_april');?>',\r
+                                       '<?php echo $CI->lang->line('cal_mayl');?>',\r
+                                       '<?php echo $CI->lang->line('cal_june');?>',\r
+                                       '<?php echo $CI->lang->line('cal_july');?>',\r
+                                       '<?php echo $CI->lang->line('cal_august');?>',\r
+                                       '<?php echo $CI->lang->line('cal_september');?>',\r
+                                       '<?php echo $CI->lang->line('cal_october');?>',\r
+                                       '<?php echo $CI->lang->line('cal_november');?>',\r
+                                       '<?php echo $CI->lang->line('cal_december');?>'\r
+                               );\r
+var last_click = new Array();\r
+var current_month  = '';\r
+var current_year   = '';\r
+var last_date  = '';\r
+       \r
+function calendar(id, d, highlight, adjusted)\r
+{              \r
+       if (adjusted == undefined)\r
+       {       \r
+               var d = new Date(d * 1000);\r
+       }\r
+\r
+       this.id                 = id;\r
+       this.highlight  = highlight;\r
+       this.date_obj   = d;\r
+       this.write              = build_calendar;\r
+       this.total_days = total_days;\r
+       this.month              = d.getMonth();\r
+       this.date               = d.getDate();\r
+       this.day                = d.getDay();\r
+       this.year               = d.getFullYear();\r
+       this.hours              = d.getHours();\r
+       this.minutes    = d.getMinutes();\r
+       this.seconds    = d.getSeconds();\r
+       this.date_str   = date_str;\r
+                               \r
+       if (highlight == false)\r
+       {\r
+               this.selected_date = '';\r
+       }\r
+       else\r
+       {\r
+               this.selected_date = this.year + '' + this.month + '' + this.date;\r
+       }\r
+                       \r
+       //      Set the "selected date"\r
+       d.setDate(1);\r
+       this.firstDay = d.getDay();\r
+       \r
+       //then reset the date object to the correct date\r
+       d.setDate(this.date);\r
+}\r
+               \r
+//     Build the body of the calendar\r
+function build_calendar()\r
+{\r
+       var str = '';\r
+       \r
+       //      Calendar Heading\r
+       \r
+       str += '<div id="cal' + this.id + '">';\r
+       str += '<table class="calendar" cellspacing="0" cellpadding="0" border="0" >';\r
+       str += '<tr>';\r
+       str += '<td class="calnavleft" onClick="change_month(-1, \'' + this.id + '\')">&lt;&lt;<\/td>';\r
+       str += '<td colspan="5" class="calheading">' + months[this.month] + ' ' + this.year + '<\/td>';\r
+       str += '<td class="calnavright" onClick="change_month(1, \'' + this.id + '\')">&gt;&gt;<\/td>';\r
+       str += '<\/tr>';\r
+       \r
+       //      Day Names\r
+       \r
+       str += '<tr>';\r
+       \r
+       for (i = 0; i < 7; i++)\r
+       {\r
+               str += '<td class="caldayheading">' + days[i] + '<\/td>';\r
+       }\r
+       \r
+       str += '<\/tr>';\r
+       \r
+       //      Day Cells\r
+               \r
+       str += '<tr>';\r
+       \r
+       selDate = (last_date != '') ? last_date : this.date;\r
+       \r
+       for (j = 0; j < 42; j++)\r
+       {\r
+               var displayNum = (j - this.firstDay + 1);\r
+               \r
+               if (j < this.firstDay) // leading empty cells\r
+               {\r
+                       str += '<td class="calblanktop">&nbsp;<\/td>';\r
+               }\r
+               else if (displayNum == selDate && this.highlight == true) // Selected date\r
+               {\r
+                       str += '<td id="' + this.id +'selected" class="caldayselected" onClick="set_date(this,\'' + this.id + '\')">' + displayNum + '<\/td>';\r
+               }\r
+               else if (displayNum > this.total_days())\r
+               {\r
+                       str += '<td class="calblankbot">&nbsp;<\/td>'; // trailing empty cells\r
+               }\r
+               else  // Unselected days\r
+               {\r
+                       str += '<td id="" class="caldaycells" onClick="set_date(this,\'' + this.id + '\'); return false;"  onMouseOver="javascript:cell_highlight(this,\'' + displayNum + '\',\'' + this.id + '\');" onMouseOut="javascript:cell_reset(this,\'' + displayNum + '\',\'' + this.id + '\');" >' + displayNum + '<\/td>';\r
+               }\r
+               \r
+               if (j % 7 == 6)\r
+               {\r
+                       str += '<\/tr><tr>';\r
+               }\r
+       }\r
+\r
+       str += '<\/tr>';        \r
+       str += '<\/table>';\r
+       str += '<\/div>';\r
+       \r
+       return str;\r
+}\r
+\r
+//     Total number of days in a month\r
+function total_days()\r
+{      \r
+       switch(this.month)\r
+       {\r
+               case 1: // Check for leap year\r
+                       if ((  this.date_obj.getFullYear() % 4 == 0\r
+                               && this.date_obj.getFullYear() % 100 != 0)\r
+                               || this.date_obj.getFullYear() % 400 == 0)\r
+                               return 29;\r
+                       else\r
+                               return 28;\r
+               case 3:\r
+                       return 30;\r
+               case 5:\r
+                       return 30;\r
+               case 8:\r
+                       return 30;\r
+               case 10:\r
+                       return 30\r
+               default:\r
+                       return 31;\r
+       }\r
+}\r
+\r
+//     Highlight Cell on Mouseover\r
+function cell_highlight(td, num, cal)\r
+{\r
+       cal = eval(cal);\r
+\r
+       if (last_click[cal.id]  != num)\r
+       {\r
+               td.className = "caldaycellhover";\r
+       }\r
+}              \r
+\r
+//     Reset Cell on MouseOut\r
+function cell_reset(td, num, cal)\r
+{      \r
+       cal = eval(cal);\r
+\r
+       if (last_click[cal.id] == num)\r
+       {\r
+               td.className = "caldayselected";\r
+       }\r
+       else\r
+       {\r
+               td.className = "caldaycells";\r
+       }\r
+}              \r
+\r
+//     Clear Field\r
+function clear_field(id)\r
+{                              \r
+       eval("document." + form_name + "." + id + ".value = ''");\r
+       \r
+       document.getElementById(id + "selected").className = "caldaycells";\r
+       document.getElementById(id + "selected").id = "";       \r
+       \r
+       cal = eval(id);\r
+       cal.selected_date = '';         \r
+}              \r
+\r
+\r
+//     Set date to specified time\r
+function set_to_time(id, raw)\r
+{                      \r
+       if (document.getElementById(id + "selected"))\r
+       {                       \r
+               document.getElementById(id + "selected").className = "caldaycells";\r
+               document.getElementById(id + "selected").id = "";       \r
+       }\r
+       \r
+       document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';                              \r
+               \r
+       var nowDate = new Date();\r
+       nowDate.setTime = raw * 1000;\r
+       \r
+       current_month   = nowDate.getMonth();\r
+       current_year    = nowDate.getFullYear();\r
+       current_date    = nowDate.getDate();\r
+       \r
+       oldcal = eval(id);\r
+       oldcal.selected_date = current_year + '' + current_month + '' + current_date;                           \r
+\r
+       cal = new calendar(id, nowDate, true, true);            \r
+       cal.selected_date = current_year + '' + current_month + '' + current_date;      \r
+       \r
+       last_date = cal.date;\r
+       \r
+       document.getElementById('tempcal'+id).innerHTML = cal.write();  \r
+       \r
+       insert_date(cal);\r
+}\r
+\r
+//     Set date to what is in the field\r
+var lastDates = new Array();\r
+\r
+function update_calendar(id, dateValue)\r
+{\r
+       if (lastDates[id] == dateValue) return;\r
+       \r
+       lastDates[id] = dateValue;\r
+       \r
+       var fieldString = dateValue.replace(/\s+/g, ' ');\r
+       \r
+       while (fieldString.substring(0,1) == ' ')\r
+       {\r
+               fieldString = fieldString.substring(1, fieldString.length);\r
+       }\r
+       \r
+       var dateString = fieldString.split(' ');\r
+       var dateParts = dateString[0].split('-')\r
+\r
+       if (dateParts.length < 3) return;\r
+       var newYear  = dateParts[0];\r
+       var newMonth = dateParts[1];\r
+       var newDay   = dateParts[2];\r
+       \r
+       if (isNaN(newDay)  || newDay < 1 || (newDay.length != 1 && newDay.length != 2)) return;\r
+       if (isNaN(newYear) || newYear < 1 || newYear.length != 4) return;\r
+       if (isNaN(newMonth) || newMonth < 1 || (newMonth.length != 1 && newMonth.length != 2)) return;\r
+       \r
+       if (newMonth > 12) newMonth = 12;\r
+       \r
+       if (newDay > 28)\r
+       {\r
+               switch(newMonth - 1)\r
+               {\r
+                       case 1: // Check for leap year\r
+                               if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)\r
+                               {\r
+                                       if (newDay > 29) newDay = 29;\r
+                               }\r
+                               else\r
+                               {\r
+                                       if (newDay > 28) newDay = 28;\r
+                               }\r
+                       case 3:\r
+                               if (newDay > 30) newDay = 30;\r
+                       case 5:\r
+                               if (newDay > 30) newDay = 30;\r
+                       case 8:\r
+                               if (newDay > 30) newDay = 30;\r
+                       case 10:\r
+                               if (newDay > 30) newDay = 30;\r
+                       default:\r
+                               if (newDay > 31) newDay = 31;\r
+               }\r
+       }\r
+       \r
+       if (document.getElementById(id + "selected"))\r
+       {                       \r
+               document.getElementById(id + "selected").className = "caldaycells";\r
+               document.getElementById(id + "selected").id = "";       \r
+       }\r
+       \r
+       document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';                              \r
+               \r
+       var nowDate = new Date();\r
+       nowDate.setDate(newDay);\r
+       nowDate.setMonth(newMonth - 1);\r
+       nowDate.setYear(newYear);\r
+       nowDate.setHours(12);\r
+       \r
+       current_month   = nowDate.getMonth();\r
+       current_year    = nowDate.getFullYear();\r
+\r
+       cal = new calendar(id, nowDate, true, true);                                            \r
+       document.getElementById('tempcal'+id).innerHTML = cal.write();  \r
+}\r
+\r
+//     Set the date\r
+function set_date(td, cal)\r
+{                                      \r
+\r
+       cal = eval(cal);\r
+       \r
+       // If the user is clicking a cell that is already\r
+       // selected we'll de-select it and clear the form field\r
+       \r
+       if (last_click[cal.id] == td.firstChild.nodeValue)\r
+       {\r
+               td.className = "caldaycells";\r
+               last_click[cal.id] = '';\r
+               remove_date(cal);\r
+               cal.selected_date =  '';\r
+               return;\r
+       }\r
+                               \r
+       // Onward!\r
+       if (document.getElementById(cal.id + "selected"))\r
+       {\r
+               document.getElementById(cal.id + "selected").className = "caldaycells";\r
+               document.getElementById(cal.id + "selected").id = "";\r
+       }\r
+                                                                       \r
+       td.className = "caldayselected";\r
+       td.id = cal.id + "selected";\r
+\r
+       cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;                  \r
+       cal.date_obj.setDate(td.firstChild.nodeValue);\r
+       cal = new calendar(cal.id, cal.date_obj, true, true);\r
+       cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;                  \r
+       \r
+       last_date = cal.date;\r
+\r
+       //cal.date\r
+       last_click[cal.id] = cal.date;\r
+                               \r
+       // Insert the date into the form\r
+       insert_date(cal);\r
+}\r
+/*\r
+//     Insert the date into the form field\r
+function insert_date(cal)\r
+{\r
+       cal = eval(cal);\r
+       fval = eval("document." + form_name + "." + cal.id);    \r
+       \r
+       if (fval.value == '')\r
+       {\r
+               fval.value = cal.date_str('y');\r
+       }\r
+       else\r
+       {\r
+               time = fval.value.substring(10);\r
+               new_date = cal.date_str('n') + time;\r
+               fval.value = new_date;\r
+       }       \r
+}\r
+*/             \r
+//     Remove the date from the form field\r
+function remove_date(cal)\r
+{\r
+       cal = eval(cal);\r
+       fval = eval("document." + form_name + "." + cal.id);    \r
+       fval.value = '';\r
+}\r
+\r
+//     Change to a new month\r
+function change_month(mo, cal)\r
+{              \r
+       cal = eval(cal);\r
+\r
+       if (current_month != '')\r
+       {\r
+               cal.date_obj.setMonth(current_month);\r
+               cal.date_obj.setYear(current_year);\r
+       \r
+               current_month   = '';\r
+               current_year    = '';\r
+       }\r
+                               \r
+       var newMonth = cal.date_obj.getMonth() + mo;\r
+       var newDate  = cal.date_obj.getDate();\r
+       \r
+       if (newMonth == 12)\r
+       {\r
+               cal.date_obj.setYear(cal.date_obj.getFullYear() + 1)\r
+               newMonth = 0;\r
+       }\r
+       else if (newMonth == -1)\r
+       {\r
+               cal.date_obj.setYear(cal.date_obj.getFullYear() - 1)\r
+               newMonth = 11;\r
+       }\r
+       \r
+       if (newDate > 28)\r
+       {\r
+               var newYear = cal.date_obj.getFullYear();\r
+               \r
+               switch(newMonth)\r
+               {\r
+                       case 1: // Check for leap year\r
+                               if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)\r
+                               {\r
+                                       if (newDate > 29) newDate = 29;\r
+                               }\r
+                               else\r
+                               {\r
+                                       if (newDate > 28) newDate = 28;\r
+                               }\r
+                       case 3:\r
+                               if (newDate > 30) newDate = 30;\r
+                       case 5:\r
+                               if (newDate > 30) newDate = 30;\r
+                       case 8:\r
+                               if (newDate > 30) newDate = 30;\r
+                       case 10:\r
+                               if (newDate > 30) newDate = 30;\r
+                       default:\r
+                               if (newDate > 31) newDate = 31;\r
+               }\r
+       }\r
+       \r
+       cal.date_obj.setDate(newDate);\r
+       cal.date_obj.setMonth(newMonth);\r
+       new_mdy = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;\r
+       \r
+       highlight = (cal.selected_date == new_mdy) ? true : false;                      \r
+       cal = new calendar(cal.id, cal.date_obj, highlight, true);                      \r
+       document.getElementById('cal' + cal.id).innerHTML = cal.write();        \r
+}\r
+\r
+//     Finalize the date string\r
+function date_str(time)\r
+{\r
+       var month = this.month + 1;\r
+       if (month < 10)\r
+               month = '0' + month;\r
+               \r
+       var day         = (this.date  < 10)     ?  '0' + this.date              : this.date;\r
+       var minutes     = (this.minutes  < 10)  ?  '0' + this.minutes   : this.minutes;\r
+               \r
+       if (format == 'us')\r
+       {\r
+               var hours       = (this.hours > 12) ? this.hours - 12 : this.hours;\r
+               var ampm        = (this.hours > 11) ? 'PM' : 'AM'\r
+       }\r
+       else\r
+       {\r
+               var hours       = this.hours;\r
+               var ampm        = '';\r
+       }\r
+       \r
+       if (time == 'y')\r
+       {\r
+               return this.year + '-' + month + '-' + day + '  ' + hours + ':' + minutes + ' ' + ampm;         \r
+       }\r
+       else\r
+       {\r
+               return this.year + '-' + month + '-' + day;\r
+       }\r
+}\r
+\r
+//-->\r
+</script>\r
+<?php\r
+\r
+$r = ob_get_contents();\r
+ob_end_clean();\r
+return $r;\r
+}\r
+\r
+\r
+function js_calendar_write($field_id, $time = '', $highlight = TRUE)\r
+{\r
+       if ($time == '')\r
+               $time = time();\r
+\r
+       return\r
+       '<script type="text/javascript">\r
+               var '.$field_id.' = new calendar("'.$field_id.'", '.$time.', '.(($highlight == TRUE) ? 'true' : 'false').');\r
+               document.write('.$field_id.'.write());\r
+       </script>';     \r
+}      \r
+\r
+\r
+/* End of file js_calendar_pi.php */\r
+/* Location: ./system/plugins/js_calendar_pi.php */
\ No newline at end of file
diff --git a/rounded.css b/rounded.css
new file mode 100644 (file)
index 0000000..4825add
--- /dev/null
@@ -0,0 +1,59 @@
+
+div.rounded {
+ margin: 0pt auto;
+ width: 200px;
+ background-color: rgb(153, 170, 187);
+ font-family: Georgia;
+ font-variant: small-caps;
+ font-weight: bold;
+ font-size: 2em;
+ line-height: 4em;
+ font-size-adjust: none;
+ font-stretch: normal;
+ color: rgb(255, 255, 255);
+ text-align: center
+}
+
+div.plroundedconfirm {
+  margin: 0pt auto;
+  width: 700px;
+  background-color: #ddeeee;
+  font-family: Georgia;
+  /*font-variant: small-caps;*/
+  /*font-weight: bold;*/
+  /*font-size: 2em;*/
+  /*line-height: 2em;*/
+  font-size-adjust: none;
+  font-stretch: normal;
+  color: rgb(0, 0, 0);
+  text-align: left; 
+ }
+
+div.plroundedupdate {
+  margin: 0pt auto;
+  width: 700px;
+  background-color: #ddeedd;
+  font-family: Georgia;
+  /*font-variant: small-caps;*/
+  /*font-weight: bold;*/
+  /*font-size: 2em;*/
+  /*line-height: 2em;*/
+  font-size-adjust: none;
+  font-stretch: normal;
+  color: rgb(0, 0, 0);
+  text-align: left; 
+ }
+
+div.plroundedwhite {
+  margin: 5px auto;
+  width: 670px;
+  background-color: #ffffff;
+  /*font-variant: small-caps;*/
+  /*font-weight: bold;*/
+  /*font-size: 2em;*/
+  /*line-height: 2em;*/
+  font-size-adjust: none;
+  font-stretch: normal;
+  color: rgb(0, 0, 0);
+  text-align: left; 
+ }
diff --git a/rounded.js b/rounded.js
new file mode 100644 (file)
index 0000000..546502a
--- /dev/null
@@ -0,0 +1,187 @@
+// Contributors \r
+// Ilkka Huotari at http://www.editsite.net\r
+// Mathieu 'p01' HENRI at http://www.p01.org/\r
+// http://seky.nahory.net/2005/04/rounded-corners/\r
+// Steven Wittens at http://www.acko.net/anti-aliased-nifty-corners\r
+// Original Nifty Corners by Alessandro Fulciniti at http://pro.html.it/esempio/nifty/\r
+function NiftyCheck() {\r
+  if(!document.getElementById || !document.createElement) {\r
+    return false;\r
+  }\r
+  var b = navigator.userAgent.toLowerCase();\r
+  if (b.indexOf("msie 5") > 0 && b.indexOf("opera") == -1) {\r
+    return false;\r
+  }\r
+  return true;\r
+}\r
+\r
+function Rounded(className, sizex, sizey, sizex_b, sizey_b) {\r
+       var bk;\r
+       if (!NiftyCheck()) return;\r
+       if (typeof(sizex_b) == 'undefined')\r
+               sizex_b = sizex;\r
+       if (typeof(sizey_b) == 'undefined')\r
+               sizey_b = sizey;\r
+       var v = getElements(className);\r
+       var l = v.length;\r
+       for (var i = 0; i < l; i++) {\r
+               color = get_current_style(v[i],"background-color","transparent");\r
+               bk = get_current_style(v[i].parentNode,"background-color","transparent");\r
+               AddRounded(v[i], bk, color, sizex, sizey, true);\r
+               AddRounded(v[i], bk, color, sizex_b, sizey_b, false);\r
+       }\r
+}\r
+\r
+Math.sqr = function (x) {\r
+  return x*x;\r
+};\r
+\r
+function Blend(a, b, alpha) {\r
+\r
+  var ca = Array(\r
+    parseInt('0x' + a.substring(1, 3)), \r
+    parseInt('0x' + a.substring(3, 5)), \r
+    parseInt('0x' + a.substring(5, 7))\r
+  );\r
+  var cb = Array(\r
+    parseInt('0x' + b.substring(1, 3)), \r
+    parseInt('0x' + b.substring(3, 5)), \r
+    parseInt('0x' + b.substring(5, 7))\r
+  );\r
+  return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)\r
+             + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)\r
+             + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);\r
+\r
+  return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)\r
+             + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)\r
+             + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);\r
+}\r
+\r
+function AddRounded(el, bk, color, sizex, sizey, top) {\r
+  if (!sizex && !sizey)\r
+       return;\r
+  var i, j;\r
+  var d = document.createElement("div");\r
+  d.style.backgroundColor = bk;\r
+  var lastarc = 0;\r
+  for (i = 1; i <= sizey; i++) {\r
+    var coverage, arc2, arc3;\r
+    // Find intersection of arc with bottom of pixel row\r
+    arc = Math.sqrt(1.0 - Math.sqr(1.0 - i / sizey)) * sizex;\r
+    // Calculate how many pixels are bg, fg and blended.\r
+    var n_bg = sizex - Math.ceil(arc);\r
+    var n_fg = Math.floor(lastarc);\r
+    var n_aa = sizex - n_bg - n_fg;\r
+    // Create pixel row wrapper\r
+    var x = document.createElement("div");\r
+    var y = d;\r
+    x.style.margin = "0px " + n_bg + "px";\r
+       x.style.height='1px';\r
+       x.style.overflow='hidden';\r
+    // Make a wrapper per anti-aliased pixel (at least one)\r
+    for (j = 1; j <= n_aa; j++) {\r
+      // Calculate coverage per pixel\r
+      // (approximates circle by a line within the pixel)\r
+      if (j == 1) {\r
+        if (j == n_aa) {\r
+          // Single pixel\r
+          coverage = ((arc + lastarc) * .5) - n_fg;\r
+        }\r
+        else {\r
+          // First in a run\r
+          arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;\r
+          coverage = (arc2 - (sizey - i)) * (arc - n_fg - n_aa + 1) * .5;\r
+          // Coverage is incorrect. Why?\r
+          coverage = 0;\r
+        }\r
+      }\r
+      else if (j == n_aa) {\r
+        // Last in a run\r
+        arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;\r
+        coverage = 1.0 - (1.0 - (arc2 - (sizey - i))) * (1.0 - (lastarc - n_fg)) * .5;\r
+      }\r
+      else {\r
+        // Middle of a run\r
+        arc3 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j) / sizex)) * sizey;\r
+        arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;\r
+        coverage = ((arc2 + arc3) * .5) - (sizey - i);\r
+      }\r
+      \r
+      x.style.backgroundColor = Blend(bk, color, coverage);\r
+         if (top)\r
+             y.appendChild(x);\r
+      else\r
+             y.insertBefore(x, y.firstChild);\r
+      y = x;\r
+      var x = document.createElement("div");\r
+               x.style.height='1px';\r
+               x.style.overflow='hidden';\r
+      x.style.margin = "0px 1px";\r
+    }\r
+    x.style.backgroundColor = color;\r
+    if (top)\r
+           y.appendChild(x);\r
+    else\r
+               y.insertBefore(x, y.firstChild);\r
+    lastarc = arc;\r
+  }\r
+  if (top)\r
+         el.insertBefore(d, el.firstChild);\r
+  else\r
+         el.appendChild(d);\r
+}\r
+\r
+function getElements(className) {\r
+       var elements = [];\r
+       var el = document.getElementsByTagName('DIV');  \r
+       var regexp=new RegExp("\\b"+className+"\\b");\r
+       for (var i = 0; i < el.length; i++) \r
+       {\r
+               if (regexp.test(el[i].className)) \r
+                       elements.push(el[i]);\r
+       }\r
+       return elements;\r
+}\r
+\r
+function get_current_style(element,property,not_accepted)\r
+{\r
+  var ee,i,val,apr;\r
+  try\r
+  {\r
+    var cs=document.defaultView.getComputedStyle(element,'');\r
+    val=cs.getPropertyValue(property);\r
+  }\r
+  catch(ee)\r
+  {\r
+    if(element.currentStyle)\r
+       {\r
+           apr=property.split("-");\r
+           for(i=1;i<apr.length;i++) apr[i]=apr[i].toUpperCase();\r
+           apr=apr.join("");\r
+           val=element.currentStyle.getAttribute(apr);\r
+   }\r
+  }\r
+  if((val.indexOf("rgba") > -1 || val==not_accepted) && element.parentNode)\r
+  {\r
+        if(element.parentNode != document) \r
+                val=get_current_style(element.parentNode,property,not_accepted);\r
+        else\r
+                val = '#FFFFFF';\r
+  }\r
+  if (val.indexOf("rgb") > -1 && val.indexOf("rgba") == -1)\r
+         val = rgb2hex(val);\r
+  if (val.length == 4)\r
+         val = '#'+val.substring(1,1)+val.substring(1,1)+val.substring(2,1)+val.substring(2,1)+val.substring(3,1)+val.substring(3,1);\r
+  return val;\r
+}\r
+\r
+function rgb2hex(value)\r
+{\r
+       var x = 255;\r
+       var hex = '';\r
+       var i;\r
+       var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;\r
+       var array=regexp.exec(value);\r
+       for(i=1;i<4;i++) hex += ('0'+parseInt(array[i]).toString(16)).slice(-2);\r
+       return '#'+hex;\r
+}\r
diff --git a/scaffolding/Scaffolding.php b/scaffolding/Scaffolding.php
new file mode 100644 (file)
index 0000000..28172ca
--- /dev/null
@@ -0,0 +1,291 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
+/**\r
+ * CodeIgniter\r
+ *\r
+ * An open source application development framework for PHP 4.3.2 or newer\r
+ *\r
+ * @package            CodeIgniter\r
+ * @author             ExpressionEngine Dev Team\r
+ * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
+ * @license            http://codeigniter.com/user_guide/license.html\r
+ * @link               http://codeigniter.com\r
+ * @since              Version 1.0\r
+ * @filesource\r
+ */\r
+\r
+// ------------------------------------------------------------------------\r
+\r
+/**\r
+ * Scaffolding Class\r
+ *\r
+ * Provides the Scaffolding framework\r
+ *\r
+ * @package            CodeIgniter\r
+ * @subpackage Scaffolding\r
+ * @author             ExpressionEngine Dev Team\r
+ * @link               http://codeigniter.com/user_guide/general/scaffolding.html\r
+ */\r
+class Scaffolding {\r
+\r
+       var $CI;\r
+       var $current_table;\r
+       var $base_url = '';\r
+       var $lang = array();\r
+\r
+       function Scaffolding($db_table)\r
+       {\r
+               $this->CI =& get_instance();\r
+               \r
+               $this->CI->load->database("", FALSE, TRUE);                     \r
+               $this->CI->load->library('pagination');\r
+               \r
+               // Turn off caching\r
+               $this->CI->db->cache_off();\r
+                               \r
+               /**\r
+                * Set the current table name\r
+                * This is done when initializing scaffolding:\r
+                * $this->load->scaffolding('table_name')\r
+                *\r
+                */\r
+               $this->current_table = $db_table;\r
+               \r
+               /**\r
+                * Set the path to the "view" files\r
+                * We'll manually override the "view" path so that\r
+                * the load->view function knows where to look.\r
+                */\r
+               \r
+               $this->CI->load->_ci_view_path = BASEPATH.'scaffolding/views/';\r
+\r
+               // Set the base URL\r
+               $this->base_url = $this->CI->config->site_url().'/'.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'both');\r
+               $this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'leading');\r
+\r
+               // Set a few globals\r
+               $data = array(\r
+                                               'image_url'     => $this->CI->config->system_url().'scaffolding/images/',\r
+                                               'base_uri'  => $this->base_uri,\r
+                                               'base_url'      => $this->base_url,\r
+                                               'title'         => $this->current_table\r
+                                       );\r
+               \r
+               $this->CI->load->vars($data);\r
+               \r
+               // Load the language file and create variables\r
+               $this->lang = $this->CI->load->scaffold_language('scaffolding', '', TRUE);\r
+               $this->CI->load->vars($this->lang);\r
+                               \r
+               //  Load the helper files we plan to use\r
+               $this->CI->load->helper(array('url', 'form'));\r
+               \r
+                               \r
+               log_message('debug', 'Scaffolding Class Initialized');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * "Add" Page\r
+        *\r
+        * Shows a form representing the currently selected DB\r
+        * so that data can be inserted\r
+        *\r
+        * @access      public\r
+        * @return      string  the HTML "add" page\r
+        */\r
+       function add()\r
+       {       \r
+               $data = array(\r
+                                               'title' =>  ( ! isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'],\r
+                                               'fields' => $this->CI->db->field_data($this->current_table),\r
+                                               'action' => $this->base_uri.'/insert'\r
+                                       );\r
+       \r
+               $this->CI->load->view('add', $data);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Insert the data\r
+        *\r
+        * @access      public\r
+        * @return      void    redirects to the view page\r
+        */\r
+       function insert()\r
+       {               \r
+               if ($this->CI->db->insert($this->current_table, $_POST) === FALSE)\r
+               {\r
+                       $this->add();\r
+               }\r
+               else\r
+               {\r
+                       redirect($this->base_uri.'/view/');\r
+               }\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * "View" Page\r
+        *\r
+        * Shows a table containing the data in the currently\r
+        * selected DB\r
+        *\r
+        * @access      public\r
+        * @return      string  the HTML "view" page\r
+        */\r
+       function view()\r
+       {\r
+               // Fetch the total number of DB rows\r
+               $total_rows = $this->CI->db->count_all($this->current_table);\r
+               \r
+               if ($total_rows < 1)\r
+               {\r
+                       return $this->CI->load->view('no_data');\r
+               }\r
+               \r
+               // Set the query limit/offset\r
+               $per_page = 20;\r
+               $offset = $this->CI->uri->segment(4, 0);\r
+               \r
+               // Run the query\r
+               $query = $this->CI->db->get($this->current_table, $per_page, $offset);\r
+\r
+               // Now let's get the field names                                \r
+               $fields = $this->CI->db->list_fields($this->current_table);\r
+               \r
+               // We assume that the column in the first position is the primary field.\r
+               $primary = current($fields);\r
+\r
+               // Pagination!\r
+               $this->CI->pagination->initialize(\r
+                                                       array(\r
+                                                                       'base_url'               => $this->base_url.'/view',\r
+                                                                       'total_rows'     => $total_rows,\r
+                                                                       'per_page'               => $per_page,\r
+                                                                       'uri_segment'    => 4,\r
+                                                                       'full_tag_open'  => '<p>',\r
+                                                                       'full_tag_close' => '</p>'\r
+                                                                       )\r
+                                                               );      \r
+\r
+               $data = array(\r
+                                               'title' =>  ( ! isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'],\r
+                                               'query'         => $query,\r
+                                               'fields'        => $fields,\r
+                                               'primary'       => $primary,\r
+                                               'paginate'      => $this->CI->pagination->create_links()\r
+                                       );\r
+                                               \r
+               $this->CI->load->view('view', $data);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * "Edit" Page\r
+        *\r
+        * Shows a form representing the currently selected DB\r
+        * so that data can be edited\r
+        *\r
+        * @access      public\r
+        * @return      string  the HTML "edit" page\r
+        */\r
+       function edit()\r
+       {\r
+               if (FALSE === ($id = $this->CI->uri->segment(4)))\r
+               {\r
+                       return $this->view();\r
+               }\r
+\r
+               // Fetch the primary field name\r
+               $primary = $this->CI->db->primary($this->current_table);                                \r
+\r
+               // Run the query\r
+               $query = $this->CI->db->get_where($this->current_table, array($primary => $id));\r
+\r
+               $data = array(\r
+                                               'title' =>  ( ! isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'],\r
+                                               'fields'        => $query->field_data(),\r
+                                               'query'         => $query->row(),\r
+                                               'action'        => $this->base_uri.'/update/'.$this->CI->uri->segment(4)\r
+                                       );\r
+       \r
+               $this->CI->load->view('edit', $data);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Update\r
+        *\r
+        * @access      public\r
+        * @return      void    redirects to the view page\r
+        */\r
+       function update()\r
+       {       \r
+               // Fetch the primary key\r
+               $primary = $this->CI->db->primary($this->current_table);                                \r
+\r
+               // Now do the query\r
+               $this->CI->db->update($this->current_table, $_POST, array($primary => $this->CI->uri->segment(4)));\r
+               \r
+               redirect($this->base_uri.'/view/');\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Delete Confirmation\r
+        *\r
+        * @access      public\r
+        * @return      string  the HTML "delete confirm" page\r
+        */\r
+       function delete()\r
+       {\r
+               if ( ! isset($this->lang['scaff_del_confirm']))\r
+               {\r
+                       $message = 'Are you sure you want to delete the following row: '.$this->CI->uri->segment(4);\r
+               }\r
+               else\r
+               {\r
+                       $message = $this->lang['scaff_del_confirm'].' '.$this->CI->uri->segment(4);\r
+               }\r
+               \r
+               $data = array(\r
+                                               'title'         => ( ! isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'],\r
+                                               'message'       => $message,\r
+                                               'no'            => anchor(array($this->base_uri, 'view'), ( ! isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']),\r
+                                               'yes'           => anchor(array($this->base_uri, 'do_delete', $this->CI->uri->segment(4)), ( ! isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes'])\r
+                                       );\r
+       \r
+               $this->CI->load->view('delete', $data);\r
+       }\r
+       \r
+       // --------------------------------------------------------------------\r
+       \r
+       /**\r
+        * Delete\r
+        *\r
+        * @access      public\r
+        * @return      void    redirects to the view page\r
+        */\r
+       function do_delete()\r
+       {               \r
+               // Fetch the primary key\r
+               $primary = $this->CI->db->primary($this->current_table);                                \r
+\r
+               // Now do the query\r
+               $this->CI->db->where($primary, $this->CI->uri->segment(4));\r
+               $this->CI->db->delete($this->current_table);\r
+\r
+               header("Refresh:0;url=".site_url(array($this->base_uri, 'view')));\r
+               exit;\r
+       }\r
+\r
+}\r
+\r
+/* End of file Scaffolding.php */\r
+/* Location: ./system/scaffolding/Scaffolding.php */
\ No newline at end of file
diff --git a/scaffolding/images/background.jpg b/scaffolding/images/background.jpg
new file mode 100644 (file)
index 0000000..9d5bdce
Binary files /dev/null and b/scaffolding/images/background.jpg differ
diff --git a/scaffolding/images/index.html b/scaffolding/images/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/scaffolding/images/logo.jpg b/scaffolding/images/logo.jpg
new file mode 100644 (file)
index 0000000..d6cc9a7
Binary files /dev/null and b/scaffolding/images/logo.jpg differ
diff --git a/scaffolding/index.html b/scaffolding/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/scaffolding/views/add.php b/scaffolding/views/add.php
new file mode 100644 (file)
index 0000000..cbb12f6
--- /dev/null
@@ -0,0 +1,32 @@
+<?php  $this->load->view('header');  ?>
+
+<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all); ?></p>
+
+
+<?php echo form_open($action); ?>
+
+<table border="0" cellpadding="3" cellspacing="1">
+<?php foreach($fields as $field): ?>
+
+<?php if ($field->primary_key == 1) continue; ?>
+
+<tr>
+       <td><?php echo $field->name; echo ' '.$field->default; ?></td>
+       
+       <?php if ($field->type == 'blob'): ?>
+       <td><textarea class="textarea" name="<?php echo $field->name; ?>" cols="60" rows="10" ><?php echo form_prep($field->default); ?></textarea></td>
+       <?php else : ?>
+       <td><input class="input" name="<?php echo $field->name; ?>" value="<?php echo form_prep($field->default); ?>" size="60" /></td>
+       <?php endif; ?>
+       
+</tr>
+<?php endforeach; ?>
+</table>
+
+<input type="submit" class="submit" value="Insert" />
+
+</form>
+
+<?php $this->load->view('footer'); 
+/* End of file add.php */
+/* Location: ./system/scaffolding/views/add.php */
diff --git a/scaffolding/views/delete.php b/scaffolding/views/delete.php
new file mode 100644 (file)
index 0000000..d195421
--- /dev/null
@@ -0,0 +1,9 @@
+<?php  $this->load->view('header');  ?>
+
+<p><?php echo $message; ?></p>
+
+<p><?php echo $no; ?>&nbsp;&nbsp;|&nbsp;&nbsp;<?php echo $yes; ?>
+
+<?php $this->load->view('footer'); 
+/* End of file delete.php */
+/* Location: ./system/scaffolding/views/delete.php */
diff --git a/scaffolding/views/edit.php b/scaffolding/views/edit.php
new file mode 100644 (file)
index 0000000..fe553e5
--- /dev/null
@@ -0,0 +1,33 @@
+<?php $this->load->view('header');  ?>
+
+
+<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all);?></p>
+
+
+<?php echo form_open($action); ?>
+
+<table border="0" cellpadding="3" cellspacing="1">
+<?php foreach($fields as $field): ?>
+
+<?php if ($field->primary_key == 1) continue; ?>
+
+<tr>
+       <td><?php echo  $field->name; ?></td>
+       
+       <?php if ($field->type == 'blob'): ?>
+       <td><textarea class="textarea" name="<?php echo $field->name;?>" cols="60" rows="10" ><?php $f = $field->name; echo form_prep($query->$f); ?></textarea></td>
+       <?php else : ?>
+       <td><input class="input" value="<?php $f = $field->name; echo form_prep($query->$f); ?>" name="<?php echo $field->name; ?>" size="60" /></td>
+       <?php endif; ?>
+       
+</tr>
+<?php endforeach; ?>
+</table>
+
+<input type="submit" class="submit" value="Update" />
+
+</form>
+
+<?php $this->load->view('footer'); 
+/* End of file edit.php */
+/* Location: ./system/scaffolding/views/edit.php */
\ No newline at end of file
diff --git a/scaffolding/views/footer.php b/scaffolding/views/footer.php
new file mode 100644 (file)
index 0000000..a287664
--- /dev/null
@@ -0,0 +1,10 @@
+\r
+</div>\r
+\r
+<div id="footer">\r
+<p><a href="http://codeigniter.com/">CodeIgniter</a>, by <a href="http://www.EllisLab.com">EllisLab</a> -  Version <?php echo CI_VERSION ?></p>\r
+<p>Page rendered in {elapsed_time}</p>\r
+</div>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/scaffolding/views/header.php b/scaffolding/views/header.php
new file mode 100644 (file)
index 0000000..50f234a
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+
+<title><?php echo $title; ?></title>
+
+<style type='text/css'>
+<?php $this->file(BASEPATH.'scaffolding/views/stylesheet.css'); ?>
+</style>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta http-equiv='expires' content='-1' />
+<meta http-equiv= 'pragma' content='no-cache' />
+
+</head>
+<body>
+
+<div id="header">
+<div id="header_left">
+<h3>Scaffolding:&nbsp; <?php echo $title; ?></h3>
+</div>
+<div id="header_right">
+<?php echo anchor(array($base_uri, 'view'), $scaff_view_records); ?> &nbsp;&nbsp;|&nbsp;&nbsp;
+<?php echo anchor(array($base_uri, 'add'),  $scaff_create_record); ?>
+</div>
+</div>
+
+<br clear="all">
+<div id="outer">
\ No newline at end of file
diff --git a/scaffolding/views/index.html b/scaffolding/views/index.html
new file mode 100644 (file)
index 0000000..065d2da
--- /dev/null
@@ -0,0 +1,10 @@
+<html>\r
+<head>\r
+       <title>403 Forbidden</title>\r
+</head>\r
+<body>\r
+\r
+<p>Directory access is forbidden.</p>\r
+\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/scaffolding/views/no_data.php b/scaffolding/views/no_data.php
new file mode 100644 (file)
index 0000000..bc81e74
--- /dev/null
@@ -0,0 +1,8 @@
+<?php  $this->load->view('header');  ?>
+
+<p><?php echo $scaff_no_data; ?></p>
+<p><?php echo anchor(array($base_uri, 'add'), $scaff_create_record); ?></p>
+
+<?php $this->load->view('footer'); 
+/* End of file no_data.php */
+/* Location: ./system/scaffolding/views/no_data.php */
\ No newline at end of file
diff --git a/scaffolding/views/stylesheet.css b/scaffolding/views/stylesheet.css
new file mode 100644 (file)
index 0000000..ba6ee0a
--- /dev/null
@@ -0,0 +1,143 @@
+body {\r
+ margin: 0;\r
+ padding: 0;\r
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+ font-size: 11px;\r
+ color: #4F5155;\r
+ background: #fff url(<?php echo $image_url; ?>background.jpg) repeat-x left top;\r
+}\r
+\r
+a {\r
+ color: #8B0D00;\r
+ background-color: transparent;\r
+ text-decoration: none;\r
+ font-weight: bold;\r
+}\r
+\r
+a:visited {\r
+ color: #8B0D00;\r
+ background-color: transparent;\r
+ text-decoration: none;\r
+}\r
+\r
+a:hover {\r
+ color: #000;\r
+ text-decoration: none;\r
+ background-color: transparent;\r
+}\r
+\r
+\r
+#header {\r
+ margin: 0;\r
+ padding: 0;\r
+}\r
+\r
+#header_left {\r
+ background-color: transparent;\r
+ float: left;\r
+ padding: 21px 0 0 32px;\r
+ margin: 0\r
+}\r
+\r
+#header_right {\r
+ background-color: transparent;\r
+ float: right;\r
+ text-align: right;\r
+ padding: 35px 50px 20px 0;\r
+ margin: 0\r
+}\r
+\r
+#footer {\r
+ margin: 20px 0 15px 0;\r
+ padding: 0;\r
+}\r
+\r
+#footer p {\r
+ font-size: 10px;\r
+ color: #999;\r
+ text-align: center;\r
+}\r
+\r
+#outer {\r
+ margin: 30px 40px 0 40px;\r
+}\r
+\r
+img {\r
+ padding:0;\r
+ border: 0;\r
+ margin: 0;\r
+}\r
+\r
+.nopad {\r
+ padding:0;\r
+ border: 0;\r
+ margin: 0;\r
+}\r
+\r
+table {\r
+ background-color: #efefef;\r
+}\r
+\r
+th {\r
+ background-color: #eee;\r
+ font-weight: bold;\r
+ padding: 6px;\r
+ text-align: left;\r
+}\r
+\r
+td {\r
+ background-color: #fff;\r
+ padding: 6px;\r
+}\r
+\r
+\r
+form {\r
+ margin: 0;\r
+ padding: 0;\r
+}\r
+\r
+.input {\r
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+ font-size: 11px;\r
+ width: 600px;\r
+ color: #333;\r
+ border: 1px solid #B3B4BD;\r
+ font-size: 11px;\r
+ height: 2em;\r
+ padding: 0;\r
+ margin: 0;\r
+}\r
+\r
+.textarea {\r
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;\r
+ font-size: 12px;\r
+ width: 600px;\r
+ color: #333;\r
+ border: 1px solid #B3B4BD;\r
+ padding: 0;\r
+ margin: 0;\r
+}\r
+\r
+.select {\r
+ background-color: #fff;\r
+ font-size:  11px;\r
+ font-weight: normal;\r
+ color: #333;\r
+ padding: 0;\r
+ margin: 0 0 3px 0;\r
+}\r
+\r
+.checkbox {\r
+ background-color: transparent;\r
+ padding: 0;\r
+ border: 0;\r
+}\r
+\r
+.submit {\r
+ background-color: #8B0D00;\r
+ color: #FFF;\r
+ font-weight: normal;\r
+ border: 1px solid #000;\r
+ margin: 6px 0 0 0;\r
+ padding: 1px 5px 1px 5px;\r
+}\r
diff --git a/scaffolding/views/view.php b/scaffolding/views/view.php
new file mode 100644 (file)
index 0000000..a81241d
--- /dev/null
@@ -0,0 +1,27 @@
+<?php  $this->load->view('header');  ?>
+
+<table border="0" cellpadding="0" cellspacing="1" style="width:100%">
+ <tr>
+       <th>Edit</th>
+       <th>Delete</th>
+       <?php foreach($fields as $field): ?>
+       <th><?php echo $field; ?></th>
+       <?php endforeach; ?>
+</tr>
+
+<?php foreach($query->result() as $row): ?>
+ <tr>
+       <td>&nbsp;<?php echo anchor(array($base_uri, 'edit', $row->$primary), $scaff_edit); ?>&nbsp;</td>
+       <td><?php echo anchor(array($base_uri, 'delete', $row->$primary), $scaff_delete); ?></td>
+       <?php foreach($fields as $field): ?>    
+       <td><?php echo form_prep($row->$field);?></td>
+       <?php endforeach; ?>
+ </tr>
+<?php endforeach; ?>
+</table>
+
+<?php echo $paginate; ?>
+
+<?php $this->load->view('footer'); 
+/* End of file view.php */
+/* Location: ./system/scaffolding/views/view.php */
\ No newline at end of file
diff --git a/www-register-wizard.spec b/www-register-wizard.spec
new file mode 100755 (executable)
index 0000000..ceee8f9
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# $Id: PLCWWW.spec 12168 2009-02-22 23:26:24Z thierry $
+#
+%define url $URL: https://svn.planet-lab.org/svn/www-register-wizard/trunk/www-register-wizard.spec $
+
+%define name www-register-wizard
+%define version 4.3
+%define taglevel 0
+
+%define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
+
+Summary: Registration Wizard for Nodes and PCUs
+Name: %{name}
+Version: %{version}
+Release: %{release}
+License: PlanetLab
+Group: System Environment/Daemons
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildArch: noarch
+
+Vendor: PlanetLab
+Packager: PlanetLab Central <support@planet-lab.org>
+Distribution: PlanetLab %{plrelease}
+URL: %(echo %{url} | cut -d ' ' -f 2)
+
+# We use set everywhere
+#Requires: httpd >= 2.0
+Requires: PLCWWW >= 4.2
+Requires: PLCAPI >= 4.2
+
+%description
+
+The www-register-wizard provides a web interface for MyPLC that integrates and
+serializes the steps required to register, configure and verify that a node is
+running correctly.  This is an improvement upon and replacement for the existing 'Add Node' and
+'Add PCU' forms.
+
+%prep
+%setup -q
+
+%build
+echo "There is no build stage for this component."
+echo "All files just need to be installed as is from the codebase."
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+echo "* www-register-wizard: Installing www-register-wizard pages"
+
+mkdir -p $RPM_BUILD_ROOT/var/www/html
+# let's be conservative and exclude codebase files, though there should not be any
+rsync -a --exclude \*.spec --exclude .svn ./ $RPM_BUILD_ROOT/var/www/html/registerwizard
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+/var/www/html/registerwizard
+
+%changelog
+* Fri Feb 27 2009 Stephen Soltesz <soltesz@cs.princeton.edu> -
+- Initial creation of spec file.