From f518b04d3f033c37fbefd7921cf038b55f360492 Mon Sep 17 00:00:00 2001 From: Sebastiaan Lauwers Date: Tue, 4 Mar 2008 00:06:50 +0100 Subject: [PATCH] carbonPHP Initial commit v2.0 This is the initial commit of carbonPHP. All of these files and the contents are by TomB Downloaded from: http://tombell.org.uk/~tomb/source/carbonphp/carbonphp-2.0-final.zip --- Documentation/database/active_record.html | 615 ++++++++++++++++++ Documentation/database/caching.html | 190 ++++++ Documentation/database/configuration.html | 125 ++++ Documentation/database/connecting.html | 150 +++++ Documentation/database/field_data.html | 150 +++++ Documentation/database/function_calls.html | 99 +++ Documentation/database/helpers.html | 158 +++++ Documentation/database/queries.html | 125 ++++ Documentation/database/quick.html | 196 ++++++ Documentation/database/result.html | 240 +++++++ Documentation/database/table_data.html | 95 +++ Documentation/database/transactions.html | 176 +++++ Documentation/database/utilities.html | 274 ++++++++ Documentation/general/autoloading.html | 73 +++ Documentation/general/caching.html | 102 +++ Documentation/general/carbonphp_libraries.html | 72 +++ Documentation/general/controllers.html | 367 +++++++++++ Documentation/general/core_libraries.html | 173 +++++ Documentation/general/creating_libraries.html | 311 +++++++++ Documentation/general/error_handling.html | 116 ++++ Documentation/general/extensions.html | 153 +++++ Documentation/general/models.html | 244 +++++++ Documentation/general/scaffolding.html | 133 ++++ Documentation/general/security.html | 127 ++++ Documentation/general/uri_routing.html | 175 +++++ Documentation/general/urls.html | 154 +++++ Documentation/general/views.html | 235 +++++++ Documentation/index.html | 161 +++++ Documentation/libraries/benchmark.html | 172 +++++ Documentation/libraries/config.html | 211 ++++++ Documentation/libraries/controller.html | 89 +++ Documentation/libraries/exception.html | 91 +++ Documentation/libraries/extensions.html | 83 +++ Documentation/libraries/input.html | 195 ++++++ Documentation/libraries/language.html | 146 +++++ Documentation/libraries/loader.html | 218 +++++++ Documentation/libraries/logging.html | 77 +++ Documentation/libraries/model.html | 76 +++ Documentation/libraries/output.html | 139 ++++ Documentation/libraries/pagination.html | 148 +++++ Documentation/libraries/router.html | 132 ++++ Documentation/libraries/table.html | 199 ++++++ Documentation/libraries/uri.html | 256 ++++++++ Documentation/libraries/zip.html | 219 +++++++ Documentation/utilities/filesystem.html | 158 +++++ Documentation/utilities/form.html | 309 +++++++++ Documentation/utilities/url.html | 266 ++++++++ Documentation/utilities/uuid.html | 95 +++ Documentation/utilities/xml.html | 102 +++ Source/application/config/autoload.php | 36 ++ Source/application/config/config.php | 64 ++ Source/application/config/database.php | 59 ++ Source/application/config/extensions.php | 68 ++ Source/application/config/routing.php | 32 + Source/application/controllers/carbon.php | 23 + Source/application/errors/error.php | 34 + Source/application/errors/error_404.php | 38 ++ Source/application/errors/error_database.php | 34 + Source/application/errors/error_php.php | 10 + Source/application/views/carbon_view.php | 55 ++ Source/application/views/stylesheet.css | 23 + Source/carbon/config/autoload.php | 36 ++ Source/carbon/config/config.php | 64 ++ Source/carbon/config/database.php | 59 ++ Source/carbon/config/extensions.php | 68 ++ Source/carbon/config/routing.php | 32 + Source/carbon/core/Base.php | 32 + Source/carbon/core/Carbon_Core.php | 109 ++++ Source/carbon/core/Common.php | 163 +++++ Source/carbon/database/Database.php | 65 ++ Source/carbon/database/Database_active_record.php | 545 ++++++++++++++++ Source/carbon/database/Database_cache.php | 129 ++++ Source/carbon/database/Database_driver.php | 714 +++++++++++++++++++++ Source/carbon/database/Database_result.php | 208 ++++++ Source/carbon/database/Database_utility.php | 296 +++++++++ .../carbon/database/drivers/mssql/mssql_driver.php | 199 ++++++ .../carbon/database/drivers/mssql/mssql_result.php | 80 +++ .../database/drivers/mssql/mssql_utility.php | 50 ++ .../carbon/database/drivers/mysql/mysql_driver.php | 226 +++++++ .../carbon/database/drivers/mysql/mysql_result.php | 80 +++ .../database/drivers/mysql/mysql_utility.php | 143 +++++ Source/carbon/languages/english/database_lang.php | 30 + .../carbon/languages/english/scaffolding_lang.php | 24 + Source/carbon/libraries/Benchmark.php | 55 ++ Source/carbon/libraries/Config.php | 158 +++++ Source/carbon/libraries/Controller.php | 71 ++ Source/carbon/libraries/Exception.php | 97 +++ Source/carbon/libraries/Extensions.php | 143 +++++ Source/carbon/libraries/Input.php | 524 +++++++++++++++ Source/carbon/libraries/Language.php | 79 +++ Source/carbon/libraries/Loader.php | 520 +++++++++++++++ Source/carbon/libraries/Logging.php | 88 +++ Source/carbon/libraries/Model.php | 46 ++ Source/carbon/libraries/Output.php | 204 ++++++ Source/carbon/libraries/Pagination.php | 158 +++++ Source/carbon/libraries/Router.php | 393 ++++++++++++ Source/carbon/libraries/Table.php | 307 +++++++++ Source/carbon/libraries/Uri.php | 198 ++++++ Source/carbon/libraries/Zip.php | 258 ++++++++ Source/carbon/scaffolding/Scaffolding.php | 180 ++++++ Source/carbon/scaffolding/images/background.jpg | Bin 0 -> 410 bytes Source/carbon/scaffolding/views/add.php | 30 + Source/carbon/scaffolding/views/delete.php | 7 + Source/carbon/scaffolding/views/edit.php | 30 + Source/carbon/scaffolding/views/footer.php | 10 + Source/carbon/scaffolding/views/header.php | 29 + Source/carbon/scaffolding/views/no_data.php | 6 + Source/carbon/scaffolding/views/stylesheet.css | 143 +++++ Source/carbon/scaffolding/views/view.php | 29 + Source/carbon/utilities/filesystem_utility.php | 122 ++++ Source/carbon/utilities/form_utility.php | 265 ++++++++ Source/carbon/utilities/url_utility.php | 376 +++++++++++ Source/carbon/utilities/uuid_utility.php | 24 + Source/carbon/utilities/xml_utility.php | 25 + Source/index.php | 37 ++ changelog.txt | 41 ++ 116 files changed, 17051 insertions(+) create mode 100644 Documentation/database/active_record.html create mode 100644 Documentation/database/caching.html create mode 100644 Documentation/database/configuration.html create mode 100644 Documentation/database/connecting.html create mode 100644 Documentation/database/field_data.html create mode 100644 Documentation/database/function_calls.html create mode 100644 Documentation/database/helpers.html create mode 100644 Documentation/database/queries.html create mode 100644 Documentation/database/quick.html create mode 100644 Documentation/database/result.html create mode 100644 Documentation/database/table_data.html create mode 100644 Documentation/database/transactions.html create mode 100644 Documentation/database/utilities.html create mode 100644 Documentation/general/autoloading.html create mode 100644 Documentation/general/caching.html create mode 100644 Documentation/general/carbonphp_libraries.html create mode 100644 Documentation/general/controllers.html create mode 100644 Documentation/general/core_libraries.html create mode 100644 Documentation/general/creating_libraries.html create mode 100644 Documentation/general/error_handling.html create mode 100644 Documentation/general/extensions.html create mode 100644 Documentation/general/models.html create mode 100644 Documentation/general/scaffolding.html create mode 100644 Documentation/general/security.html create mode 100644 Documentation/general/uri_routing.html create mode 100644 Documentation/general/urls.html create mode 100644 Documentation/general/views.html create mode 100644 Documentation/index.html create mode 100644 Documentation/libraries/benchmark.html create mode 100644 Documentation/libraries/config.html create mode 100644 Documentation/libraries/controller.html create mode 100644 Documentation/libraries/exception.html create mode 100644 Documentation/libraries/extensions.html create mode 100644 Documentation/libraries/input.html create mode 100644 Documentation/libraries/language.html create mode 100644 Documentation/libraries/loader.html create mode 100644 Documentation/libraries/logging.html create mode 100644 Documentation/libraries/model.html create mode 100644 Documentation/libraries/output.html create mode 100644 Documentation/libraries/pagination.html create mode 100644 Documentation/libraries/router.html create mode 100644 Documentation/libraries/table.html create mode 100644 Documentation/libraries/uri.html create mode 100644 Documentation/libraries/zip.html create mode 100644 Documentation/utilities/filesystem.html create mode 100644 Documentation/utilities/form.html create mode 100644 Documentation/utilities/url.html create mode 100644 Documentation/utilities/uuid.html create mode 100644 Documentation/utilities/xml.html create mode 100644 Source/application/config/autoload.php create mode 100644 Source/application/config/config.php create mode 100644 Source/application/config/database.php create mode 100644 Source/application/config/extensions.php create mode 100644 Source/application/config/routing.php create mode 100644 Source/application/controllers/carbon.php create mode 100644 Source/application/errors/error.php create mode 100644 Source/application/errors/error_404.php create mode 100644 Source/application/errors/error_database.php create mode 100644 Source/application/errors/error_php.php create mode 100644 Source/application/views/carbon_view.php create mode 100644 Source/application/views/stylesheet.css create mode 100644 Source/carbon/config/autoload.php create mode 100644 Source/carbon/config/config.php create mode 100644 Source/carbon/config/database.php create mode 100644 Source/carbon/config/extensions.php create mode 100644 Source/carbon/config/routing.php create mode 100644 Source/carbon/core/Base.php create mode 100644 Source/carbon/core/Carbon_Core.php create mode 100644 Source/carbon/core/Common.php create mode 100644 Source/carbon/database/Database.php create mode 100644 Source/carbon/database/Database_active_record.php create mode 100644 Source/carbon/database/Database_cache.php create mode 100644 Source/carbon/database/Database_driver.php create mode 100644 Source/carbon/database/Database_result.php create mode 100644 Source/carbon/database/Database_utility.php create mode 100644 Source/carbon/database/drivers/mssql/mssql_driver.php create mode 100644 Source/carbon/database/drivers/mssql/mssql_result.php create mode 100644 Source/carbon/database/drivers/mssql/mssql_utility.php create mode 100644 Source/carbon/database/drivers/mysql/mysql_driver.php create mode 100644 Source/carbon/database/drivers/mysql/mysql_result.php create mode 100644 Source/carbon/database/drivers/mysql/mysql_utility.php create mode 100644 Source/carbon/languages/english/database_lang.php create mode 100644 Source/carbon/languages/english/scaffolding_lang.php create mode 100644 Source/carbon/libraries/Benchmark.php create mode 100644 Source/carbon/libraries/Config.php create mode 100644 Source/carbon/libraries/Controller.php create mode 100644 Source/carbon/libraries/Exception.php create mode 100644 Source/carbon/libraries/Extensions.php create mode 100644 Source/carbon/libraries/Input.php create mode 100644 Source/carbon/libraries/Language.php create mode 100644 Source/carbon/libraries/Loader.php create mode 100644 Source/carbon/libraries/Logging.php create mode 100644 Source/carbon/libraries/Model.php create mode 100644 Source/carbon/libraries/Output.php create mode 100644 Source/carbon/libraries/Pagination.php create mode 100644 Source/carbon/libraries/Router.php create mode 100644 Source/carbon/libraries/Table.php create mode 100644 Source/carbon/libraries/Uri.php create mode 100644 Source/carbon/libraries/Zip.php create mode 100644 Source/carbon/scaffolding/Scaffolding.php create mode 100644 Source/carbon/scaffolding/images/background.jpg create mode 100644 Source/carbon/scaffolding/views/add.php create mode 100644 Source/carbon/scaffolding/views/delete.php create mode 100644 Source/carbon/scaffolding/views/edit.php create mode 100644 Source/carbon/scaffolding/views/footer.php create mode 100644 Source/carbon/scaffolding/views/header.php create mode 100644 Source/carbon/scaffolding/views/no_data.php create mode 100644 Source/carbon/scaffolding/views/stylesheet.css create mode 100644 Source/carbon/scaffolding/views/view.php create mode 100644 Source/carbon/utilities/filesystem_utility.php create mode 100644 Source/carbon/utilities/form_utility.php create mode 100644 Source/carbon/utilities/url_utility.php create mode 100644 Source/carbon/utilities/uuid_utility.php create mode 100644 Source/carbon/utilities/xml_utility.php create mode 100644 Source/index.php create mode 100644 changelog.txt diff --git a/Documentation/database/active_record.html b/Documentation/database/active_record.html new file mode 100644 index 0000000..4847e41 --- /dev/null +++ b/Documentation/database/active_record.html @@ -0,0 +1,615 @@ + + + CarbonPHP Documentation + + + + +
+

Active Record Class

+ +

CarbonPHP implements a modified version of the active record design pattern. This pattern allows + information to be retrieved, inserted, and updated in your database with minimal coding. In some cases + only one or two lines of code are needed. CarbonPHP does not require that each database table be its own + class file. It instead provides a more simpler interface.

+ +

Beyond the simplicity a major benefit of using the active record class is that it will allow you to + create database independent applications, since query syntax is generated by each database driver.

+
+ +
+

Selecting Data

+ +

The following examples show you how you can build SELECT statements for getting data from a + database.

+
+ +
+

$this->db-get()

+ +

This method runs the query and returns the results object. This can be used itself to retrieve all the + rows from a table.

+ +
+ $query = $this->db->get('some_table');
+
+ // This produces: SELECT * FROM some_table +
+ +

The second and third parameters allow you to specify a limit and offset.

+ +
+ $query = $this->db->get('some_table', 10, 20);
+
+ // This produces: SELECT * FROM some_table LIMIT 20, 10 +
+
+ +
+

$this->db->getwhere()

+ +

This method is identical to the above one except that it allows you to add a 'where' clause to the + statement, instead of using $this->db->where().

+ +
+ $query = $this->db->getwhere('some_table', array('id' => $id), $limit, $offset); +
+ +

The where() method is outlined below.

+
+ +
+

$this->db->select()

+ +

This method allows you to write the SELECT part of your queries.

+ +
+ $this->db->select('title, author, post');
+
+ $query = $this->db->get('some_table');
+
+ // This produces: SELECT title, author, post FROM some_table +
+ +

If you are selecting all (*) from a table, you can omit this method.

+
+ +
+

$this->db->from()

+ +

This method allows you to write the FROM part of your queries.

+ +
+ $this->db->select('title, author, post');
+ $this->db->from('some_table');
+ $this->db->get();
+
+ // This produces: SELECT title, author, post FROM some_table +
+ +

As shown above the FROM part of your query can be passed in the get() method.

+
+ +
+

$this->db->join()

+ +

This method allows you to write the JOIN parts of your queries.

+ +
+ $this->db->select('*');
+ $this->db->from('blogs');
+ $this->db->join('comments', 'comments.id = blogs.id');
+
+ $query = $this->db->get();
+
+ // This produces:
+ // SELECT * FROM blogs
+ // JOIN comments ON comments.id = blogs.id +
+ +

Multiple function call can be made if you need several joins in one query.

+ +

If you need something other than a natural JOIN you can specify it via the third parameter of the function. + Options are, left, right, outer, inner, left outer, and right outer.

+ +
+ $this->db->join('comments', 'comments.id = blogs.id', 'left');
+
+ // This produces: LEFT JOIN comments ON comments.id = blogs.id +
+
+ +
+

$this->db->where()

+ +

This method enables you to create WHERE clauses using one of four methods.

+ +
    +
  1. + Simple key/value array method + +
    + $this->db->where('name', $name);
    +
    + // This produces: WHERE name = 'John'; +
    + +

    You may notice that the equals sign is added for you.

    + +

    You can use multiple method calls to chain together with AND between them.

    + +
    + $this->db->where('name' => $name);
    + $this->db->where('title' => $title);
    + $this->db->where('status' => $status);
    +
    + // This produces: WHERE name = 'John' AND title = 'Student' AND status = 'active' +
    +
  2. + +
  3. + Custom key/value array method + +

    You can include an operator in the first parameter in order to control how the comparsion occurs.

    + +
    + $this->db->where('name !=', $name);
    + $this->db->where('id <', $id);
    +
    + // This produces: WHERE name != 'John' AND id < 4 +
    +
  4. + +
  5. + Associative array method + +
    + $array = array('name' => $name, 'title' => $title, 'status' => $status);
    +
    + $this->db->where($array);
    +
    + // This produces: WHERE name = 'John' AND title = 'Student' AND status 'active' +
    + +

    You can include your own operators using this method as well.

    + +
    + $array = array('name !=' => $name, 'id <' => $id);
    +
    + $this->db->where($array); +
    +
  6. + +
  7. + Custom string + +

    You can write your own WHERE clauses manually.

    + +
    + $where = "name='John' AND status='Student' OR status='active'";
    +
    + $this->db->where($where); +
    +
  8. +
+
+ +
+

$this->db->orwhere()

+ +

This method is identical to the above one, except that multiple instances are joined by OR.

+ +
+ $this->db->where('name !=', $name);
+ $this->db->orwhere('id >', $id);
+
+ // This produces: WHERE name != 'John' OR id > 500 +
+
+ +
+

$this->db->like()

+ +

This method enables you to generate LIKE clauses, these are useful for doing searches.

+ +
    +
  1. + Simple key/value array method + +
    + $this->db->like('title', $match);
    +
    + // This produces: WHERE title LINK '%match%' +
    + +

    If you use multiple method calls they will be joined with AND between them.

    + +
    + $this->db->like('title', $match);
    + $this->db->like('body', $match);
    +
    + // This produces: WHERE title LIKE '%match%' AND body LIKE '%match%' +
    +
  2. + +
  3. + Associative array method + +
    + $array = array('title' => $match, 'page1' => $match, 'page2' => $match);
    +
    + $this->db->like($array);
    +
    + // This produces: WHERE title LIKE '%match%' AND page1 LIKE '%match%' AND 'page2' LIKE '%match%' +
    +
  4. +
+
+ +
+

$this->db->orlike()

+ +

This method is identical to the above one except that multiple calls will be joined with OR.

+ +
+ $this->db->like('title', $match);
+ $this->db->orlike('body', $match);
+
+ // This produces: WHERE title LIKE '%match%' OR body LIKE '%match%' +
+
+ +
+

$this->db->groupby()

+ +

This method allows you to write GROUP BY parts of your queries.

+ +
+ $this->db->groupby('title');
+
+ // This produces: GROUP BY title +
+ +

You can also pass an array of multiple values.

+ +
+ $this->db->groupby(array('title', 'author'));
+
+ // This produces: GROUP BY title, author +
+
+ +
+

$this->db->having()

+ +

This method allows you to write the HAVING parts of your queries.

+ +
+ $this->db->having('user_id = 3');
+
+ // This produces: HAVING 'user_id = 3' +
+ +

You can also pass an array of multiple values to the method.

+ +
+ $this->db->having(array('title =' => 'Title', 'id <' => $id));
+
+ // This produces: HAVING title ='Title', 'id < 35' +
+
+ +
+

$this->db->orderby()

+ +

This method lets you set an ORDER BY clause. The first parameter contains the name of the column you + would like to order by. The second parameter allows you to set the direction of the result. The options + are asc, desc, or RAND().

+ +
+ $this->db->orderby('title', 'desc');
+
+ // This produces: ORDER BY title DESC +
+ +

You can also pass your own string in the first parameter.

+ +
+ $this->db->orderby('title desc, name asc');
+
+ // This produces: ORDER BY title DESC, name ASC +
+
+ +
+

$this->db->limit()

+ +

This method lets you limit the number of rows that you would like returned.

+ +
+ $this->db->limit(10);
+
+ // This produces: LIMIT 10 +
+ +

The second parameter lets you specify a result offset.

+ +
+ $this->db->limit(10, 20);
+
+ // This produces: LIMIT 20, 10 +
+
+ +
+

$this->db->count_all()

+ +

This method allows you to determine the number of rows in the table.

+ +
+ $this->db->count_all('some_table');
+
+
+ +
+

Inserting Data

+ +

These methods provide an interface for inserting data into a database.

+
+ +
+

$this->db->insert()

+ +

This method generates an insert string based on the data you supply, and runs the query. You can either + either pass an array or an object to the method.

+ +
+ $data = array(
+     'title' => 'My Title',
+     'author' => 'My Author',
+     'date' => 'My Date'
+ );
+
+ $this->db->insert('some_table', $data);
+
+ // This produces: INSERT INTO some_table (title, author, date) VALUES ('My Title, 'My Author', 'My Date') +
+ +

The first parameter will contain the table name, the second parameter is an array of values.

+ +
+ /*
+ class MyClass
+ {
+     public $title = 'My Title';
+     public $content = 'Content';
+     public $date = 'My Date';
+ }
+ */
+
+ $object = new MyClass();
+
+ $this->db->insert('some_table', $object);
+
+ // This produces: INSERT INTO some_table (title, content, date) VALUE ('My Title', 'Content', 'My Date') +
+ +

The first parameter is the table name, and the second parameter is an object with member variables.

+
+ +
+

$this->db->set()

+ +

This method allows you to set values for INSERT and UPDATE queries.

+ +

This method can be used instead of passing an array directly to the insert() or update() + methods.

+ +
+ $this->db->set('name', $name);
+ $this->db->insert('some_table');
+
+ // This produces: INSERT INTO some_table (name) VALUES ('{$name}') +
+ +

This method allows you to call it multiple times and will correctly build the query based on whether you + are doing an INSERT or UPDATE.

+ +
+ $this->db->set('name', $name);
+ $this->db->set('title', $title);
+ $this->db->set('date', $date);
+ $this->db->insert('some_table'); +
+ +

You can also pass an associative array to the method.

+ +
+ $array = array('name' => $name, 'title' => $title, 'date' => $date);
+
+ $this->db->set($array);
+ $this->db->insert('some_table'); +
+ +

You can also pass an object to the method.

+ +
+ /*
+ class MyClass
+ {
+     public $title = 'My Title';
+     public $content = 'Content';
+     public $date = 'My Date';
+ }
+ */
+
+ $object = new MyClass();
+
+ $this->db->set($object);
+ $this->db->insert('some_table'); +
+
+ +
+

Updating Data

+ +

These methods provide an interface for updating data in a database.

+
+ +
+

$this->db->update()

+ +

This method generates an update string and runs the query based on the data you supply. You can pass an + array or an object to the method.

+ +
+ $data = array(
+     'title' => $title,
+     'author' => $author,
+     'date' => $date
+ );
+
+ $this->db->where('id', $id);
+ $this->db->update('some_table', $data);
+
+ // This produces:
+ // UPDATE some_table
+ // SET title = '{$title}', name = '{$name}', date = '{$date}'
+ // WHERE id = $id +
+ +

You can also choose to supply an object to the method.

+ +
+ /*
+ class MyClass
+ {
+     public $title = 'My Title';
+     public $content = 'Content';
+     public $date = 'My Date';
+ }
+ */
+
+ $this->db->where('id', $id);
+ $this->db->update('some_table');
+
+ // This produces:
+ // UPDATE some_table
+ // SET title = '{$title}', name = '{$name}', date = '{$date}'
+ // WHERE id = $id +
+ +

You will notice the use of the where() method, enabling you to set the WHERE clause. You can + optionally pass this information directly into the update method as a string.

+ +
+ $this->db->update('some_table', $data, 'id = 4'); +
+ +

You can also choose to pass an array to the method.

+ +
+ $this->db->update('some_table', $data, array('id' => $id)); +
+ +

You can also use the set() method described above when performing updates.

+
+ +
+

Deleting Data

+ +

These methods provide an interface for deleting data from databases.

+
+ +
+

$this->db->delete()

+ +

This method generates a DELETE SQL string and runs the query.

+ +
+ $this->db->delete('some_table', array('id' => $id));
+
+ // This produces:
+ // DELETE FROM some_table
+ // WHERE id = $id +
+ +

The first parameter is the table name, the second parameter is the where clause. You can also use + the where() or orwhere() methods instead of passing the data.

+ +
+ $this->db->where('id', $id);
+ $this->db->delete('some_table');
+
+ // This produces:
+ // DELETE FROM some_table
+ // WHERE id = $id +
+
+ +
+

Method Chaining

+ +

Method chaining allows you to simplify your syntax by connecting multiple methods.

+ +
+ $this->db->select('title')->from('some_table')->where('id', $id)->limit(10, 20);
+
+ $query = $this->db->get(); +
+
+ + + diff --git a/Documentation/database/caching.html b/Documentation/database/caching.html new file mode 100644 index 0000000..82be2fb --- /dev/null +++ b/Documentation/database/caching.html @@ -0,0 +1,190 @@ + + + CarbonPHP Documentation + + + + +
+

Database Caching

+ +

The database class allows you to cache your queries as text files for reducing the database load.

+ +

The caching class is loaded automatically loaded by the database class you do not have to manually load + it.

+
+ +
+

Enabling Caching

+ +

Caching is enabled by following these three steps.

+ + + +

Once caching is enabled caching will happen automatically whenever a page is loaded that contains any + database queries.

+
+ +
+

How Does Caching Work

+ +

CarbonPHP caching happens dynamically when your pages are viewed. When caching is enabled the first time + a page is loaded the query result object will be serialised and stored in a text file on the server. The next + time the page is loaded the cache file will be served instead of accessing the database.

+ +

Only 'read' type queries can be cached, since these are the only type of queries that produce a result + object.

+ +

Cache files do not expire. Any queries that have been called will remain cached until you delete them. + The caching system permits you to clear caches associated with individual pages, or you can delete the + whole set of cache files.

+
+ +
+

Does Caching Improve Site Performance

+ +

Getting a performance gain as a result of caching depends on many factors. If you have a highly optimised + database under very little load you will probably not noticed an improved performance. If your database + is under heavy load you probably will see an improved response.

+ +

In some clustered server environments for example caching may be detrimental since file system operations + are so instense. On single servers in shared environments caching you probably be more benficial.

+
+ +
+

How are Cache Files Stored

+ +

CarbonPHP places the result of each query into it's own cache file which are then organised into + subdirectories corresponding to the name of your controller and method.

+ +

For example if you have a controller called blog and a method called post that contains + three queries, the caching system will create a cache directory called blog+post into which it + will create three cache files, one for each query.

+
+ +
+

Managing Cache Files

+ +

Since cache files do not expire you will need to use the built in deletion methods to remove old cache + files.

+
+ +
+

Unsupported Methods

+ +

Some methods are not supported by the caching system.

+ + + +

The database connection ID and result ID are not available when caching.

+
+ +
+

$this->db->cache_on() and $this->db->cache_off()

+ +

This method enables and disabled the caching manually. This can be useful if you wish to keep certain + queries from being cached.

+ +
+ $this->db->cache_on();
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ $this->db->cache_off();
+ $query = $this->db->query('SELECT * FROM `another_table`');
+
+ $this->db->cache_on();
+ $query = $this->db->query('SELECT * FROM `more_table`'); +
+
+ +
+

$this->db->cache_delete()

+ +

This method deletes the cache files associated with a particular page. This is useful if you need to clear + a cache file after you update your database.

+ +

The caching system saves your cache files to directories correspond to the URI of the page you are viewing. + To delete the cache files of a controller and method you should the following.

+ +
+ $this->db->cache_delete('blog', 'posts'); +
+ +

If you do not pass any parameters to the function it will determine the cache files based on the current + URL.

+
+ +
+

$this->db->cache_delete_all()

+ +

Clears all the existing cache files.

+ +
+ $this->db->cache_delete_all(); +
+
+ + + diff --git a/Documentation/database/configuration.html b/Documentation/database/configuration.html new file mode 100644 index 0000000..92d45a0 --- /dev/null +++ b/Documentation/database/configuration.html @@ -0,0 +1,125 @@ + + + CarbonPHP Documentation + + + + +
+

Database Configuration

+ +

There is a configuration file that lets you store your database connection details. The configuration file + is in the application/config/database.php file.

+ +

The configuration settings are stored in a multi-dimensional array with the following prototype.

+ +
+ $database['default']['hostname'] = 'localhost';
+ $database['default']['username'] = 'root';
+ $database['default']['password'] = '';
+ $database['default']['database'] = 'database_name';
+ $database['default']['dbdriver'] = 'mysql';
+ $database['default']['dbprefix'] = '';
+ $database['default']['active_r'] = true;
+ $database['default']['pconnect'] = true;
+ $database['default']['db_debug'] = false; +
+ +

The reason a multi-dimensional array is used is that it allows more than one set of database connection + settings to be stored. Below is an example second set of connection details.

+ +
+ $database['test']['hostname'] = 'localhost';
+ $database['test']['username'] = 'root';
+ $database['test']['password'] = '';
+ $database['test']['database'] = 'database_name';
+ $database['test']['dbdriver'] = 'mysql';
+ $database['test']['dbprefix'] = '';
+ $database['test']['active_r'] = true;
+ $database['test']['pconnect'] = true;
+ $database['test']['db_debug'] = false; +
+ +

To globally tell CarbonPHP which connection settings to use you just set the $active_group + variable.

+ +
+ $active_group = 'test'; +
+
+ +
+

Configuration Options

+ + + +

Note: depending on which database driver you are using not all values will be needed. For example + when you are using the SQLite driver you will not need to supply a username or password, and the database + name will be the path to the database file.

+
+ + + diff --git a/Documentation/database/connecting.html b/Documentation/database/connecting.html new file mode 100644 index 0000000..91f6d08 --- /dev/null +++ b/Documentation/database/connecting.html @@ -0,0 +1,150 @@ + + + CarbonPHP Documentation + + + + +
+

Connecting to a Database

+ +

There are two methods of connecting to a database.

+
+ +
+

Connecting Automatically

+ +

The automatically connecting feature will loads and initialise the database class with every page load. To + enable this, add the database library to the autoload array in the + application/config/autoload.php file.

+
+ +
+

Connecting Manually

+ +

If you only need to connect to your database for some pages you can manually load the database class. To + load the database class you add the following method to any method or function where you need to use a + database.

+ +
+ $this->load->database(); +
+ +

If the method does not contain any parameters it will connect using the group specified in the database + configuration file application/config/database.php, this is the method most people will use.

+ +

The first parameter of the method can optionally be used to specify database connection settings.

+ +

You can pass a specific group name to the method to load a specific set of database connection settings.

+ +
+ $this->load->database('group_name'); +
+ +

You can also manually pass an array of connection settings to the method.

+ +
+ $config['hostname'] = 'localhost';
+ $config['username'] = 'myusername';
+ $config['password'] = 'mypassword';
+ $config['database'] = 'mydatabase';
+ $config['dbdriver'] = 'mysql';
+ $config['dbprefix'] = '';
+ $config['pconnect'] = false;
+ $config['db_debug'] = true;
+ $config['active_r'] = true;
+
+ $this->load->database($config); +
+ +

The individual settings are explained on the configuration page. You can even specify a data source name. + DSNs must have this prototype.

+ +
+ $dsn = 'dbdriver://username:password@hostname/database';
+
+ $this->load->database($dsn); +
+
+ +
+

Connecting to Multiple Databases

+ +

If you wish to connect to more than one database at the same time you can do the following.

+ +
+ $db1 = $this->load->database('group_one', true);
+ $db2 = $this->load->database('group_two', true); +
+ +

The words 'group_one' and 'group_two' are the group names for the connection settings. By setting the + second parameter to true the method will return the database object instead of assigning it to the + carbon object.

+ +

When you connect this way you will use your object name to call the methods.

+ +
+ $this->db->query();
+ $this->db->result();
+
+ // You will use the following instead...
+
+ $db1->query();
+ $db1->result(); +
+
+ + + diff --git a/Documentation/database/field_data.html b/Documentation/database/field_data.html new file mode 100644 index 0000000..190621d --- /dev/null +++ b/Documentation/database/field_data.html @@ -0,0 +1,150 @@ + + + CarbonPHP Documentation + + + + +
+

Field Meta Data

+ +

These are a set of methods that let you retrieve information about fields within a table.

+
+ +
+

$this->db->list_fields()

+ +

This method returns an array containing the names of the fields in the specified table. There are two ways + in which you can call this method.

+ +
    +
  1. +

    You can supply the table name and call it from the $this->db object.

    + +
    + $fields = $this->db->list_fields('some_table');
    +
    + foreach ($fields as $field)
    + {
    +     echo $field;
    + } +
    +
  2. + +
  3. +

    You can gather the field names associated with any query that you run.

    + +
    + $query = $this->db->query('SELECT * FROM `some_table`');
    +
    + foreach ($query->list_fields() as $field)
    + {
    +     echo $field;
    + } +
    +
  4. +
+
+ +
+

$this->db->field_exists()

+ +

This method returns whether a field in a table exists or not.

+ +
+ if ($this->db->field_exists('field_name', 'table_name'))
+ {
+     // Execute some code...
+ } +
+
+ +
+

$this->db->field_data()

+ +

This method returns an array of object containing the information for the specified field. Sometimes + it is helpful to gather informatin about field names.

+ +
+ $fields = $this->db->field_data('table_name');
+
+ foreach ($fields as $field)
+ {
+     echo $field->name;
+     echo $field->type;
+     echo $field->max_length;
+     echo $field->primary_key;
+ } +
+ +

If you have run a query already you can use the result object instead of supplying a table name.

+ +
+ $query = $this->db->query('SQL QUERY');
+ $fields = $query->field_data(); +
+ +

You can retrieve the following data about the fields.

+ + +
+ + + diff --git a/Documentation/database/function_calls.html b/Documentation/database/function_calls.html new file mode 100644 index 0000000..d9becd1 --- /dev/null +++ b/Documentation/database/function_calls.html @@ -0,0 +1,99 @@ + + + CarbonPHP Documentation + + + + +
+

Custom Function Calls

+ +

CarbonPHP provides a method that allows you to manually call a database function that are not implemented + in the CarbonPHP database classes. For example if you wish to call the MySQL function + mysql_get_client_info() which is not implemented in CarbonPHP you can do so using the following + method.

+ +
+ $this->db->call_function('get_client_info'); +
+ +

You have to supply the function name without the mysql_ prefix as CarbonPHP will automatically + prepend this to the function call based on the database driver being used.

+ +

If you need to pass parameters to the function you can add them by passing them as a second parameter and + onwards.

+ +
+ $this->db->call_function('some_function', $param1, $param2, ...); +
+ +

You may also need to pass the result ID or connection ID to the function, these can be access by doing the + following.

+ +
+ $this->db->conn_id; +
+ +

The result ID can be accessed by doing the following.

+ +
+ $query = $this->db->query('SQL QUERY');
+
+ $query->result_id; +
+
+ + + diff --git a/Documentation/database/helpers.html b/Documentation/database/helpers.html new file mode 100644 index 0000000..635bc05 --- /dev/null +++ b/Documentation/database/helpers.html @@ -0,0 +1,158 @@ + + + CarbonPHP Documentation + + + + +
+

Query Helper Methods

+ +

These are simple methods that may help you with your SQL queries.

+
+ +
+

$this->db->insert_id()

+ +

This method returns the ID number associated with the insert query performed.

+
+ +
+

$this->db->affected_rows()

+ +

This method returns the number of affected rows when performing a 'write' type query.

+ +

Note: in MySQL a 'DELETE FROM TABLE' query returns 0 affected rows. There is a hack written into + CarbonPHP that allows it to return the correct number of affected rows.

+
+ +
+

$this->db->count_all()

+ +

This method returns the number of rows in the specified table.

+ +
+ echo $this->db->count_all('blog_posts'); +
+
+ +
+

$this->db->platform()

+ +

This method outputs the database driver that you are using.

+
+ +
+

$this->db->version()

+ +

This method outputs the database version you are using.

+
+ +
+

$this->db->last_query()

+ +

This method returns the last query run as a string, not a result.

+ +
+ $string = $this->db->last_query();
+
+ // Produces: 'SELECT * FROM `some_table`' +
+
+ +
+

$this->db->insert_string()

+ +

This method simplifies the process of inserting data into the database. It returns a correctly formatted + string containing the database query.

+ +
+ $data = array('name' => $name, 'size' => $size, 'url' => $url);
+
+ $string = $this->db->insert_string('table_name', $data); +
+ +

The first parameter is the table name, and the second parameter is an array with the data to be inserted.

+ +
+ INSERT INTO `table_name` (name, size, url) VALUES ('shirt', 'large', 'www.your-domain.com/shirt/3') +
+
+ +
+

$this->db->update_string()

+ +

This method simplifies the process of writing database update queries. It returns a correctly formatted + string containing the database query.

+ +
+ $data = array('name' => $name, 'size' => $size, 'url' => $url);
+
+ $where = 'product_id = 1 AND status = "outofstock"';
+
+ $string = $this->db->update_string('table_name', $data, $where); +
+ +

This first parameter is the name of the table, the second parameter is an array of data to be inserted into + the database, and the third parameter is the where clause.

+ +
+ UPDATE table_name SET name = 'shirt', size = 'medium', url = 'www.your-domain.com/shirt/4' WHERE + product_id = 1 AND status = 'outofstock' +
+
+ + + diff --git a/Documentation/database/queries.html b/Documentation/database/queries.html new file mode 100644 index 0000000..fa47bb9 --- /dev/null +++ b/Documentation/database/queries.html @@ -0,0 +1,125 @@ + + + CarbonPHP Documentation + + + + +
+

Database Queries

+ +

These outline the ways in which you can submit queries to your database.

+
+ +
+

$this->db->query()

+ +

To submit a query you can use the following method.

+ +
+ $this->db->query('SQL QUERY HERE'); +
+ +

The query() method returns a database result object when 'read' type queries run, which you can + then use to show database results. When a 'write' type of query is used it will simply return a true or false + depending on success or failure. When retrieving data you will typically assign the return value to a + variable

+ +
+ $query = $this->db->query('SQL QUERY HERE'); +
+
+ +
+

$this->db->simple_query()

+ +

This is a simplified version of the query() method. It will only return true or false. It will + not return a database result set, nor does it set the query timer, or compile bind data, or store your query + for debugging. It simply submits a query.

+
+ +
+

Escaping SQL Queries

+ +

It is very good practice to escape your data that is being inserted into a database. CarbonPHP provides + two methods to help you do this.

+ +
    +
  1. $this->db->escape() - this method determines the data type so that it can escape only string + data. It also automatically adds single quotes around the data.
  2. +
  3. $this->db->escape_str() - this method escapes data regardless of the type. Most of the time + the above method will be used instead of this one.
  4. +
+
+ +
+

Query Binding

+ +

Binding enables you to simplify your SQL query syntax by letting CarbonPHP put the queries together for you. + Consider the following example.

+ +
+ $sql = 'SELECT * FROM `some_table` WHERE `id` = ? AND `status` = ? AND `author` = ?';
+
+ $this->db->query($sql, array(3, 'inprint', 'Charlie')); +
+ +

The question marks in the query are replaced by the values found in the array passed to the method in the + second parameter. Another benefit of using binds are that they automatically escape values producing + safer queries.

+
+ + + diff --git a/Documentation/database/quick.html b/Documentation/database/quick.html new file mode 100644 index 0000000..9b91aa9 --- /dev/null +++ b/Documentation/database/quick.html @@ -0,0 +1,196 @@ + + + CarbonPHP Documentation + + + + +
+

Database Quick Start

+ +

This page will show you some quick examples showing how you can go about interacting with your database + using CarbonPHP. If you wish for a more in depth outline please read the individual pages.

+
+ +
+

Initialising and Connecting to a Database

+ +

The following loads and initialises the database class which connects to a database based on your + configuration settings.

+ +
+ $this->load->database(); +
+ +

Once the class has been loaded, the database object will be available via the $this object and + used as shown in the examples below. Note: if all your controllers/page require database access you + can autoload the database library.

+
+ +
+

Simply Query With an Object Result

+ +
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ foreach ($query->result() as $row)
+ {
+     echo $row->title;
+     echo $row->author;
+     echo $row->body;
+ }
+
+ echo 'Total results: ' . $query->num_rows(); +
+ +

The above example uses the result() method to return an array of objects. These objects will have + member variables corrosponding to the field names. Example $row->title.

+
+ +
+

Simple Query With an Array Result

+ +
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ foreach ($query->result_array() as $row)
+ {
+     echo $row['title'];
+     echo $row['author'];
+     echo $row['body'];
+ }
+
+ echo 'Total results: ' . $query->num_rows(); +
+
+ +
+

Simple Query With a Single Object Result

+ +
+ $query = $this->db->query('SELECT title FROM `some_table` LIMIT 1');
+
+ $row = $query->row(); + echo $row->title; +
+ +

The above example uses the row() method to return an object.

+
+ +
+

Simple Query With a Single Array Result

+ +
+ $query = $this->db->query('SELECT title FROM `some_table` LIMIT 1');
+
+ $row = $query->row_array(); + echo $row['title']; +
+ +

The above example uses the row_array() method to return an array.

+
+ +
+

Simple Insert Query

+ +
+ $sql = 'INSERT INTO `some_table` (title, author) VALUES (' . $this->db->escape($title) . ', ' . + $this->db->escape($author) . ')';
+
+ $this->db->query($sql);
+
+ echo $this->db->affected_rows(); +
+
+ +
+

Simple Active Record Query

+ +

The Active Record design pattern gives you a simple interface for retrieving database data.

+ +
+ $query = $this->db->get('some_table');
+
+ foreach ($query->result() as $row)
+ {
+     echo $row->author;
+ }
+
+ +

The get() method retrieves all the results from the table name specified. The active record class + provides a range of methods for working with database data.

+
+ +
+

Simple Active Record Insert Query

+ +
+ $data = array(
+     'title' => $title,
+     'author' => $author,
+     'post' => $post
+ );
+
+ $this->db->insert('some_table', $data);
+
+ // Will produce: INSERT INTO `some_table` (title, author, post) VALUES ('{title}', '{$author}', '{$post}') +
+ +

The insert() method inserts data into the specified table name, you can pass either an array or + object.

+
+ + + diff --git a/Documentation/database/result.html b/Documentation/database/result.html new file mode 100644 index 0000000..e85c2d8 --- /dev/null +++ b/Documentation/database/result.html @@ -0,0 +1,240 @@ + + + CarbonPHP Documentation + + + + +
+

Query Results

+ +

There are several ways to generate query results in CarbonPHP.

+
+ +
+

result()

+ +

This method returns the query result as an array of objects, or an empty array on failure. Typically you'll + use this in a foreach () look like the following example.

+ +
+ $query = $this->db-query('SQL QUERY');
+
+ foreach ($query->result() as $row)
+ {
+     echo $row->title;
+     echo $row->author;
+     echo $row->post;
+ } +
+ +

This method is an alias of the result_object() method. If you run queries that may not produce + any results you are encouraged to test to see if there are any results.

+ +
+ $query = $this->db->query('SQL QUERY');
+
+ if ($query->num_rows() > 0)
+ {
+     foreach ($query->result() as $row)
+     {
+         echo $row->title;
+         echo $row->author;
+         echo $row->post;
+     }
+ } +
+
+ +
+

result_array()

+ +

This method returns the query result as a pure array, on an empty array on failure. Typically you will use + this in a foreach () loop like the following.

+ +
+ $query = $this->db-query('SQL QUERY');
+
+ foreach ($query->result_array() as $row)
+ {
+     echo $row['title'];
+     echo $row['author'];
+     echo $row['post'];
+ } +
+
+ +
+

row()

+ +

The method returns a single result row. If you query has more than one result in the row it returns only + the first row. The first is returned as an object.

+ +
+ $query = $this->db->query('SQL QUERY');
+
+ if ($query->num_rows() > 0)
+ {
+     $row = $query->row();
+
+     echo $row->title;
+     echo $row->author;
+     echo $row->post;
+ } +
+ +

If you wish to return a specific row from the result set you can pass a digit as the parameter.

+ +
+ $row = $query->row(4); +
+
+ +
+

row_array()

+ +

This method is identical to the above row() method except that it will return the row as an array.

+ +
+ $query = $this->db->query('SQL QUERY');
+
+ if ($query->num_rows() > 0)
+ {
+     $row = $query->row_array();
+
+     echo $row['title'];
+     echo $row['author'];
+     echo $row['post'];
+ } +
+ +

If you wish to return a specific row from the result set you can pass a digit as the parameter.

+ +
+ $row = $query->row_array(6); +
+ +

In addition to the above method you can also walk through the results forwards or backwards. You can use + the following methods.

+ +
+ $row = $query->first_row();
+ $row = $query->last_row();
+ $row = $query->next_row();
+ $row = $query->previous_row(); +
+ +

By default they return an object unless you pass the parameter 'array' like the following.

+ +
+ $row = $query->first_row('array');
+ $row = $query->last_row('array');
+ $row = $query->next_row('array');
+ $row = $query->previous_row('array') +
+
+ +
+

num_rows()

+ +

This method returns the amount of rows that are returned by a query.

+ +
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ echo $query->num_rows(); +
+
+ +
+

num_fields()

+ +

This method returns the number of fields returned by a query.

+ +
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ echo $query->num_fields(); +
+
+ +
+

free_result()

+ +

This method will free the memory associated with the result and deletes the results resource ID. Normally + PHP frees its memory automatically at the end of the execution of the script. However if you are running many + queries in a speicifc script you may wish to free a result after each query to cut down on the memory usage.

+ +
+ $query = $this->db->query('SELECT `title` FROM `some_table`');
+
+ foreach ($query->result() as $row)
+ {
+     echo $row->title;
+ }
+
+ $query->free_result(); +
+ $query2 = $this->db->query('SELECT `author` FROM `some_table`');
+
+ $row = $query2->row();
+ echo $row->author;
+
+ $query2->free_result(); +
+
+ + + diff --git a/Documentation/database/table_data.html b/Documentation/database/table_data.html new file mode 100644 index 0000000..28da889 --- /dev/null +++ b/Documentation/database/table_data.html @@ -0,0 +1,95 @@ + + + CarbonPHP Documentation + + + + +
+

Table Meta Data

+ +

This methods let you retrieve information about a specific table.

+
+ +
+

$this->db->list_tables()

+ +

This method returns an array containing the names of all the tables in the database you are connected ot.

+ +
+ $tables = $this->db->list_tables();
+
+ foreach ($tables as $table)
+ {
+     echo $table;
+ } +
+
+ +
+

$this->db->table_exists()

+ +

This method returns whether a table specified exists or not.

+ +
+ if ($this->db->table_exists('some_table'))
+ {
+     // Execute some code...
+ } +
+
+ + + diff --git a/Documentation/database/transactions.html b/Documentation/database/transactions.html new file mode 100644 index 0000000..0449df8 --- /dev/null +++ b/Documentation/database/transactions.html @@ -0,0 +1,176 @@ + + + CarbonPHP Documentation + + + + +
+

Database Transactions

+ +

CarbonPHP's database classes allow you to use transactions with databases that support transaction + safe table types. In MySQL, you will need to be running InnoDB or BDB table types instead of the common + MyISAM/. Most other database platforms support transactions natively.

+ +

If you do not have experience with database transactions we recommend you find a resource to learn about + them for your database platform. This page assume you have previous experience with transactions.

+
+ +
+

Transacations in CarbonPHP

+ +

CarbonPHP uses an approach similar to that of the ADODB class for transactions. This approach simplifies + the process of running transactions. In most cases all that is needed are two lines of code.

+ +

Usually transactions require a fair amount of code to implement since they demand that you keep track of + your queries and determine whether to commit or rollback based on success or failure of the query.

+
+ +
+

Running a Transaction

+ +

To run a query using a transaction you will need to use the trans_start() and + trans_complete() methods.

+ +
+ $this->db->trans_start();
+ $this->db->query('SOME QUERY');
+ $this->db->query('ANOTHER QUERY');
+ $this->db->trans_complete(); +
+ +

You are allowed to run any amount of queries between the start and complete methods. They will be committed + or rolled back depending on success or failure.

+
+ +
+

Managing Errors

+ +

If you have error reporting enabled in the application/config/config.php file you will see a + standard error message if your commit was unsuccessful. If debugging is enabled you can manage your own + errors.

+ +
+ $this->db->trans_start();
+ $this->db->query('SOME QUERY');
+ $this->db->query('ANOTHER QUERY');
+ $this->db->trans_complete();
+
+ if ($this->db->trans_status() === false)
+ {
+     // Generate an error message...
+ } +
+
+ +
+

Enabling Transactions

+ +

Transactions are enabled automatically the moment you call the trans_start() method. If you wish + to disabled transactions you can do so by calling the trans_off() method.

+ +
+ $this->db->trans_off();
+
+ $this->db->trans_start();
+ $this->db->query('SOME QUERY');
+ $this->db->query('ANOTHER QUERY');
+ $this->db->trans_complete(); +
+ +

When transcations are disabled your queries will be committed, just as they are when running queries + without transactions.

+
+ +
+

Test Mode

+ +

You can optionally put the transaction system into 'test mode' which will cause your queries to be rolled + back, even if the queries produce a successful result.

+ +
+ $this->db->trans_start(true);
+ $this->db->query('SOME QUERY');
+ $this->db->trans_complete();
+
+
+ +
+

Manually Running a Transaction

+ +

If you wish to manually run a transaction you can do so like the following example.

+ +
+ $this->db->trans_begin();
+
+ $this->db->query('SOME QUERY');
+ $this->db->query('ANOTHER QUERY');
+
+ if ($this->db->trans_status() === false)
+ {
+     $this->db->trans_rollback();
+ }
+ else
+ {
+     $this->db->trans_commit();
+ } +
+ +

You should remember to use trans_begin() when running manual transactions instead of + trans_start().

+
+ + + diff --git a/Documentation/database/utilities.html b/Documentation/database/utilities.html new file mode 100644 index 0000000..c7064f7 --- /dev/null +++ b/Documentation/database/utilities.html @@ -0,0 +1,274 @@ + + + CarbonPHP Documentation + + + + +
+

Database Utilities

+ +

The database utilities class contains methods that help you manage your databases.

+
+ +
+

Intialising the Class

+ +

In order for you to use this class your database class must already be loaded since this class relies on + it. You can load the class by doing the following.

+ +
+ $this->load->dbutil(); +
+ +

Once this class is initialised you can access it via the $this->dbutil object.

+ +
+ $this->dbutil->some_method(); +
+
+ +
+

$this->dbutil->create_database('db_name')

+ +

This allows you to create a database as specified in the first parameter. It will return true or false + based on its success or failure.

+ +
+ if ($this->dbutil->create_database('some_database'))
+ {
+     echo 'Database has been created.';
+ } +
+
+ +
+

$this->dbutil->drop_database('db_name')

+ +

This allows you to drop a database as specified in the first parameter. It will return true or false + based on its success or failure.

+ +
+ if ($this->dbutil->drop_database('some_database'))
+ {
+     echo 'Database has been dropped.';
+ } +
+
+ +
+

$this->dbutil->list_databases()

+ +

This method returns an array of database names.

+ +
+ $dbs = $this->dbutil->list_databases();
+
+ foreach ($dbs as $db)
+ {
+     echo $db;
+ } +
+
+ +
+

$this->dbutil->optimise_table('table_name')

+ +

This method allows you to optimise a table using the table named passed as a parameter. This method + returns true or false based on success or failure. Note: this method is only available for + MySQL and MySQLi databases.

+ +
+ if ($this->dbutil->optimise_table('table_name'))
+ {
+     echo 'Optimised that database.';
+ } +
+
+ +
+

$this->dbutil->repair_table('table_name')

+ +

This method allows you to repair a table using a table named passed as a parameter. This method returns + true or false based on success or failure. Note: this method is only available for MySQL and MySQLi + databases.

+ +
+ if ($this->dbutil->repair_table('table_name'))
+ {
+     echo 'Repaired the database.';
+ } +
+
+ +
+

$this->dbutil->optimise_database()

+ +

This method allows you to optimise a database that the database class is currently connected to. This + method returns an array containing the database status messages or false. Note: this method is only + available for MySQL and MySQLi databases.

+ +
+ $result = $this->dbutil->optimise_database();
+
+ if ($result !=== false)
+ {
+     print_r($result);
+ } +
+
+ +
+

$this->dbutil->csv_from_result($result)

+ +

This method allows you to create a CSV file from a query result. The first parameter is the result object + from the query.

+ +
+ $this->load->dbutil();
+
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ echo $this->dbutil->csv_from_result($query); +
+ +

The second and third parameters allow you to set the delimeter and newline characters. By default tabs + are used as the delimeter and '\n' as a newline.

+ +
+ $delimeter = ",";
+ $newlien = "\r\n";
+
+ echo $this->dbutil->csv_from_result($query, $delimeter, $newline); +
+ +

This method will not write the CSV file for you, only produce the contents of the file.

+
+ +
+

$this->dbutil->xml_from_result($result)

+ +

This method allows you to generate an XML file from a query result. The first parameter is a query result + object, the second may contain an optional array configuration.

+ +
+ $this->load->dbutil();
+
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ $config = array(
+     'root' => 'root',
+     'element' => 'element',
+     'newline' => "\n",
+     'tab' => "\t"
+ );
+
+ echo $this->dbutil->xml_from_result($query); +
+ +

This method will not create the XML file you for, only the contents of the XML file.

+
+ +
+

$this->dbutil->backup()

+ +

This method allows you to backup your full database or individual tables. The backup data can be + compressed in either zip or gzip format. This method is only available for MySQL and MySQLi databases.

+ +

Due to the limited execution time and memory available to PHP, backing up a very large database may not + be possible.

+ +
+ $this->load->dbutil();
+
+ $backup =& $this->dbutil->backup();
+
+ $this->load->utility('filesystem');
+ write_file('/path/to/backups/backup.gz', $backup);
+
+ +

Backup preferences are set by submitting an array of values to the first parameter of the backup method.

+ +
+ $pref = array(
+     'tables' => array('table1', 'table2'),
+     'ignore' => array(),
+     'format' => 'txt',
+     'filename' => 'backup.sql',
+     'add_drop' => true,
+     'add_insert' => true,
+     'newline' => "\n"
+ );
+
+ $this->dbutil->backup($pref); +
+
+ +
+

Backup Preferences

+ + +
+ + + diff --git a/Documentation/general/autoloading.html b/Documentation/general/autoloading.html new file mode 100644 index 0000000..bc4d2fe --- /dev/null +++ b/Documentation/general/autoloading.html @@ -0,0 +1,73 @@ + + + CarbonPHP Documentation + + + + +
+

Autoloading CarbonPHP Resources

+ +

CarbonPHP has a feature that allows you to autoload libraries, utilities, and other files everytime + it runs. If you find yourself loading resources a lot throughout your application you should consider + autoloading them. The following items can be autoloaded in CarbonPHP.

+ + + +

To autoload the items edit the application/config/autoload.php file and add the item you want + to autoload into the array. Note: you do not include the file extension when adding the item to the + autoload array.

+
+ + + diff --git a/Documentation/general/caching.html b/Documentation/general/caching.html new file mode 100644 index 0000000..2949339 --- /dev/null +++ b/Documentation/general/caching.html @@ -0,0 +1,102 @@ + + + CarbonPHP Documentation + + + + +
+

Caching CarbonPHP Pages

+ +

CarbonPHP allows you to cache certain pages in order to max out the performance of your application.

+ +

Even though CarbonPHP is fast, the amount of dynamic data you display will affect the server resources, + memory, and processing cycles. This will affect your loading speeds. By caching pages they are saved in + their fully rendered state, this will allow you to achieve the same performance as though you were loading + static pages.

+
+ +
+

How Does CarbonPHP Caching Work

+ +

Caching can be enabled on a per-page basis, and you can set the expiration time of the cache before the + cached page should be refreshed. When a page is loaded for the very first time a cache file will be written + to the carbon/cache/ directory. On page loads after this, the page will be served from the cache + directory and if it has expired, it will be deleted and refreshed before being sent to the browser.

+ +

Note: any benchmarking tags you use in your pages will not be cached, so you can still view + your page load speed when caching is enabled.

+
+ +
+

Enabling Caching For a Page

+ +

To enable caching just need to add the follow method into any of your controller methods.

+ +
+ $this->output->cache(minutes); +
+ +

Where minutes is the number of minutes you wish the cache file to last until it is refreshed.

+ +

The above method can be put anywhere within your controller methods. It is not affected by where it + appears in your methods. Note: before the cache files can be written, the correct permissions should + be set on the carbon/cache/ directory. The permissions 666 should suffice.

+
+ +
+

Deleting Cached Files

+ +

If you no longer wish to cache any files you can remove the caching method from your controller methods. + This will mean the page will no longer be cached. Removing the method will not delete the cache immediately. + It will expire normally if you leave it to, otherwise you can simply delete the file yourself if you wish + to remove it earlier.

+
+ + + diff --git a/Documentation/general/carbonphp_libraries.html b/Documentation/general/carbonphp_libraries.html new file mode 100644 index 0000000..97c3fe8 --- /dev/null +++ b/Documentation/general/carbonphp_libraries.html @@ -0,0 +1,72 @@ + + + CarbonPHP Documentation + + + + +
+

Using the CarbonPHP Libraries

+ +

The CarbonPHP libraries can be found in the carbon/libraries/ directory. To use most of the + libraries you just need to load the library in your controller.

+ +
+ $this->load->library('library_name'); +
+ +

Where library_name is the name of the library you wish to load. To load the pagination library you + would load it by doing the following.

+ +
+ $this->load->library('pagination'); +
+
+ + + diff --git a/Documentation/general/controllers.html b/Documentation/general/controllers.html new file mode 100644 index 0000000..1dc6efb --- /dev/null +++ b/Documentation/general/controllers.html @@ -0,0 +1,367 @@ + + + CarbonPHP Documentation + + + + +
+

Controllers

+ +

Controllers are one of the main parts of a model-view-controller framework. They determine how a HTTP + request should be handled.

+
+ +
+

What is a Controller?

+ +

A controller in CarbonPHP is just a PHP class that is named so that it can be associated with a URI.

+ +
+ www.your-domain.com/index.php/blog/ +
+ +

The above example shows the controller blog being called, CarbonPHP will attempt to find the + file blog.php and load it.

+ +

If a controller's name matches the first segment of the URI, the controller will be loaded by CarbonPHP. + If a controller cannot be found a 404 page is displayed.

+
+ +
+

Example Controller

+ +

An easy way to understand controllers is to start by creating your own.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function index()
+     {
+         echo 'Hello world!';
+     }
+ }
+
+ ?> +
+ +

You can then save this file in the application/controllers/ folder and visit the site using the URL + shown below.

+ +
+ www.your-domain.com/index.php/blog/ +
+ +

If you have done everything correctly, the page should be displaying Hello world!. Note: + class names must start with an uppercase letter.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+
+ }
+
+ ?> +
+ +

The above example is valid, however the example below is invalid.

+ +
+ <?php
+
+ class blog extends Controller
+ {
+
+ }
+
+ ?> +
+ +

You should also always make sure that your controllers extend the parent controller class. This is + so that it can inherit the parent's methods.

+
+ +
+

Methods

+ +

In the above example we created a method called index(). The index() method functions just + like an index.htm page. It is the default method that is called if no second segment in the URI is specified. + You can also call the index() method directly.

+ +
+ www.your-domain.com/index.php/blog/index/ +
+ +

As explained previously the second segment of the URI determines which of the controllers methods is called. + We can try this by adding a second method to our example controller.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function index()
+     {
+         echo 'Hello world!';
+     }
+
+     public function post()
+     {
+         echo 'More content!';
+     }
+ }
+
+ ?> +
+ +

If you now load the follow URL, you can see the output of the new function we added.

+ +
+ www.your-domain.com/index.php/blog/post/ +
+ +

If everything has worked correctly you should see the new message.

+
+ +
+

Passing URI Segments to Methods

+ +

If the URI contains more than two segments they can be passed to your methods as function parameters.

+ +
+ www.your-domain.com/index.php/shop/tshirts/short/1 +
+ +

The controller method will be passed the 3rd and 4th URI segments ('short' and '1').

+ +
+ <?php
+
+ class Shop extends Controller
+ {
+     public function tshirts($type, $id)
+     {
+         echo $type;
+         echo $id;
+     }
+ }
+
+ ?> +
+ +

Note: if you are using the URI routing feature, any segments that are passed to your methods will + be the re-routed segments.

+
+ +
+

Using a Default Controller

+ +

CarbonPHP can be told to load a default controller is no controller is specified in the URI. You can + specify the default controller in the configuration file config/routes.php.

+ +
+ $routes['default_controller'] = 'Blog'; +
+ +

This sets the default controller to the one called Blog. If you load the main index.php + without any URI segments you should see the 'Hello world' message.

+
+ +
+

Remapping Method Calls

+ +

As explained above the second segment of the URI determines which method in the controller is called. + CarbonPHP allows you to override this through the use of a method called _remap().

+ +
+ public function _remap()
+ {
+     // Code goes here...
+ }
+
+ +

Note: if you have a controller that contains a method called _remap(), it will always be + called regardless of what your URI contains. It overrides the normal behavior in which the URI determines + which method is called, this allows you to define your own routing rules for methods.

+ +

Typically the second segment of the URI will be passed as a parameter to the _remap() function.

+ +
+ public function _remap($method)
+ {
+     if ($method == 'some_method')
+     {
+         $this->$method();
+     }
+     else
+     {
+         $this->other_method();
+     }
+ }
+
+
+ +
+

Processing the Output

+ +

CarbonPHP has a library class that takes care of sending the final rendered output to the web browser. + However you may wish to post-process the finalised output in some way, and then send it to the web browser + yourself. CarbonPHP allows you to do this by adding a method called _output().

+ +

Note: if your controller contains a method called _output(), it will always be called by + the output class instead of displaying the final data. THe first parameter of the method will contain the + final output to be sent to the web browser.

+ +
+ public function _output($output)
+ {
+     echo $output;
+ }
+
+ +

Note: the _output() method will receive data in its final state. Benchmark and memory usage + data will be rendered, cache files will be written if caching is enabled, and headers will be sent if using + that feature. If you are using the _output() method any execution timers and memory usage stats being + used will not be accurate because they do not take into account the extra processing.

+
+ +
+

Private Methods

+ +

In some of your controllers you may wish to have methods that are not accessible by the public. To make + a method private you can simple add an underscore to its name and declare it as private. Note: you + cannot simply declare the method as private as this will generate a PHP error. You must add an underscore.

+ +
+ private function _priv_func()
+ {
+     echo 'Private function!';
+ }
+
+ +

If you tried to access this method via the URL, it would display a 404 page.

+ +
+ www.your-domain.com/index.php/blog/_priv_func/ +
+
+ +
+

Organising Controllers

+ +

When creating large web applications you may find it useful to organise controllers into subdirectories. + You can accomplish this by creating subdirectories in the application/controllers/ directory and + place the controller classes within those subdirectories. Note: when you use this feature the first + segment of the URI must specify the directory.

+ +
+ application/controllers/products/tshirts.php +
+ +

Now when you want to call the above controller you can do the following.

+ +
+ www.your-domain.com/index.php/products/tshirts/short/ +
+ +

Each subdirectory can have its own default controller which is called when the URI only contains the name + of the subdirectory. Simple name the default controller as specified in the config/routes.php + configuration file. CarbonPHP also allows you to remap your URIs using the URI routing feature.

+
+ +
+

Class Constructors

+ +

If you wish to use a constructor in any of your controllers, you must call the parent controllers + constructor.

+ +
+ parent::__construct() +
+ +

The reason for this is because the controller constructor will override the parent's constructor. This + means that we will have to call it manually.

+ +
+ <?php
+
+ class Shop extends Controller
+ {
+     public function __construct()
+     {
+         parent::__construct()
+     }
+ }
+
+ ?> +
+ +

Constructors are useful if you need to set any default values, or run a process during the instantiation + of the class. Constructors can never return a value, they can however do some of the default work.

+
+ +
+

Reserved Method Names

+ +

Since the controller classes are derived from the main controller class you must not name your methods + identically to ones used by that class. Otherwise you will be overriding those methods.

+ + +
+ + + diff --git a/Documentation/general/core_libraries.html b/Documentation/general/core_libraries.html new file mode 100644 index 0000000..e84f6b4 --- /dev/null +++ b/Documentation/general/core_libraries.html @@ -0,0 +1,173 @@ + + + CarbonPHP Documentation + + + + +
+

Creating Core CarbonPHP Libraries

+ +

When CarbonPHP runs it initialises several libraries as part of the core. It is posssible to replace or + extend any of the core libraries with your own libraries.

+ +

Note: Many users will not need to extend or replace these core libraries. Although some users may + wish to change the CarbonPHP core.

+
+ +
+

CarbonPHP Core Libraries

+ +

This is a list of the core libraries CarbonPHP will load when it runs.

+ + +
+ +
+

Replacing Core Libraries

+ +

To replace one of the core libraries simple create your library in the application/libraries/ + directory.

+ +
+ application/libraries/some_core_library.php +
+ +

Any library named identically to one of the above core libraries will be loaded instead of the CarbonPHP + library. Note: your class name must also use the Carbon_ prefix.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Carbon_Output
+ {
+
+ }
+
+ ?> +
+
+ +
+

Extending Core Libraries

+ +

If you only need to add a little functionality to a core library you can extend the library using a + subclass.

+ + + +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Sub_Output extends Carbon_Output
+ {
+
+ }
+
+ ?> +
+ +

If you want to use a constructor in your subclass you need to remember to call the parent classes + constructor.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Sub_Output extends Carbon_Output
+ {
+     public function __construct()
+     {
+         parent::__construct();
+     }
+ }
+
+ ?> +
+ +

Note: any methods you create that are named identically to methods in the parent class will + override the parent methods.

+ +

You can set your own subclass prefix in the configuration file application/config/config.php and + edit the subclass_prefix value.

+ +
+ $config['subclass_prefix'] = 'Sub_'; +
+
+ + + diff --git a/Documentation/general/creating_libraries.html b/Documentation/general/creating_libraries.html new file mode 100644 index 0000000..c78aa9b --- /dev/null +++ b/Documentation/general/creating_libraries.html @@ -0,0 +1,311 @@ + + + CarbonPHP Documentation + + + + +
+

Creating Your Own Libraries

+ +

Libraries in CarbonPHP are simply PHP classes stored in the carbon/libraries/ directory. We will + tell you how to create your own CarbonPHP libraries within the application/libraries/ directory. + This allows you to keep your libraries and the CarbonPHP libraries separate.

+ +

CarbonPHP also allows you to extend the CarbonPHP libraries with your own libraries allowing you to add + functionality to the existing libraries. You can even replace existing libraries with your own.

+ +

Note: you cannot replace or extend the CarbonPHP database classes. Every other library can be + replaced or extended.

+
+ +
+

Storing Your Libraries

+ +

As desribed above you should place your own libraries in the application/libraries/ directory. + This is the first directory that CarbonPHP looks in for loading libraries.

+
+ +
+

Naming Your Libraries

+ +

File names for your libraries should be capitalised, like Mylibrary.php. Class declarations must + be capitalised just like file names, class Myclass. Class names and file names must match.

+
+ +
+

Class File Skeleton

+ +

Classes for libraries should have the basic skeleton, the name Some_library is an example.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Some_library
+ {
+     public function some_function()
+     {
+     }
+ }
+
+ ?> +
+
+ +
+

Using Your Libraries

+ +

As with any other library, you can load your library the same way within your controllers.

+ +
+ $this->load->library('some_library'); +
+ +

Where some_library is the name of your library. You can use the capitalised and lower case name, + CarbonPHP can use either. Once you have loaded your library you can use it by accessing it the same way + as any other library.

+ +
+ $this->some_library->some_function(); +
+
+ +
+

Passing Parameters When Initialising Your Library

+ +

When you load a library you can pass data via the second parameter and it will be passed to the constructor + of the library class.

+ +
+ $params = array('Color' => 'Red', 'Size' => 'Small');
+
+ $this->load->library('Some_library, $params); +
+ +

When you do this, you will have to create your constructor so that the constructor expects data to be + passed to it.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Some_library
+ {
+     public function __construct($params)
+     {
+     // Use the $params variable
+     }
+ }
+
+ ?> +
+ +

Note: you are able to pass parameters stored in a configuration file. You can simply create the + configuration file stored in application/config/ directory. The configuration file must be identically + to the library. If you pass data as described above, this option is not available to you.

+
+ +
+

Using CarbonPHP Resources in Your Library

+ +

You can access the resources in CarbonPHP by calling the get_instance() function. This function + returns the CarbonPHP object. Usually within your controller methods you can access the $this + variable.

+ +
+ $this->load->utility('form');
+ $this->load->library('pagination');
+ $this->config->get_item_value('base_url'); +
+ +

The $this variable is only available within your controllers, models, and views. If you would like + to access CarbonPHP's libraries and classes within your own library you must do the following.

+ +
+ $carbon =& get_instance(); +
+ +

Once the object has been assigned to a variable, you can use that variable instead of the $this + variable.

+ +
+ $carbon =& get_instance();
+
+ $carbon->load->utility('form');
+ $carbon->load->library('pagination');
+ $carbon->config->get_item_value('base_url'); +
+ +

Note: please note that when get_instance() is being passed by reference. This is important + because assigning by reference means you use the original CarbonPHP object instead of creating a copy of it.

+
+ +
+

Replacing CarbonPHP Libraries

+ +

To simply replace the CarbonPHP libraries you just need to name your library the exact same. This will make + CarbonPHP use that library instead of the CarbonPHP one. For example if you were going to replace the + pagination library, you will create the file application/libraries/Pagination.php and declare the class + as the following.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Carbon_Pagination
+ {
+
+ }
+
+ ?> +
+ +

Note: CarbonPHP classes are prefixed with Carbon_ and classes you intend to replace them with + must follow this as well.

+ +

To load your library you use the same standard method of loading libraries.

+ +
+ $this->load->library('pagination'); +
+ +

Note: as previously stated, database classes cannot be replaced.

+
+ +
+

Extending CarbonPHP Libraries

+ +

If you only want to add a little functionality to an existing CarbonPHP library, then maybe adding one + or two methods, then it's overkill to fully replace the CarbonPHP library. It is better in this case to + extend the existing library. To extend a library it is nearly exactly the same as replacing a library, minus + some differences.

+ + + +

The subclass prefix is configurable in the configuration file. For example if we were going to extend the + pagination library, we would create the file application/libraries/Sub_Pagination.php and declare the + class as below.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Sub_Pagination extends Carbon_Pagination
+ {
+
+ }
+
+ ?> +
+ +

Note: if you decide to use a constructor in your subclass you must remember to call the parent + classes constructor.

+ +
+ <?php
+
+ if (!defined('CARBON_PATH'))
+ {
+     exit('Direct script access is not allowed.');
+ }
+
+ class Sub_Pagination extends Carbon_Pagination
+ {
+     public function __construct()
+     {
+         parent::__construct();
+     }
+ }
+
+ ?> +
+ +

To load your subclass you use the standard method of loading libraries. Although you do not include + the prefix in the name when loading.

+ +
+ $this->load->library('pagination'); +
+ +

Once the library is loaded you can access it as you would normally. The extended methods will be available + to you for calling.

+ +
+ $this->pagination->new_function(); +
+ +

You can set your own subclass prefix in the configuration file application/config/config.php and + edit the subclass_prefix value.

+ +
+ $config['subclass_prefix'] = 'Sub_'; +
+
+ + + diff --git a/Documentation/general/error_handling.html b/Documentation/general/error_handling.html new file mode 100644 index 0000000..2566644 --- /dev/null +++ b/Documentation/general/error_handling.html @@ -0,0 +1,116 @@ + + + CarbonPHP Documentation + + + + +
+

Error Handling in CarbonPHP

+ +

CarbonPHP has built in functions for error reporting that you can use in your application. CarbonPHP + also has an error logging class that allows you to log debugging and error messages to a log file.

+ +

Note: by default CarbonPHP will display all PHP errors. You may wish to change this behaviour + once you make your application live. You can change this by changing the parameter of the + error_reporting() function in the index.php. Disabling PHPs error reporting will not stop + log files being written by CarbonPHP.

+ +

Unlike the other libraries in CarbonPHP, the error functions are just simple procedural interfaces. They + are globally available throughout CarbonPHP. This allows error messages to be triggered without worrying + about the scope of the class and methods.

+
+ +
+

display_error('message');

+ +

This function will display a generic error using the message passed as a parameter using the template + application/errors/error.php file.

+
+ +
+

display_not_found('page');

+ +

This function will display a 404 page not found error message using the template file specified or it will + display the template application/errors/error_404.php file.

+
+ +
+

log_message('level', 'message');

+ +

This function lets you write an error message to a log file. You must supply one of three error levels in + the first parameter. The error message will be the second parameter.

+ +
+ if ($some_var != true)
+ {
+     log_message('error', 'Some variable is not equal to true.');
+ }
+ else
+ {
+     log_message('debug', 'Some variable is equal to true.');
+ }
+
+ log_message('info', 'Some variable is used to provide a value.'); +
+ +

There are three types of error message.

+ + + +

Note: in order for CarbonPHP to log to files, the logs folder must be writable, and you + must set a threshold for logging in the configuration file. For example if you wish to only log error + messages, and not the other two error types. If you set the threshold to zero, logging will be disabled.

+
+ + + diff --git a/Documentation/general/extensions.html b/Documentation/general/extensions.html new file mode 100644 index 0000000..14437b3 --- /dev/null +++ b/Documentation/general/extensions.html @@ -0,0 +1,153 @@ + + + CarbonPHP Documentation + + + + +
+

Extending the Framework Core With Extensions

+ +

CarbonPHP has the feature to allow users to extend the framework core without hacking the core classes. + When CarbonPHP runs it follows a specific flow. There are some times when you might want an action to occur + at a stage during the execution. If you want to run a method right before the controller gets loaded you + can declare an extension to do this.

+
+ +
+

Enabling Extensions

+ +

The extensions feature can be enabled or disabled by changing the item in the + application/config/config.php configuration file.

+ +
+ $config['enable_extensions'] = true; +
+
+ +
+

Declaring an Extension

+ +

Extensions are declared in the application/config/extensions.php configuration file. Each extension + follows the following prototype.

+ +
+ $extension['pre_controller'] = array(
+     'class' => 'Ext_class',
+     'method' => 'ExtMethod',
+     'filename' => 'Ext_class.php',
+     'filepath' => 'extensions',
+     'params' => array('small', 'medium', 'large')
+ );
+
+ +

Note: the array index correlates to the name of the extension you wish to use. In the above example + the extension point is pre_controller. The list of available extension points are outlined below.

+ + +
+ +
+

Calling an Extension Multiple Times

+ +

If you wish to use the same extension point with more than once, you simply just create a multi-dimensional + array.

+ +
+ $extension['pre_controller'][] = array(
+     'class' => 'Ext_class',
+     'method' => 'ExtMethod',
+     'filename' => 'Ext_class.php',
+     'filepath' => 'extensions',
+     'params' => array('small', 'medium', 'large')
+ );
+
+ $extension['pre_controller'][] = array(
+     'class' => 'Ext_otherclass',
+     'method' => 'ExtOtherMethod',
+     'filename' => 'Ext_otherclass.php',
+     'filepath' => 'extensions',
+     'params' => array('blue', 'red', 'green')
+ );
+
+ +

Note: the order in which you declare the array is the order in which they will get executed.

+
+ +
+

Extension Points

+ +

The following is a list of extension points that you can use.

+ + +
+ + + diff --git a/Documentation/general/models.html b/Documentation/general/models.html new file mode 100644 index 0000000..2bbde9d --- /dev/null +++ b/Documentation/general/models.html @@ -0,0 +1,244 @@ + + + CarbonPHP Documentation + + + + +
+

Models

+ +

You are not required to use models in your web application. They can be used for those people who wish + to use a more traditional model-view-controller approach.

+
+ +
+

What is a Model?

+ +

Models are classes that are designed to handle information in your databases. An example is if you + create a blog application using CarbonPHP. You may have a model class that has methods to insert, update, + and retrieve blog data.

+ +

An example of this model may look like the following.

+ +
+ <?php
+
+ class Blogmodel extends Model
+ {
+     public $title = '';
+     public $content = '';
+     public $data = '';
+
+     public function __construct()
+     {
+         parent::__construct();
+     }
+
+     public function get_last_ten_entries()
+     {
+         $query = $this->db->get('entries', 10);
+         return $query->result();
+     }
+
+     public function insert()
+     {
+         $this->title = $_POST['title'];
+         $this->content = $_POST['content'];
+         $this->date = time();
+
+         $this->db->insert('entries', $this);
+     }
+
+     public function update()
+     {
+         $this->title = $_POST['title'];
+         $this->content = $_POST['content'];
+         $this->date = time();
+
+         $this->db->update('entries', $this, array('id', $_POST['id']));
+     }
+ }
+
+ ?> +
+ +

Note: the above example is using methods from the Active Record data class.

+
+ +
+

The Anatomy of a Model

+ +

Models are stored the in application/models/ directory. They can be stored in subdirectories for + people who wish to use that type of organisation.

+ +
+ <?php
+
+ class Model_name extends Model
+ {
+     public function __construct()
+     {
+         parent::__construct();
+     }
+ }
+
+ ?> +
+ +

Model_name is the name of your class. Class names must be capitalised. You must also make sure + that the model class extends the base Model class. The file name will be a lower case version of + the class name.

+ +
+ <?php
+
+ class User_model extends Model
+ {
+     public function __construct()
+     {
+         parent::__construct();
+     }
+ }
+
+ ?> +
+ +

The model file name will be the following.

+ +
+ application/models/user_model.php +
+
+ +
+

Loading a Model

+ +

Usually your models will be loaded and used from within your controllers methods.

+ +
+ $this->load->model('Model_name'); +
+ +

If you have organised your models in subdirectories you will need to include the directory in the + method call.

+ +
+ $this->load->model('Directory_name/Model_name'); +
+ +

Once your model has been loaded you will access the models methods using an object with the same + name as the model class you loaded.

+ +
+ $this->load->mode('Model_name');
+ $this->Model_name->method(); +
+ +

You can specify a different name for the model object in the second parameter of the loading method.

+ +
+ $this->load->model('Model_name', 'foo');
+ $this->foo->method(); +
+ +

An example of a controller that loads and uses a model, then loads a view is shown below.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function recent()
+     {
+         $this->load->model('Blog');
+         $data['query'] = $this->blog->get_last_ten_entries();
+         $this->load->view('blog_view', $data);
+     }
+ }
+
+ ?> +
+
+ +
+

Using a Database in Models

+ +

Unless you autoload the database library (this is explained later) you model will not automaticall connect + to your database. There are three methods you can use for connecting to the database in your models.

+ + +
+ + + diff --git a/Documentation/general/scaffolding.html b/Documentation/general/scaffolding.html new file mode 100644 index 0000000..03af484 --- /dev/null +++ b/Documentation/general/scaffolding.html @@ -0,0 +1,133 @@ + + + CarbonPHP Documentation + + + + +
+

Scaffolding

+ +

CarbonPHP has a scaffolding feature that provides an easy and fast way to add, edit, or delete data + from your database during the development of your application.

+ +

You should also take note that scaffolding is only intended for use while you are developing your + application. It provides zero security except for a secret word. Anyone who has access to this + secret word has access to your database. You should disabled scaffolding when you make your application live + and make sure you set a secret word when you do use it.

+
+ +
+

Uses For Scaffolding

+ +

A typical scenario is that you are creating a new database during development and you would like to + have a quick way to insert data into the database to test with. Without the use of scaffolding you + would either have to manually insert data via the command line or a tool like phpMyAdmin. Using + CarbonPHP's scaffolding feature you can quickly insert some data using the web interface.

+
+ +
+

Setting a Scaffolding Secret Word

+ +

Before you enable scaffolding you should take the time to set a secret word. This word will launch + scaffolding when it is used in the URL. You should use something that is not easily guessed.

+ +

The secret word is set in the application/config/routes.php configuration file.

+ +
+ $routing['scaffolding_trigger'] = ''; +
+ +

Note: the scaffolding secret word should not start with an underscore.

+
+ +
+

Enabling Scaffolding

+ +

This page assumes you already understand how controllers function. You should have also configured + CarbonPHP to automatically connect to a database.

+ +

To enable scaffolding you load scaffolding in the controllers constructor.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function __construct()
+     {
+         parent::__construct();
+
+         $this->load->scaffolding('table_name');
+     }
+ }
+
+ ?> +
+ +

Where table_name is the name of the table you wish to work with. Once you've initialised + scaffolding you can access it with the following URL.

+ +
+ www.your-domain.com/index.php/class/secret_word/ +
+ +

For example if your controller class was Blog and your secret word was magicword, you would + use the following URL.

+ +
+ www.your-domain.com/index.php/blog/magicword/ +
+ +

The scaffolding web interface is intuitive and should be easy to understand and navigate. Note: + scaffolding will only work with tables that have a primary key. This is because this information is required + to perform the database tasks.

+
+ + + diff --git a/Documentation/general/security.html b/Documentation/general/security.html new file mode 100644 index 0000000..adede8b --- /dev/null +++ b/Documentation/general/security.html @@ -0,0 +1,127 @@ + + + CarbonPHP Documentation + + + + +
+

CarbonPHP Security

+ +

This page outlines some of the best practices for web-application security, and how CarbonPHP incorporates + some of these security features.

+
+ +
+

URI Security

+ +

CarbonPHP restricts which characters that can be placed in the URI in order to minimise the possibility + of malicious data being passed to the web-application.

+ +

URIs can only contain the following non-alpha numeric characters.

+ + +
+ +
+

GET, POST, and COOKIE Arrays

+ +

GET data is disallowed by CarbonPHP since CarbonPHP utilises URI segments. The $_GET array is simply + unset() by the Input class during the initialisation of CarbonPHP. The $_POST and + $_COOKIE arrays are sanitised by the Input class.

+
+ +
+

Register Globals

+ +

During the initialisation of CarbonPHP all global variables except $_POST and $_COOKIE are + unset(). The unsetting of these arrays is the same as turning register_globals off.

+
+ +
+

Magic Quotes

+ +

The magic quotes directive is disabled during the initialisation of CarbonPHP so you don't have to remove + slashes when retrieving data from your database.

+
+ +
+

Best Security Practices

+ +

Before accepting any data into your web-application, this means any data. You are encouraged to + to practice the following three step approach.

+ +
    +
  1. Filter all the data as if it were malicious.
  2. +
  3. Validate the data to ensure it meets to the correct type, length, etc.
  4. +
  5. Escape the data before submitting it into your database to stop SQL injection.
  6. +
+
+ +
+

Cross Site Scripting Filtering

+ +

CarbonPHP features a cross site scripting filter. This filter looks for common techniques used to embed + malicious javascript into your data, or other types of code.

+
+ +
+

SQL Injection Filtering

+ +

You should never insert data into your database without escaping it. carbonPHPs database class automatically + escapes data that is being inserted into the database.

+
+ + + diff --git a/Documentation/general/uri_routing.html b/Documentation/general/uri_routing.html new file mode 100644 index 0000000..e25ff73 --- /dev/null +++ b/Documentation/general/uri_routing.html @@ -0,0 +1,175 @@ + + + CarbonPHP Documentation + + + + +
+

URI Routing

+ +

Usually there is a one to one relationship betweenn the URL segments and controllers/methods. The segments + in a URI normally follow the pattern below.

+ +
+ www.your-domain.com/class/method/id/ +
+ +

However you may wish to remap this relationship so a different controller/method is called instead of the + one specified in the URL. For example if you want your URLs to have the following prototype.

+ +
+ www.your-domain.com/post/1/
+ www.your-domain.com/post/2/
+ www.your-domain.com/post/3/
+ www.your-domain.com/post/4/ +
+ +

Usually the second URI segment is reserved for the method name, but in the above the second URI segment + is the post ID. CarbonPHP allows you to remap the URI handler.

+
+ +
+

Setting Your Own Routes

+ +

Routing rules are declared in the application/config/routing.php configuration file. Inside this + configuration file you will see an array called $routing which permits you to specify you own rules + for routing. These rules can be specified using wildcards or regular expressions.

+
+ +
+

Wildcard Routing Rules

+ +

Usually a wildcard rule would look something like the following.

+ +
+ $routing['post/:num'] = 'blog/post'; +
+ +

In a routing rule, the array key contains the URI to be matched, while the array value contains the + destination it should be remapped to. In the above example, if the word post is found in the first + segment of the URI, and a number is found in the second segment, the controller blog and method + post are used instead.

+ +

There are can match literal values or use two wildcard types.

+ + + +

Some examples of routing are shown below.

+ +
+ $routing['journals'] = 'blogs'; +
+ +

In the above example any URL containing the word journals in the first segment, it will be remapped + to the blogs controller.

+ +
+ $routing['blog/john'] = 'blogs/user/1'; +
+ +

In the above example any URL containing the word blog and john in the URL segements it will + be remapped to the blogs controller, the users methods, and with the third segment being the + ID.

+ +
+ $routing['product/:any'] = 'catalog/products'; +
+ +

Any URL with product in the first segment, and anything is in the second segment, it will be + remapped to the catalog controller and the products method.

+ +

Note: remember to not use leading and trailing slashes.

+
+ +
+

Regular Expression Routing Rules

+ +

If you prefer you can use regular expressions in the routing rules you define. Any regular expression that + is valid is allowed. Note: if you use back-references you have to use the dollar syntax, instead + of the double backslash syntax.

+ +

A typical regular expression syntax might look like the following.

+ +
+ $routing['products/([a-z]+)/(\d+)'] = '$1/id_$2'; +
+ +

In the above example, any URI similar to products/shirts/12/ would instead call the shirts, + and the id_12 method. You can also mix and match wildcards with regular expressions.

+
+ +
+

Reserved Routes

+ +

There are two reserved routes in CarbonPHP. These are the default_controller and + scaffolding_trigger routes.

+ +
+ $routing['default_controller'] = 'welcome'; +
+ +

The above route specifies which controller class that CarbonPHP should load if no first segment is + specified in the URI. You should always declare a default controller, otherwise people will encounter + a 404 page by default.

+ +
+ $routing['scaffolding_trigger'] = 'secret_word'; +
+ +

This route lets you choose a secret word that when specified in the URL will trigger the CarbonPHP + scaffolding.

+ +

Note: the reserved routes must always appear before any custom routing rules.

+
+ + + diff --git a/Documentation/general/urls.html b/Documentation/general/urls.html new file mode 100644 index 0000000..7c746ea --- /dev/null +++ b/Documentation/general/urls.html @@ -0,0 +1,154 @@ + + + CarbonPHP Documentation + + + + +
+

CarbonPHP URLs

+ +

The URLs in CarbonPHP are similar to URLs that can be created using Apache's mod_rewrite. + CarbonPHP doesn't use the standard 'query string' URLs, CarbonPHP uses a segment-based method. Note: + you can still enable query string style URLs. This is shown below.

+ +
+ www.your-domain.com/index.php/shop/product/123 +
+
+ +
+

URI Segments

+ +

The URL segments in CarbonPHP follow the approach commonly found in model-view-controller frameworks.

+ +
+ www.your-domain.com/index.php/class/method/id +
+ +
    +
  1. The first segment is the controller class that is being invoked.
  2. +
  3. The second segment is the method of the class invoked.
  4. +
  5. The third, and additional segments are any additional parameters you wish to pass.
  6. +
+ +

The URI class library and URL utility contain functions and methods that make working with CarbonPHP URLs + easier.

+
+ +
+

Removing the index.php From the URL

+ +

CarbonPHP will by default include the index.php in the URL.

+ +
+ www.your-domain.com/index.php/blog/post/1 +
+ +

This can be removed easily using Apache's mod_rewrite. Below is a simple example using a + .htaccess file.

+ +
+ RewriteEngine on
+ RewriteCond $1 !^(index\.php|images|robots\.txt)
+ RewriteRule ^(*.)$ /index.php/$1 [L] +
+ +

The above example takes any HTTP request other than those for index.php, images, and robots.txt as a + request for the index.php file.

+
+ +
+

Adding a Suffix to the URL

+ +

In the configuration file config/config.php you can tell CarbonPHP a suffix that it will add to any + generated URLs.

+ +
+ www.your-domain.com/index.php/blog/post/1 +
+ +

Using the example suffix .html, you can make the page appear to be of a certain document type.

+ +
+ www.your-domain.com/index.php/blog/post/1.html +
+
+ +
+

Enabling Query Strings

+ +

If you prefer using query strings, CarbonPHP gives you the option of enabling them.

+ +
+ www.your-domain.com/index.php?c=blog&m=post&id=1 +
+ +

This capability can be enabled by turning it on in the config/config.php. In the configuration + file you will see the items below.

+ +
+ $config['use_query_strings'] = false;
+ $config['controller_trigger'] = 'c';
+ $config['method_trigger'] = 'm'; +
+ +

Changing the 'use_query_strings' to true will enable query string URLs. Your controllers and + methods are now accessible using the triggers specified in the configuration file.

+ +
+ www.your-domain.com/index.php?c=controller&m=method +
+ +

Note: If you're using query strings in your URLs you will not be able to use the URL utilities, and + you will have to build your own URLs. This is because they are designed to be used with the segment-based + URLs CarbonPHP natively uses.

+
+ + + diff --git a/Documentation/general/views.html b/Documentation/general/views.html new file mode 100644 index 0000000..4f9c788 --- /dev/null +++ b/Documentation/general/views.html @@ -0,0 +1,235 @@ + + + CarbonPHP Documentation + + + + +
+

Views

+ +

A view is another main part of model-view-controller frameworks. A view is simply a web page, or page + fragment, for example a header, footer, or sidebar. Views must always be loaded by a controller.

+ +

Using the example controller we previously created we will load a view to display the main page.

+
+ +
+

Creating a View

+ +

Using your favorite text-editor, create a file called blog_view.php, and write the following.

+ +
+ <html>
+ <head>
+     <title>My Blog</title>
+ </head>
+ <body>
+     <h1>Welcome to My Blog</h1>
+ </body>
+ </html> +
+ +

You can then save this file in the application/views/ directory.

+
+ +
+

Loading a View

+ +

To load a view you will call the following method.

+ +
+ $this->load->view('name'); +
+ +

Where name is the name of the view file you created. The file extension .php does not + need to be specified unless you use something other than .php. Now we can load the view file within + the controller we created previously.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function index()
+     {
+         $this->load->view('blog_view');
+     }
+ }
+
+ ?> +
+ +

Now if you visit the site using the URL like we did earlier you should now see the new view loaded.

+ +
+ www.your-domain.com/index.php/blog/ +
+
+ +
+

Organising Views

+ +

View files can also be organised into subdirectories. When you use this method you will have to include + the name of the folder when loading the view.

+ +
+ $this->load->view('directory_name/file_name'); +
+
+ +
+

Passing Dynamic Data to a View

+ +

Data can be passed from a controller to a view by passing an array or object in the + second parameter of the view loading method.

+ +
+ $data = array(
+     'title' => 'Blog Title',
+     'heading' => 'Post Heading',
+     'message' => 'Post Message'
+ );
+
+ $this->load->view('blog_view', $data); +
+ +

Below is an example of passing an object to a view. Note: if you use an object, the class members + will be turned into array elements.

+ +
+ $object = new ClassObject();
+ $this->load->view('blog_view', $object); +
+ +

Now we can modify the controller we created earlier to pass an array of data to our view.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function index()
+     {
+         $data['title'] = 'My Blog Title';
+         $data['heading'] = 'My Blog Heading';
+
+         $this->load->view('blog_view', $data);
+     }
+ }
+
+ ?> +
+ +

Once you have done this we can edit the blog_view.php file to include the variables we have + created.

+ +
+ <html>
+ <head>
+     <title><?php echo $title; ?></title>
+ </head>
+ <body>
+     <h1><?php echo $heading; ?></h1>
+ </body>
+ </html> +
+ +

Now if you load this page at the URL, you will see that the variables are replaced with the data that + we passed to the view.

+
+ +
+

Creating Loops in Views

+ +

Data passed to views is not limited to single variables. You can pass multi-dimensional arrays, which + can be looped to generate multiple rows. When you retrieve data from your database it will typically be + in the form of a multi-dimensional array.

+ +
+ <?php
+
+ class Blog extends Controller
+ {
+     public function index()
+     {
+         $data['title'] = 'My Blog Title';
+         $data['heading'] = 'My Blog Heading';
+         $data['todo'] = array('Shop', 'Clean', 'Tidy up');
+
+         $this->load->view('blog_view', $data);
+     }
+ }
+
+ ?> +
+ +

Now you can edit the file blog_view.php again to include a loop to iterate through the data + passed to the view.

+ +
+ <html>
+ <head>
+     <title><?=$title;?></title>
+ </head>
+ <body>
+     <h1><?=$heading;?></h1>
+
+     <h3>Todo List</h3>
+
+     <ul>
+     <?php foreach($todo as $item): ?s>
+         <li><?=$item;?></li>
+     <?php endforeach; ?s>
+ </body>
+ </html> +
+
+ + + diff --git a/Documentation/index.html b/Documentation/index.html new file mode 100644 index 0000000..1341e61 --- /dev/null +++ b/Documentation/index.html @@ -0,0 +1,161 @@ + + + CarbonPHP Documentation + + + + +
+

CarbonPHP Documentation

+ +

These files document the many features of CarbonPHP.

+
+ +
+

General

+ +

These pages outline the general information regarding CarbonPHP.

+ +
+ +
+

Libraries

+ +

These pages outline the information regarding the many CarbonPHP libraries.

+ + +
+ +
+

Database Library

+ +

These pages outline the information needed to use the database classes.

+ + +
+ +
+

Utilities

+ +

These are utilities that provide simple procedural functions for you to use.

+ + +
+ + + diff --git a/Documentation/libraries/benchmark.html b/Documentation/libraries/benchmark.html new file mode 100644 index 0000000..c9ef4af --- /dev/null +++ b/Documentation/libraries/benchmark.html @@ -0,0 +1,172 @@ + + + CarbonPHP Documentation + + + + +
+

Benchmark Library

+ +

CarbonPHP has a benchmark library that is always active, this library enables you to make the time + between two points. Note: the benchmark library is automatically loaded by CarbonPHP so there is no + need for you to load it.

+ +

The benchmark library is always started the moment the framework is invoked, and ended once the output + class is ready to send the final data to the browser. This means a very accurate value for the time the + system took to execute.

+
+ +
+

Using the Benchmark Library

+ +

The benchmark library can be used within, models, views, or controllers. The process of using the library + is as follows.

+ +
    +
  1. Mark the start point.
  2. +
  3. Mark the end point.
  4. +
  5. Run the elapsed_time() function to view the result.
  6. +
+ +

A simple example of using the benchmark library is shown below.

+ +
+ $this->benchmark->mark('code_start');
+
+ // Some code executes here...
+
+ $this->benchmark->mark('code_end');
+
+ echo $this->benchmark->elapsed_time('code_start', 'code_end'); +
+ +

Note: the marker words code_start and code_end can be any words of your choosing. + See the follow example.

+ +
+ $this->benchmark->mark('cow');
+
+ // Some code executes here...
+
+ $this->benchmark->mark('duck');
+
+ // Some more code executes here...
+
+ $this->benchmark->mark('sheep');
+
+ echo $this->benchmark->elapsed_time('cow', 'duck');
+ echo $this->benchmark->elapsed_time('duck', 'sheep');
+ echo $this->benchmark->elapsed_time('cow', 'sheep'); +
+
+ +
+

Displaying Total CarbonPHP Execution Time

+ +

If you wish to display the total time it took the framework the execute. You can simply place the following + method call into your view.

+ +
+ <?php echo $this->benchmark->elapsed_time(); ?> +
+ +

You will notice that the above code uses the same method as calculating the time between two mark points, + except there are no parameters passed to the method. An alternate way to show the total framework elapsed + time is to include the psuedo-variable {elapsed_time} in your view if you do not wish to use the + pure PHP code.

+ +
+ {elapsed_time} +
+
+ +
+

Displaying CarbonPHP Memory Usage

+ +

If your PHP installation is setup with the --enable-memory-limit configuration option, you can + display the memory that CarbonPHP is using. To do this you can use the following line of code.

+ +
+ <?php echo $this->benchmark->memory_usage(); ?> +
+ +

Note: if you wish to use this method, it can only be used in your view files. The memory usage + shown by this method will display the amount of memory used by the entire application. You can also use a + psuedo-variable to display the memory usage, just like elapsed time.

+ +
+ {memory_usage} +
+
+ +
+

Benchmark Class Methods

+ +

public function __construct()

+

This method initialises the benchmark class.

+ +

public function mark($mark)

+

This method marks the current time in microseconds for the point $mark.

+ +

public function elapsed_time($point1 = '', $point2 = '', $precision = 4)

+

This method will return the elapsed between $point1 and $point2, $precision is the + number of decimal places you wish the time to be. If no parameters are passed the method will

+ +

public function memory_usage()

+

This method returns the memory usage of the CarbonPHP application.

+
+ + + diff --git a/Documentation/libraries/config.html b/Documentation/libraries/config.html new file mode 100644 index 0000000..9b7e59e --- /dev/null +++ b/Documentation/libraries/config.html @@ -0,0 +1,211 @@ + + + CarbonPHP Documentation + + + + +
+

Config Library

+ +

The config library provides an interface for retrieving configuration options. These options can be from + the CarbonPHP configuration file application/config/config.php or from a custom configuration file. + Note: the config library is automatically loaded by CarbonPHP so there is no need for you to load + it.

+
+ +
+

Configuration File Anatomy

+ +

CarbonPHP by default only uses one configuration file application/config/config.php. When you view + this file in a text editor you will see all the options are stored in a PHP array called $config.

+ +

CarbonPHP allows you to add your own configuration options to this file, or if you wish to keep your + configuration options separately you can simply create a file in the application/config/ directory.

+ +

Note: if you choose to create your own configuration files you should follow the same format as the + CarbonPHP configuration file. Configuration options should be stored in an array called $config. + CarbonPHP will be able to manage these files so that there will be no conflict.

+
+ +
+

Loading a Configuration File

+ +

CarbonPHP automatically loads the CarbonPHP configuration file application/config/config.php. + You will only have to load your own configurations files if you have created them.

+ +

There are two methods of loading your own configuration files.

+ +
    +
  1. + Manual Loading + +

    To load one of your own configuration files, you will use the following method within a controller + to load it

    + +
    + $this->config->load('filename'); +
    + +

    Where filename is the name of your configuration file without the file extension.

    + +

    If you need to load multiple configuration files, they are normally merged into one array. This + means that array index name collisions can occur. However if you have identical array index names in + different configuration files you can set the second parameter to true and each configuration + file will be stored in an array index corrosponding to the name of the configuration file.

    + +
    + // Stored in an array with the prototype: $this->config['blog_settings'] = $config;
    + $this->config->load('blog_settings', true); +
    + +

    The loading method has a third parameter that will allow you to supress errors if a configuration + file is not found.

    + +
    + $this->config->load('blog_settings', false, true); +
    +
  2. + +
  3. + Automatically Loading + +

    If you find that you're loading your configuration a lot for different controllers, you may wish + to have that configuration file loaded automatically. To do this you need to edit the + application/config/autoload.php file, and add your configuration file as the comments say.

    +
  4. +
+
+ +
+

Retrieving Configuration Options

+ +

To retrieve a configuration option from your configuration file, you can do the following.

+ +
+ $this->config->get_config_value('item_name'); +
+ +

Where item_name is the name of the $config array index you wish to retrieve. For example if you + wish to retrieve the logging threshold you have set, you do the following.

+ +
+ $threshold = $this->config->get_config_value('logging_threshold'); +
+ +

The method will return false if the configuration option you're trying to get does not exist.

+ +

If you chose the use the second parameter of the load() method in order to assign your configuration + items to a specific array index you can retrieve it by specifying the index name in the second parameter of + the get_config_value() method.

+ +
+ $this->config->load('blog_settings, true);
+
+ $site_name = $this->config->get_config_value('site_name', 'blog_settings');
+
+ // You can also do the following...
+ $blog_config = $this->config->get_config_value('blog_settings');
+ $site_name = $blog_config['site_name']; +
+
+ +
+

Setting Configuration Options

+ +

If you wish to dynamically change the value of a configuration option you can do the following.

+ +
+ $this->config->set_config_value('item_name', 'new_item_value'); +
+ +

Where item_name is the name of the index of the $config array you wish to change, and + new_item_value is the new value of the item. Note: any dynamic changes made to configuration + files are not saved after CarbonPHP finishes executing.

+
+ +
+

Config Class Methods

+ +

public function __construct()

+

This method initialises the config class, and loads the CarbonPHP configuration file.

+ +

public function load($file_name = '', $use_sections = false, $fail_gracefully = false)

+

This method loads a configuration file called $file_name. If $use_sections is set to + true, CarbonPHP will load the configuration file options into an array index with the same name as the + configuration file's name. If $fail_gracefully is set to true CarbonPHP will supress any errors + that occur if a configuration file is not found.

+ +

public function get_config_value($config_item, $index = '')

+

This method will return the value of the configuration option $config_item. If you passed + true to the second parameter of the loading method you can use $index to get the configuration + values of the separate array.

+ +

public function slash_config_item($config_item)

+

This method will return the value of the configuration option $config_item, but with an appended + slash on the end.

+ +

public function get_site_url($uri = '')

+

This method will return the site URL, and if $uri is passed, it will be appended to the end of the + URL.

+ +

public function get_system_url()

+

This method will return the URL to the carbon directory.

+ +

public function set_config_item($config_item, $item_value)

+

This method will set the configuration option $config_item to the value of $item_value.

+
+ + + diff --git a/Documentation/libraries/controller.html b/Documentation/libraries/controller.html new file mode 100644 index 0000000..e7b0650 --- /dev/null +++ b/Documentation/libraries/controller.html @@ -0,0 +1,89 @@ + + + CarbonPHP Documentation + + + + +
+

Controller Library

+ +

This library is a core library and you probably won't have any interaction with it, however the following + methods are present in the class.

+
+ +
+

Controller Class Methods

+ +

public function __construct()

+

This method initialises the class and calls the c_initialise() method.

+ +

private function c_initialise()

+

This method loads and initialises the core CarbonPHP libraries, and then loads any files that are in the + autoload configuration file.

+ +

public function c_scaffolding()

+

This method is called if scaffolding is requested, and this method loads the scaffolding class, and + displays the scaffolding.

+ +

public function set_scaffolding($scaffolding)

+

This method sets whether the request is a scaffolding request or not. $scaffolding being true + or false.

+ +

public function set_scaff_table($scaff_table)

+

This method sets the name of the database table that is being scaffolded.

+
+ + + diff --git a/Documentation/libraries/exception.html b/Documentation/libraries/exception.html new file mode 100644 index 0000000..2a2ce94 --- /dev/null +++ b/Documentation/libraries/exception.html @@ -0,0 +1,91 @@ + + + CarbonPHP Documentation + + + + +
+

Exception Library

+ +

This library is a core library and you probably won't have any interaction with it, however the following + methods are present in the class.

+
+ +
+

Exception Class Methods

+ +

public function __construct()

+

This method initialises the class, and gets the output buffer level.

+ +

public function log_exception($severity, $message, $file_path, $line_number)

+

This method logs an exception with the severity $severity, message of $message, in the file + $file_path, on the line number $line_numer.

+ +

public function display_not_found($page = '')

+

This method displays a 404 page not found page. It also logs a message saying that $page is the + page missing.

+ +

public function display_error($heading, $message, $template = 'error')

+

This method displays a generic error with the heading $header and message $message. You + can also specify which error template you wish it to use.

+ +

public function display_php_error($severity, $message, $file_path, $line_number)

+

This method displays any PHP errors that occur. With the severity $severity, and message + $message. It also displays the file $file_path and line number $line_number of the + PHP error.

+
+ + + diff --git a/Documentation/libraries/extensions.html b/Documentation/libraries/extensions.html new file mode 100644 index 0000000..6677694 --- /dev/null +++ b/Documentation/libraries/extensions.html @@ -0,0 +1,83 @@ + + + CarbonPHP Documentation + + + + +
+

Extensions Library

+ +

This library is a core library and you probably won't have any interaction with it, however the following + methods are present in the class.

+
+ +
+

Extensions Class Methods

+ +

public function __construct()

+

This method initialises the class, and calls the c_initialise() method.

+ +

private function c_initialise()

+

This method initialises the extensions class by reading the extensions configuration file.

+ +

public function c_call_extension($which = '')

+

This method calls the extension point called $which.

+ +

private function c_run_extension($data)

+

This method will call the actual extension that is specified for the extension point.

+
+ + + diff --git a/Documentation/libraries/input.html b/Documentation/libraries/input.html new file mode 100644 index 0000000..8ec0b89 --- /dev/null +++ b/Documentation/libraries/input.html @@ -0,0 +1,195 @@ + + + CarbonPHP Documentation + + + + +
+

Input Library

+ +

The input library provides two purposes which are the following.

+ +
    +
  1. It preprocesses global input data for security.
  2. +
  3. It provides methods for retrieving input data.
  4. +
+ +

Note: this library is loaded automatically by CarbonPHP.

+
+ +
+

Data Sanitising

+ +

The security filtering of CarbonPHP is called automatically when a controller is initialised. This filter + does the following.

+ + +
+ +
+

Cross Site Scripting Filtering

+ +

CarbonPHP comes with a cross site scripting filter that can filter any attempts of cross site scripting. + The cross site scripting filter looks for common techniques used for cross site scripting. Note: it + doesn't escape all HTML entities, only those involved in cross site scripting.

+ +

Note: this method should only be used for data submission. It's processing overhead is fairly high + to use it on runtime processing.

+ +

To use the cross site scripting method you can call it like the following example.

+ +
+ $data = $this->input->xss_clean($data); +
+ +

If you wish to run the filter automatically every time CarbonPHP encounters $_POST or + $_COOKIE data. You enable it by editing the option in the application/config/config.php + file.

+ +
+ $config['use_xss_filtering'] = true; +
+
+ +
+

Using POST, COOKIE, and SERVER Data

+ +

CarbonPHP comes with some methods that allow you to retrieve POST, COOKIE, and SERVER data. The main + advantage of using these methods are rather than retrieving an item directly, the methods will check whether + an item is set, and return false if they're not set.

+ +
+ $somevar = $this->input->post('somevar'); +
+ +

There are three methods for retrieving POST, COOKIE, and SERVER data.

+ + +
+ +
+

Input Class Methods

+ +

public function __construct()

+

This method initialises the class, and loads some of the configuration file value.

+ +

private function c_sanitise_globals()

+

This method sanitised all of the global variables.

+ +

private function c_clean_input_data($string)

+

This method sanitises the string $string.

+ +

private function c_clean_input_keys($string)

+

This method sanitises the keys of any input data.

+ +

public function get($index = '', $xss_clean = false)

+

This method returns the value of $index in the $_GET array. If $xss_clan is set to + true the method will filter the value for cross site scripting attempts.

+ +

public function post($index = '', $xss_clean = false)

+

This method returns the value of $index in the $_POST array. If $xss_clan is set to + true the method will filter the value for cross site scripting attempts.

+ +

public function cookie($index = '', $xss_clean = false)

+

This method returns the value of $index in the $_COOKIE array. If $xss_clan is set to + true the method will filter the value for cross site scripting attempts.

+ +

public function server($index = '', $xss_clean = false)

+

This method returns the value of $index in the $_SERVER array. If $xss_clan is set to + true the method will filter the value for cross site scripting attempts.

+ +

public function ip_address()

+

This method returns the IP address of the user visiting the application.

+ +

public function valid_ip($ip)

+

This method validates whether the IP address $ip is a valid IP address.

+ +

public function user_agent()

+

This method returns the value of the user agent that is visiting the application.

+ +

public function filename_security($string)

+

This method filters a file name $string of any malicious characters.

+ +

public function xss_clean($string)

+

This method filters the string $string for cross site scripting attempts.

+ +

private function c_js_link_removal($match)

+

This method is called by the cross site scripting filter method.

+ +

private function c_js_img_removal($match)

+

This method is called by the cross site scripting filter method.

+ +

private function c_attribute_conversion($match)

+

This method is called by the cross site scripting filter method.

+ +

private function c_html_entity_decode_callback($match)

+

This method is called by the cross site scripting filter method.

+ +

private function c_html_entity_decode($string, $charset = 'UTF-8')

+

This method is called by the cross site scripting filter method.

+
+ + + diff --git a/Documentation/libraries/language.html b/Documentation/libraries/language.html new file mode 100644 index 0000000..7b4f248 --- /dev/null +++ b/Documentation/libraries/language.html @@ -0,0 +1,146 @@ + + + CarbonPHP Documentation + + + + +
+

Language Library

+ +

The language library provides an interface to retrieve language files and lines of text for the sole + purpose of internationalisation.

+ +

In the CarbonPHP directory there is a directory called languages containing language files. You + can create your own language files as needed in order to display errors and other messages in other + languages.

+ +

Languages are typically stored in carbon/languages/. You can alternately create a directory called + languages in your application directory. CarbonPHP will look in the application/languages/ + directory first. Note: each language should be stored in its own directory. For example english + language files will be stored in carbon/languages/english/.

+
+ +
+

Creating Language Files

+ +

Language files must be named with _lang.php at the end. For example if you wanted a language file to + contain error messages, you might name it error_lang.php. Within the file you will assign each line + of text to an array called $lang.

+ +
+ $lang['lang_key'] = 'This is a message in the language.'; +
+ +

Note: it is good practice to prefix your array keys to avoid collisions with similarly named items + that could be in other files. For example in the error language file you could do something like the + following.

+ +
+ $lang['error_missing_url'] = 'The URL is missing';
+ $lang['error_missing_input'] = 'The input is missing';
+ $lang['error_missing_output'] = 'The output is missing'; +
+
+ +
+

Loading Language Files

+ +

In order to retrieve lines from a language file you must load the file.

+ +
+ $this->lang->load('filename', 'language'); +
+ +

Where filename is the name of the file you wish to load, without the file extension, and + language is the language set you want to load for example english. If the second parameter is not + specified the default language from application/config/config.php will be used.

+
+ +
+

Retrieving a Line of Text

+ +

Once you have loaded the language file you can retrieve any line of text from the file.

+ +
+ $this->lang->line('lang_key'); +
+ +

Where lang_key is the array key of the line of text you wish to retrieve. Note: this method + only returns the line, it does not echo it for you.

+
+ +
+

Automatically Loading Language Files

+ +

You may find yourself loading a language file throughout your application, you can automatically load it + you can add it to the application/config/autoload.php configuration file.

+
+ +
+

Language Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function load($langfile = '', $idiom = '', $return = false)

+

This method loads the language file $langfile. If you specify $idiom it will load the file + from that language. If $return is set to true it will return the $lang array.

+ +

public function line($line = '')

+

This method returns the line specified at the array index $line.

+
+ + + diff --git a/Documentation/libraries/loader.html b/Documentation/libraries/loader.html new file mode 100644 index 0000000..8e9fe21 --- /dev/null +++ b/Documentation/libraries/loader.html @@ -0,0 +1,218 @@ + + + CarbonPHP Documentation + + + + +
+

Loader Library

+ +

This is the class that loads the various elements within the framework. These elements can be, models, + views, utilities, and even your own files.

+ +

Note: this library is loaded automatically by CarbonPHP.

+
+ +
+

$this->load->library('class_name')

+ +

This method loads the core CarbonPHP libraries. class_name is the name of the class you wish to + load. For example if you wish to load the pagination library you would do the following.

+ +
+ $this->load->library('pagination'); +
+ +

Once the library has been loaded it will be accessible via the object in the $this object. Each + library is outlined on its own page.

+
+ +
+

$this->load->view('view_name', $data, true/false)

+ +

This method is used to load a view file. The first parameter is required and is the name of the view file + to load without the file extension.

+ +

The second parameter is an optional parameter that can take an array or an object, which it runs through + the PHP function extract to convert to variables that can be accessed in the view file.

+ +

The third parameter is another optional parameter that changes how the method returns. If the parameter + is set to true the method will return the data instead of sending it to the browser.

+ +
+ $data = $this->load->view('myview', '', true); +
+
+ +
+

$this->load->database('options', true/false)

+ +

This method loads the database class which connects to a database. This method is outlined more in the + database pages.

+
+ +
+

$this->load->scaffolding('table_name')

+ +

This method enables scaffolding. This method is outlined more in the scaffolding page.

+
+ +
+

$this->load->var($array)

+ +

This method takes an array as input and generates variables. This method produces the same result as + using the second parameter of $this->load->view() explained above. The main reason you may wish to + use this is if you wish to set some global variables in the constructor of your controller and have them + become available in any view file.

+
+ +
+

$this->load->utility('file_name')

+ +

This method loads any utility files, where file_name is the name of the utility without the + _utility.php on the end.

+
+ +
+

$this->load->file('filepath/filename', true/false)

+ +

This method will load any file. If the second parameter is set to true the data from the file will + be returned as a string, instead of being sent to the browser.

+
+ +
+

$this->load->language('file_name')

+ +

This method is an alias of the $this->lang->load() method.

+
+ +
+

$this->load->config('file_name')

+ +

This method is an alias of the $this->config->load() method.

+
+ +
+

Loader Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function library($library = '', $params = null)

+

This method loads a library class. If $params is passed to the method, it is passed to the + constructor of the library class.

+ +

public function model($model, $name = '', $db_conn = false)

+

This method loads a model file. If $db_conn is passed a database connection will be established. + More information on this method is outlined in the model page.

+ +

public function database($params = '', $return = false, $active_record = false)

+

This method loads the database and connects to the database. More information is available in the database + pages.

+ +

public function dbutils()

+

This method loads the database utilies class.

+ +

public function view($view, $vars = array(), $return = false)

+

This method loads the view file $view. If $vars is passed as an array or object, the + variables will be converted so that you can access them in your view. If $return is set to true + the data will be returned as a string.

+ +

public function file($path, $return = false)

+

This method loads a generic file using the path $path. If $return is set to true the + data will be returned as a string.

+ +

public function vars($vars = array())

+

This method converts the variables passed as an array or object into variables you can use globally in + all of your view files.

+ +

public function utility($utilities = array())

+

This method loads a utility file, if an array is passed it will load all the utilities in that array.

+ +

public function language($file = array(), $lang = '')

+

This method loads a language file, or files in an array. $lang is the name of the language you + wish to use.

+ +

public function scaffold_language($file = '', $lang = '', $return = false)

+

This method loads the language file for scaffolding.

+ +

public function config($file = '', $use_sections = false, $fail_gracefully = false)

+

This method is exactly the same as the $this->config->load() method.

+ +

private function c_load($data)

+

This method loads any non-class files. It is called by the above loading method.

+ +

private function c_load_class($class_name, $params = null)

+

This method loads and initialises the class and passes $params to the class constructor.

+ +

private function c_init_class($class, $prefix = '', $config = false)

+

This method calls the constructor of $class, and if $config is passed it will load any + configuration files for that class.

+ +

public function autoloader()

+

This method autoloads anything specified in the application/config/autoload.php file.

+ +

public function set_view_path($view_path)

+

This method sets the path to the view files.

+ +

private function c_assign_to_models()

+

This method assigns libraries to models so that models can use the $this object.

+ +

private function c_object_to_array($object)

+

This method converts object members into an array.

+
+ + + diff --git a/Documentation/libraries/logging.html b/Documentation/libraries/logging.html new file mode 100644 index 0000000..e81b0dc --- /dev/null +++ b/Documentation/libraries/logging.html @@ -0,0 +1,77 @@ + + + CarbonPHP Documentation + + + + +
+

Logging Library

+ +

This library is a core library and you probably won't have any interaction with it, however the following + methods are present in the class.

+
+ +
+

Logging Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function write_log_message($level = 'error', $message, $php_eror = false)

+

This method writes message to a log file.

+
+ + + diff --git a/Documentation/libraries/model.html b/Documentation/libraries/model.html new file mode 100644 index 0000000..8eb8afd --- /dev/null +++ b/Documentation/libraries/model.html @@ -0,0 +1,76 @@ + + + CarbonPHP Documentation + + + + +
+

Model Library

+ +
+ +
+

Model Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function assign_libraries($use_references = true)

+

This method assigns the CarbonPHP libraries to the model so that the model can access them using the + $this object.

+
+ + + diff --git a/Documentation/libraries/output.html b/Documentation/libraries/output.html new file mode 100644 index 0000000..44e94ee --- /dev/null +++ b/Documentation/libraries/output.html @@ -0,0 +1,139 @@ + + + CarbonPHP Documentation + + + + +
+

Output Library

+ +

The output library is a small class used to send the finalised web page to the browser. It is also + responsible for caching.

+ +

Note: this library is loaded automatically by CarbonPHP.

+ +

Normally you will not notice or interact with the output class.

+
+ +
+

$this->output->set_final_output()

+ +

This lets you set the final output string.

+ +
+ $this->output->set_final_output($data); +
+ +

Note: if you do manually set your output it must be the last thing done when you call it.

+
+ +
+

$this->output->get_final_output()

+ +

This lets you manually get the data as a string that will be sent to the browser.

+ +
+ $data = $this->output->get_final_output(); +
+ +

Note: data will only be available from this method only if the data has previously been sent to + the browser.

+
+ +
+

$this->output->set_header_data()

+ +

This lets you manually set any server headers, which the output class will send for you.

+ +
+ $this->output->set_header_data('HTTP/1.0 200 OK');
+ $this->output->set_header_data('HTTP/1.1 200 OK');
+ $this->output->set_header_data('Last-modified: ' . gmdate('D, d M Y H:i:s', $last_update) . 'GMT');
+ $this->output->set_header_data('Cache-Control: no-store, no-cache, must-revalidate');
+ $this->output->set_header_data('Cache-Control: post-check=0, pre-check=0, false);
+ $this->output->set_header_data('Pragma: no-cache'); +
+ +
+

Output Class Method

+ +

public function __construct()

+

This method initialises the class.

+ +

public function set_final_output($final_output)

+

This method sets the final output to be send to $final_output.

+ +

public function get_final_output()

+

This method returns the final output sent to the browser.

+ +

public function set_header_data($http_header)

+

This method adds a HTTP header to be sent to the browser.

+ +

public function set_cache_expiration($expiration)

+

This method sets the expiration time for cached files.

+ +

public function display_output($output = '')

+

This method displays the output $output.

+ +

private function c_write_cache($output)

+

This method writes the $output to a cache file.

+ +

public function display_cache(&$config, &$router)

+

This method displays the cached output.

+
+
+ + + diff --git a/Documentation/libraries/pagination.html b/Documentation/libraries/pagination.html new file mode 100644 index 0000000..1709c5f --- /dev/null +++ b/Documentation/libraries/pagination.html @@ -0,0 +1,148 @@ + + + CarbonPHP Documentation + + + + +
+

Pagination Library

+ +

CarbonPHP's pagination library is very simple to use, and you can customise every aspect of it.

+
+ +
+

Pagination Example

+ +
+ $this->load->library('pagination');
+
+ $config['base_url'] = 'http://www.your-domain.com/index.php/some/page';
+ $config['total_rows'] = '400';
+ $config['per_page'] = '20';
+
+ $this->pagination->initialise($config);
+
+ echo $this->pagination->create_links(); +
+ +

The $config array contains any configuration options. It is passed to the + $this->pagination->initialise() method.

+ +

If you do not wish to set the configuration options every time, you can create a configuration file + application/config/pagination.php with the configuration options in.

+
+ +
+

Configuration Options

+ +

$config['uri_segment'] - This determines which segment of the URI contains the page number.

+ +

$config['num_links'] - This determines the number of digit links are either side of the current + page number.

+ +

$config['full_tag_open'] - This is the opening tag placed of the left of the entire result.

+ +

$config['full_tag_close'] - This is the closing tag placed at the end of the result.

+ +

$config['first_link'] - This is the text shown for the first link on the left.

+ +

$config['first_tag_open'] - This is the tag on the left of the first link.

+ +

$config['first_tag_close'] - This is the tag on the end of the first link.

+ +

$config['last_link'] - This is the text shown for the last link on the right.

+ +

$config['last_tag_open'] - This is the tag on the left of the last link.

+ +

$config['last_tag_close'] - This is the tag on the end of the last link.

+ +

$config['next_link'] - This is the text of the next page link.

+ +

$config['next_tag_open'] - This is the tag on the left of the next page link.

+ +

$config['next_tag_close'] - This is the tag on the end of the next page link.

+ +

$config['prev_link'] - This is the text of the previous page link.

+ +

$config['prev_tag_open'] - This is the tag on the left of the previous page link.

+ +

$config['prev_tag_close'] - This is the tag on the end of the previous page link.

+ +

$config['cur_tag_open'] - This is the opening tag for the current page link.

+ +

$config['cur_tag_close'] - This is the closing tag for the current page link.

+ +

$config['num_tag_open'] - This is the opening tag for the digit link.

+ +

$config['num_tag_close'] - This is the closing tag for the digit link.

+
+ +
+

Pagination Class Methods

+ +

public function __construct($params = array())

+

This method initialises the class, and if $params is passed it calls the initialise() + method.

+ +

public function initialise($params = array())

+

This method initialises the pagination using the configuration passed in $params or a configuration + file.

+ +

public function create_links()

+

This method returns the links for pagination ready to be outputted on the page.

+
+ + + diff --git a/Documentation/libraries/router.html b/Documentation/libraries/router.html new file mode 100644 index 0000000..de29b91 --- /dev/null +++ b/Documentation/libraries/router.html @@ -0,0 +1,132 @@ + + + CarbonPHP Documentation + + + + +
+

Router Library

+ +

This library is a core library and you probably won't have any interaction with it, however the following + methods are present in the class.

+
+ +
+

Router Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

private function c_set_route_mapping()

+

This method maps out the route based on routing rules, and makes sure the correct controller and method + are loaded and called.

+ +

private function c_compile_uri_segments($segments = array())

+

This method compiles the URI segments into an array.

+ +

private function c_validate_uri_segments($segments)

+

This method validates the URI segments making sure the controller and method exist.

+ +

private function c_reindex_segments()

+

This method reindexes the URI segment array so that index 1 is segment 1.

+ +

public function get_uri_string()

+

This method returns the URI string.

+ +

private function c_parse_request_uri()

+

This method parses the request URI into segments.

+ +

private function c_filter_uri_chars($uri_string)

+

This method filters the URI string for malicious characters.

+ +

private function c_parse_routes()

+

This method parses any routing rules and checks whether routes need remapping.

+ +

public function set_class_name($class_name)

+

This method sets the name of the class to be loaded.

+ +

public function get_class_name()

+

This method returns the name of the class.

+ +

public function set_method_name($method_name)

+

This method sets the name of the method to be called.

+ +

public function get_method_name()

+

This method returns the name of the method.

+ +

public function set_directory_name($directory_name)

+

This method sets the name of the directory.

+ +

public function get_directory_name()

+

This method returns the name of the directory.

+ +

public function segment($index)

+

This method returns the value of the segment at the index $index.

+ +

public function rsegment($index)

+

This method returns the value of the reindexed segment at the index $index.

+ +

public function get_uri_segment_array()

+

This method returns the URI segment array.

+ +

public function get_ruri_segment_array()

+

This method returns the reindexed URI segment array.

+ +

public function is_scaffolding_request()

+

This method returns whether the request is a scaffolding request.

+
+ + + diff --git a/Documentation/libraries/table.html b/Documentation/libraries/table.html new file mode 100644 index 0000000..c718d1e --- /dev/null +++ b/Documentation/libraries/table.html @@ -0,0 +1,199 @@ + + + CarbonPHP Documentation + + + + +
+

Table Library

+ +

The table library provides an interface to auto-generate HTML tables from arrays or database result sets.

+
+ +
+

Example Tables

+ +

This is an example showing how you can generate a table from a multi-dimensional array. The first array + index must be the headings for the table cells. You can also use set_heading() to set table cell + headings.

+ +
+ $this->load->library('table');
+
+ $data = array(
+     array('Name, 'Colour', 'Size'),
+     array('Charlie', 'Blue', 'Small'),
+     array('Emily', 'Green', 'Medium'),
+     array('Simon', 'Red', 'Large')
+ );
+
+ echo $this->table->generate($data); +
+ +

You can also generate tables from database query results. The table class will automatically generate + table headings based on the field names of the table. You can also use the set_heading() method.

+ +
+ $this->load->library('table');
+
+ $query = $this->db->query('SELECT * FROM `some_table`');
+
+ echo $this->table->generate($query); +
+ +

You can also generate tables by individually passing the parameters to methods.

+ +
+ $this->load->library('table');
+
+ $this->table->set_heading('Name, 'Colour', 'Size');
+
+ $this->table->add_row('Charlie', 'Blue', 'Small');
+ $this->table->add_row('Emily', 'Green', 'Medium');
+ $this->table->add_row('Simon', 'Red', 'Large');
+
+ echo $this->table->generate(); +
+
+ +
+

Changing the Table Template

+ +

The table library allows you to change the template that the library uses to generate the table layout.

+ +
+ $template = array (
+     'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
+
+     'heading_row_start' => '<tr>',
+     'heading_row_end' => '</tr>',
+     'heading_cell_start' => '<th>',
+     'heading_cell_end' => '</th>',
+
+     'row_start' => '<tr>',
+     'row_end' => '</tr>',
+     'cell_start' => '<td>',
+     'cell_end' => '</td>',
+
+     'row_alt_start' => '<tr>',
+     'row_alt_end' => '</tr>',
+     'cell_alt_start' => '<td>',
+     'cell_alt_end' => '</td>',
+
+     'table_close' => '</table>'
+ );
+
+ $this->table->set_template($template); +
+ +

Note: you will notice there are two sets of 'row' elements. This allows you to create alternating + row colours or design elements that alternate with each other row.

+ +

You are not required to submit a template with every element changed. You only need to change parts of + the template you need.

+ +
+ $template = array( 'table_open' => '<table cellpadding="2" cellspacing="1" class="tablebox">');
+
+ $this->table->set_template($template); +
+
+ +
+

Table Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function set_template($template)

+

This method sets a user defined template $template.

+ +

public function set_heading()

+

This method sets the headings for the table cells.

+ +

public function make_columns($array = array(), $col_limit = 0)

+

This method takes an array as input and creates a multi-dimensional array with a depth of $col_limit. + This allows a single array with many elements to be displayed in a table that has a fixed column count.

+ +

public function set_empty($value)

+

This method sets the value to be displayed in empty table cells.

+ +

public function add_row()

+

This method lets you add a row to your table using either discreet parameters or an array.

+ +

public function set_caption($caption)

+

This method lets you set a caption for the table.

+ +

public function generate($table_data = null)

+

This method generates the table ready to be outputted.

+ +

public function clear()

+

This method clears any data in the table class so that you can create another table.

+ +

private function c_set_from_object($query)

+

This method sets the table data from the members of an object.

+ +

private function c_set_from_array($data, $set_heading = true)

+

This method sets the table data from an array.

+ +

private function c_compile_template()

+

This method compiles the table template ready for use.

+ +

private function c_default_template()

+

This method returns the default table template.

+
+ + + diff --git a/Documentation/libraries/uri.html b/Documentation/libraries/uri.html new file mode 100644 index 0000000..ac72b5c --- /dev/null +++ b/Documentation/libraries/uri.html @@ -0,0 +1,256 @@ + + + CarbonPHP Documentation + + + + +
+

URI Library

+ +

The URI library provides an interface for retrieving information from URI strings. If you use URI + routing you can also retrieve information about the rerouted segments. Note: the config library is + automatically loaded by CarbonPHP so there is no need for you to load it.

+
+ +
+

$this->uri->segment(index)

+ +

This allows you to retrieve a specific segment. Where index is the segment number you wish to + retrieve. Segments are numbered from left to right.

+ +
+ www.your-domain.com/index.php/blog/archives/2007/09/ +
+ +

The segment numbers would be the following.

+ +
    +
  1. blog
  2. +
  3. archives
  4. +
  5. 2007
  6. +
  7. 09
  8. +
+ +

By default the function will return false if a segment does not exist. There is an optional second + parameter that allows you to set your own return value if a segment does not exist.

+ +
+ $post_id = $this->uri->segment(3, 0); +
+
+ +
+

$this->uri->rsegment(index)

+ +

This method is identical to the above one, except it retrieves the segment from your rerouted URI if you + are using CarbonPHP's URI routing feature.

+
+ +
+

$this->uri->slash_segment(index)

+ +

This method is almost identical to $this->uri->segment(), except it adds a trailing slash and/or + leading slash based on the second parameter.

+ +
+ $this->uri->slash_segment(3);
+ $this->uri->slash_segment(3, 'leading');
+ $this->uri->slash_segment(3, 'both'); +
+ +

The above example would return the following.

+ + +
+ +
+

$this->uri->slash_rsegment(index)

+ +

This method is identical to the above method except that it lets you add slashes to a segment from your + rerouted URI if you're using CarbonPHP's URI routing feature.

+
+ +
+

$this->uri->get_uri_to_assoc(index)

+ +

This method lets you turn URI segments into an associative array of keys and values.

+ +
+ index.php/user/search/name/john/country/england/gender/male +
+ +

Using this method on this URL would turn it into the following array with the following prototype.

+ +
+ [array]
+ (
+     'name' => 'john',
+     'country' => 'england',
+     'gender' => 'male'
+ ) +
+ +

The first parameter of the method lets you set an offset. By default the offset is set to 3 since your + URI will contain a controller and method name in the first and second segments.

+ +

The second parameter lets you set default key names, so that the array returned by the method will always + contain expected indexes, even if they are missing from the URI.

+ +

If the URI does not contain a value in your default an array index will be set to that name with a value of + false. Also if a value is not found for a given array key the value will be set to false.

+
+ +
+

$this->uri->get_ruri_to_assoc(index)

+ +

This method is identical to the above one except that it creates an associative array using the rerouted + URI if you're using the CarbonPHP URI routing feature.

+
+ +
+

$this->uri->assoc_to_uri($array)

+ +

This method takes an associative array and generates a URI string from it.

+ +
+ $array = array('product' => 'shirts', 'size' => 'medium', 'colour' => 'blue');
+
+ $string = $this->uri->assoc_to_uri($array);
+
+ // Will generate: product/shirts/size/medium/colour/blue +
+
+ +
+

$this->uri->get_uri_string()

+ +

This method returns a string with the complete URI.

+ +
+ www.your-domain.com/index.php/blog/post/4 +
+ +

This URI would return the following string.

+ +
+ blog/post/4 +
+
+ +
+

$this->uri->get_ruri_string()

+ +

This method is identical to the above one except that it returns the rerouted URI if you're using the + URI rerouting feature of CarbonPHP.

+
+ +
+

URI Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function segment($index, $no_result = false)

+

This method returns the value of a URI segment.

+ +

public function rsegment($index, $no_result = false)

+

This method returns the value of a rerouted URI segment.

+ +

public function get_uri_to_assoc($index = 3, $default = array())

+

This method creates an associative array from a URI.

+ +

public function get_ruri_to_assoc($index = 3, $default = array())

+

This method creates an associative array from a rerouted URI.

+ +

private function c_uri_to_assoc($index = 3, $default, $which = 'segment')

+

This method creates the associative arrays for the URI methods.

+ +

public function assoc_to_uri($array)

+

This method creates a URI string from an associative array.

+ +

public function slash_segment($index, $where = 'trailing')

+

This method returns a URI segment with a slash in the specified place.

+ +

public function slash_rsegment($index, $where = 'trailing')

+

This method returns a rerouted URI segment with a slash in the specified place.

+ +

private function c_slash_segment($index, $where = 'trailing', $which = 'segment')

+

This method gets the URI segment and slashes the value.

+ +

public function get_segment_array()

+

This method returns an array of URI segments.

+ +

public function get_rsegment_array()

+

This method returns an array of rerouted URI segments.

+ +

public function total_segments()

+

This method returns the total number of URI segments.

+ +

public function total_rsegments()

+

This method returns the total number of rerouted URI segments.

+ +

public function get_uri_string()

+

This method returns the URI string.

+ +

public function get_ruri_string()

+

This method returns the rerouted URI string.

+
+ + + diff --git a/Documentation/libraries/zip.html b/Documentation/libraries/zip.html new file mode 100644 index 0000000..9b09269 --- /dev/null +++ b/Documentation/libraries/zip.html @@ -0,0 +1,219 @@ + + + CarbonPHP Documentation + + + + +
+

Zip Library

+ +

The zip library allows you to create zip archives which can be downloaded or saved to a directory on the + web host.

+ +

You can load the zip library just like any other library with the $this->load->library() method.

+
+ +
+

Using the Zip Library

+ +

This example shows you how to compress a file, save it to a directory on the web host, and download it.

+ +
+ $name = 'somedata.txt';
+ $data = 'This is a data string';
+
+ $this->zip->data_date($name, $data);
+
+ // Write the zip file to a directory...
+ $this->zip->archive('/path/to/a/dir/backup.zip');
+
+ // Download the file...
+ $this->zip->download('backup.zip'); +
+
+ +
+

$this->zip->add_data()

+ +

This method allows you to add data to your zip archive. The first parameter is the file name, and the + second parameter is the data contained in the file as a string.

+ +
+ $name = 'some_file.txt';
+ $data = 'This is some random data to store in the file...';
+
+ $this->zip->add_data($name, $data); +
+ +

You can also call the method multiple times to add multiple files to the archive. You can also pass multiple + files to the method using an array.

+ +
+ $data = array(
+     'file1.txt' => 'Some data',
+     'file2.txt' => 'More data'
+ );
+
+ $this->zip->add_data($data);
+
+ $this->zip->download('backup.zip'); +
+ +

You can also organised your compressed data into subdirectories by including the path in the file name.

+
+ +
+

$this->zip->add_dir()

+ +

This method allows you to add a directory to your archive. You usually do not need to call this as you + can place your data into directories with the $this->zip->add_data() method.

+ +
+ // Creates a directory called 'folder' in the archive...
+ $this->zip->add_dir('folder'); +
+
+ +
+

$this->zip->read_file()

+ +

This method allows you to add an existing file to the archive.

+ +
+ $path = '/path/to/my/photo.jpg';
+
+ $this->zip->read_file($path);
+
+ $this->zip->download('my_photos.zip'); +
+ +

If you wish the zip archive to maintain the directory structure the file is in, you can pass true in + the second parameter of the method.

+
+ +
+

$this->zip->read_dir()

+ +

This allows you to recursively add a directory and it's contents to an archive.

+ +
+ $path = '/path/to/directory/';
+
+ $this->zip->read_dir($path);
+
+ $this->zip->download('backup.zip'); +
+
+ +
+

$this->zip->archive()

+ +

This method allows you to create the zip archive in a directory on the web host. The directory must have + the correct permissions (666 or 777 will be fine).

+ +
+ // Creates an archive called 'archive.zip'... + $this->zip->archive('/path/to/backups/archive.zip'); +
+
+ +
+

$this->zip->archive()

+ +

This method causes the archive to be downloads from the server. The function must be passed the name + you would like the zip archive to the called. Note: do not display any data in the controller in which + you call this method since it sends server headers that cause the download to occur and the file to be treated + as binary data.

+
+ +
+

Zip Class Methods

+ +

public function __construct()

+

This method initialises the class.

+ +

public function add_dir($directory)

+

This method adds an empty directory to the archive.

+ +

private function c_add_dir($directory)

+

This method actually adds the directory to the archive data.

+ +

public function add_data($filepath, $data = null)

+

This method adds data to the archive.

+ +

private function c_add_data($filepath, $data)

+

This method actually adds the data to the archive.

+ +

public function read_file($path, $preserver_filepath = false)

+

This method reads a file and adds it to the archive.

+ +

public function read_dir($path)

+

This method recursively adds a directory and it's contents to the archive.

+ +

public function get_zip()

+

This method returns the raw zip data as a string.

+ +

public function archive($filepath)

+

This method creates the archive on the server.

+ +

public function download($filename = 'backup.zip')

+

This method causes the archive to be sent to the browser as a download.

+ +

public function clear_data()

+

This method resets the zip data so another zip archive can be created.

+
+ + + diff --git a/Documentation/utilities/filesystem.html b/Documentation/utilities/filesystem.html new file mode 100644 index 0000000..ec16a58 --- /dev/null +++ b/Documentation/utilities/filesystem.html @@ -0,0 +1,158 @@ + + + CarbonPHP Documentation + + + + +
+

Filesystem Utility

+ +

This utility is loaded using the following piece of code.

+ +
+ $this->load->utility('filesystem'); +
+
+ +
+

read_file('path')

+ +

This function returns the data contained in the file specified in the path.

+ +
+ $string = read_file('./path/to/the/file.php'); +
+ +

The path can either be a relative path or full serve rpath. The function returns false on failure.

+ +

The path is relative to the sites index.php file, not your controller or view files.

+ +

If your server is running an open_basedir restriction this function may not work if you're trying to access + a file above the calling script.

+
+ +
+

write_file('path', $data)

+ +

This function writes data to the file specified in the path. If the file does not exist the function will + create it.

+ +
+ $data = 'This is some data for the file.';
+
+ if (!write_file('./path/to/file.php', $data))
+ {
+     echo 'Unable to write data to the file.';
+ }
+ else
+ {
+     echo 'File has been written.';
+ } +
+ +

You can also optionally set the write mode via the third parameter.

+ +
+ write_file('./path/to/file.php', $data, 'r+'); +
+ +

The default mode is wb. Please see the PHP documentation for the fopen() function. In + order for this function to write data to a file its file permissions must be set such that it is writable + (666, or 777 should be enough). If the file does not exist, the directory containing it must be writable.

+ +

The path is relative to the sites index.php, not the controller or view files.

+
+ +
+

delete_files('path')

+ +

Deletes all the file contained the directory supplied as the path.

+ +
+ delete_files('./path/to/dir'); +
+ +

If the second parameter is set to true, any directories in the root of the path will be deleted + as well.

+ +
+ delete_files('./path/to/dir', true); +
+ +

The files must be writable or owned by the system in order for them to be deleted.

+
+ +
+

get_filenames('path')

+ +

Takes a server path as input and returns an array containing the names of all the files contained in the + directory specified by the path. The file path can optionally be added to the file name by passing + true as the second parameter.

+
+ + + diff --git a/Documentation/utilities/form.html b/Documentation/utilities/form.html new file mode 100644 index 0000000..cc08b7c --- /dev/null +++ b/Documentation/utilities/form.html @@ -0,0 +1,309 @@ + + + CarbonPHP Documentation + + + + +
+

Form Utility

+ +

The form utility file contains functions that assist in working with and creating forms. You load the + utility with the following piece of code.

+ +
+ $this->load->utility('form'); +
+
+ +
+

form_open()

+ +

This function creates an opening form tag with a base URL built from your configuration preferences. It + will optionally let you add form attributes and hidden input fields. The main benefit of using this function + rather than hard coding your own HTML is that it permits your site to be more portable in the event you + choose to change your URLs.

+ +
+ echo form_open('email/submit'); +
+ +

The above example will create a form that looks like the following.

+ +
+ <form method="post" action="http://www.your-domain.com/index.php/email/submit" /> +
+ +

Attributes can be added by passing an associative array as the second parameter.

+ +
+ $attr = array('class' => 'someform', 'id' => 'email');
+
+ echo form_open('email/submit', $attr); +
+ +

This code would create the following opening form tag.

+ +
+ <form method="post" action="http://www.your-domain.com/index.php/email/submit" + class="someform" id="email" /> +
+ +

You can create hidden fields by passing an associative array as a the third parameter.

+ +
+ $hidden = array('username' => 'John', 'id' => '2');
+
+ echo form_open('email/send', '', $hidden); +
+ +

The above example will create the following form.

+ +
+ <form method="post" action="http:/www.your-domain.com/index.php/email/submit" />
+ <input type="hidden" name="username" value="John" />
+ <input type="hidden" name="id" value="2" /> +
+
+ +
+

form_input()

+ +

This function lets you generate a standard text input field. You can minimally pass the field name + and a value in the first and second parameters.

+ +
+ echo form_input('username', 'john'); +
+ +

You can pass an associative array containing any data you wish your form to contain.

+ +
+ $data = array(
+     'name' => 'username',
+     'id' => 'username',
+     'value' => 'john',
+     'maxlength' => '100',
+     'size' => '50',
+     'style' => 'width: 100px'
+ );
+
+ echo form_input($data); +
+ +

If you would like your form to contain any additional data like JavaScript you can pass it as a string + in the third parameter.

+ +
+ $js = 'onclick="somefunction();"';
+
+ echo form_input('username', 'john', $js); +
+
+ +
+

form_password()

+ +

This function is identical to form_input() except that it sets it as a password type.

+
+ +
+

form_upload()

+ +

This function is identical to form_input() except that it set it as a file type, allowing it to + be used to upload files.

+
+ +
+

form_textarea()

+ +

This function is identical to form_input() exception that it generates a 'textarea' type. Instead + if maxlength and size attributes in the above example, you will instead specify rows and cols.

+
+ +
+

form_dropdown()

+ +

This function lets you create a standard dropdown field. The first parameter will contain the name of + the field, the second parameter is an associative array of options and the third parameter will contain + the value you wish to be selected by default.

+ +
+ $options = array(
+     'small' => 'Small shirt',
+     'medium' => 'Medium shirt',
+     'large' => 'Large shirt',
+     'xlarge' => 'Extra large shirt'
+ );
+
+ echo form_dropdown('shirts', $options, 'large'); +
+ +

If you wish to add any additional data like JavaScript you can pass it as a string in the fourth + parameter.

+ +
+ $js = 'onchange="somefunction();"';
+
+ echo form_dropdown('shirts', $options, 'large', $js); +
+
+ +
+

form_checkbox()

+ +

This function lets you generate a checkbox field.

+ +
+ echo form_checkbox('email', 'accept', true); +
+ +

The third parameter contains a true or false to determine whether the checkbox should be checked or not.

+ +

Similar to the other form functions, you can pass an array of attributes to the functions.

+ +
+ $data = array(
+     'name' => 'email',
+     'id' => 'email',
+     'value' => 'accept',
+     'checked' => true,
+     'style' => 'width: 10px;'
+ );
+
+ echo form_checkbox($data); +
+ +

Just like the other functions if you wish the tag to contain additional data like JavaScript, you + pass it as a string in the fourth parameter.

+ +
+ $js = 'onclick="somefunction();"';
+
+ echo form_checkbox('email', 'accept', true, $js); +
+
+ +
+

form_radio()

+ +

This function is identical to the form_checkbox() function except it creates a radio type field.

+
+ +
+

form_submit()

+ +

This function lets you generate a standard submit button.

+ +
+ echo form_submit('submit', 'Submit'); +
+ +

As the same as other functions you can submit an associative array in the first parameter if you prefer to + set your own attributes, the third parameter lets your add extra data for your form like JavaScript.

+
+ +
+

form_close()

+ +

This function produces a closing form tag. The only advantage to using this function is it allows you to + pass data to it which will be added below the tag.

+ +
+ $string = '</div>';
+
+ echo form_close($string);
+
+ // This produces:
+ // </form>
+ // </div> +
+
+ +
+

form_prep()

+ +

This function allows you to safely use HTML and characters such as quotes within form elements without + breaking out of the form.

+ +
+ $string = 'Here is a string containing "quoted" text.';
+
+ <input type="text" name="form" value="$string" /> +
+ +

Since the string contains quoted text so it will cause the form to break. The form_prep() function + converts HTML so that it can be used safely.

+ +
+ <input type="text" name="form" value="<?php echo form_prep($string); ?>" /> +
+ +

If you use any of the form utlity functions the values will automatically be prepped for you.

+
+ + + diff --git a/Documentation/utilities/url.html b/Documentation/utilities/url.html new file mode 100644 index 0000000..1f71e57 --- /dev/null +++ b/Documentation/utilities/url.html @@ -0,0 +1,266 @@ + + + CarbonPHP Documentation + + + + +
+

URL Utility

+ +

This utility file contains functions to help with working with URLs. You can load this utility using + the following piece of code.

+ +
+ $this->load->utility('url'); +
+
+ +
+

site_url()

+ +

This function returns the site URL as specified in your config file. The index.php file will be + added to the URL, as will any URI segments you pass to the function.

+ +
+ echo site_url('blog/post/1'); +
+ +

The above example would return something like the following.

+ +
+ www.your-domain.com/index.php/blog/post/1 +
+ +

You can also pass the segments as an array.

+ +
+ $segments = array('blog', 'post', '1');
+
+ echo site_url($segments); +
+
+ +
+

base_url()

+ +

This function returns the site base URL as specified in the configuration file.

+
+ +
+

index_page()

+ +

This function returns the site index page as specified in your configuration file.

+
+ +
+

anchor()

+ +

This function creates a standard HTML anchor link based on your site URL.

+ +

The first parameter can contain any segments you wish to append to the URL. As with the site_url() + function above, segments can be a string, or an array. The second segment is the text you would like the + link to say. If you leave it blank, the URL will be used. The third parameter can contain a list of + attributes you would like added to the link.

+ +
+ echo anchor('news/local/1', 'Local News'); +
+ +
+ echo anchor('news/local/1', 'Local News', array('title' => 'Local News')); +
+
+ +
+

anchor_popup()

+ +

This function is nearly identical to the anchor() function except that it opens the URL in a new + window. You can specify the JavaScript window attributes in the third parameter to control how the window + is opened.

+ +
+ $attr = array(
+     'width' => '800',
+     'height' => '600',
+     'scrollbars' => 'yes',
+     'status' => 'yes',
+     'resizable' => 'yes',
+     'screenx' => '0',
+     'screeny' => '0'
+ );
+
+ echo anchor_popup('news/local/1', 'Local News', $attr); +
+ +

If you wish to use the function default you only need to pass an empty array to the third parameter.

+
+ +
+

mailto()

+ +

This function creates a standard HTML email link.

+ +
+ echo mailto('email@domain.com', 'Contact Us'); +
+ +

You can passed attributes using the third parameter like the anchor() function.

+
+ +
+

safe_mailto()

+ +

This function is identical to the mailto() function except it writes an obfuscated version of + the mailto tag with ordinal numbers written with JavaScript.

+
+ +
+

auto_link()

+ +

This function automatically turns URLs and email addresses contained in a string into links.

+ +
+ $string = auto_link($string); +
+ +

The second parameter determines whether URLs and emails are converted or just one or the other.

+ +

Converting only URLs.

+ +
+ $string = auto_link($string, 'url'); +
+ +

Converting only emails.

+ +
+ $string = auto_link($string, 'email'); +
+ +

The third parameter determines whether links are shown in a new window.

+ +
+ $string = auto_link($string, 'both', true); +
+
+ +
+

url_title()

+ +

This function takes a string as input and creates a human friendly URL string.

+ +
+ $title = "What's Wrong With HTML";
+
+ $url_title = url_title($title);
+
+ // This produces: whats-wrong-with-html +
+ +

The second parameter determines the character for the word delimeter. The options are dash or + underscore.

+ +
+ $title = "What's Wrong With HTML";
+
+ $url_title = url_title($title, 'underscore');
+
+ // This produces: whats_wrong_with_html +
+
+ +
+

prep_url()

+ +

This function will add http:// in the event that it is missing from a URL.

+ +
+ $url = "www.your-domain.com";
+
+ $url = prep_url($url); +
+
+ +
+

redirect()

+ +

This function does a header redirect to the local URI specified. Just like other function in this + utility, this one is designed to use a local URL. You do not specify the full site URL. The second parameter + allows you to choose between the 'location' method or the 'refresh' method.

+ +
+ if (!$logged_in)
+ {
+     redirect('login/form', 'refresh');
+ } +
+ +

In order for this function to work correctly it must be used before any output is sent to the browser.

+
+ + + diff --git a/Documentation/utilities/uuid.html b/Documentation/utilities/uuid.html new file mode 100644 index 0000000..86162c5 --- /dev/null +++ b/Documentation/utilities/uuid.html @@ -0,0 +1,95 @@ + + + CarbonPHP Documentation + + + + +
+

UUID Utlity

+ +

The UUID utlity contains a function used for generating a 10 character UUID string. You load this utility + by using the following piece of code.

+ +
+ $this->load->utility('uuid'); +
+
+ +
+

generate_uuid()

+ +

This function returns a 10 character UUID string. You pass it a 2 character ID.

+ +
+ $uuid = generate_uuid('d0');
+
+ // This produces something like: d0jd8dJd9D +
+
+ + + diff --git a/Documentation/utilities/xml.html b/Documentation/utilities/xml.html new file mode 100644 index 0000000..7a9f9e3 --- /dev/null +++ b/Documentation/utilities/xml.html @@ -0,0 +1,102 @@ + + + CarbonPHP Documentation + + + + +
+

XML Utility

+ +

The XML utlity contains functions that help when working with XML data. You load this utility using the + following piece of code.

+ +
+ $this->load->utility('xml'); +
+
+ +
+

xml_convert('string')

+ +

This function takes a string as input and converts the following XML characters to entities.

+ + + +

This function ignores ampersands if they are part of existing character entities.

+ +
+ $string = xml_convert($string); +
+
+ + + diff --git a/Source/application/config/autoload.php b/Source/application/config/autoload.php new file mode 100644 index 0000000..bc064b5 --- /dev/null +++ b/Source/application/config/autoload.php @@ -0,0 +1,36 @@ + diff --git a/Source/application/config/config.php b/Source/application/config/config.php new file mode 100644 index 0000000..608117e --- /dev/null +++ b/Source/application/config/config.php @@ -0,0 +1,64 @@ + diff --git a/Source/application/config/database.php b/Source/application/config/database.php new file mode 100644 index 0000000..1c8bdab --- /dev/null +++ b/Source/application/config/database.php @@ -0,0 +1,59 @@ + diff --git a/Source/application/config/extensions.php b/Source/application/config/extensions.php new file mode 100644 index 0000000..cbe6c42 --- /dev/null +++ b/Source/application/config/extensions.php @@ -0,0 +1,68 @@ +output->get_output(). +*------------------------------------------------------------*/ +$extension['display_override'] = array(); + +/*------------------------------------------------------------ +* This extension point overrides the c_display_cache() +* function. This allows you to use your own cache display +* methodology. +*------------------------------------------------------------*/ +$extension['cache_override'] = array(); + +/*------------------------------------------------------------ +* This extension point overrides the c_scaffolding() +* functions. It allows you to call your own script when +* scaffolding is requested. +*------------------------------------------------------------*/ +$extension['scaffolding_override'] = array(); + +/*------------------------------------------------------------ +* This extension point is called after the final page +* rendered has been sent to the browser, right as the end +* of the system execution after the data is sent. +*------------------------------------------------------------*/ +$extension['post_system'] = array(); + +?> diff --git a/Source/application/config/routing.php b/Source/application/config/routing.php new file mode 100644 index 0000000..11d12b4 --- /dev/null +++ b/Source/application/config/routing.php @@ -0,0 +1,32 @@ + diff --git a/Source/application/controllers/carbon.php b/Source/application/controllers/carbon.php new file mode 100644 index 0000000..081a42d --- /dev/null +++ b/Source/application/controllers/carbon.php @@ -0,0 +1,23 @@ +load->scaffolding('tombell_blog_posts'); + } + + public function index() + { + $this->load->utility('url'); + $this->load->view('carbon_view'); + } + + public function _remap($method) + { + echo 'Method: ' . $method; + } +} + +?> diff --git a/Source/application/errors/error.php b/Source/application/errors/error.php new file mode 100644 index 0000000..f807588 --- /dev/null +++ b/Source/application/errors/error.php @@ -0,0 +1,34 @@ + + + Error + + + + + +
+

+

+
+ + + \ No newline at end of file diff --git a/Source/application/errors/error_404.php b/Source/application/errors/error_404.php new file mode 100644 index 0000000..34a6653 --- /dev/null +++ b/Source/application/errors/error_404.php @@ -0,0 +1,38 @@ + + + + + 404 Page Not Found + + + + +
+

+

+
+ + diff --git a/Source/application/errors/error_database.php b/Source/application/errors/error_database.php new file mode 100644 index 0000000..a17a171 --- /dev/null +++ b/Source/application/errors/error_database.php @@ -0,0 +1,34 @@ + + + Database Error + + + + + +
+

+

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

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ +
\ No newline at end of file diff --git a/Source/application/views/carbon_view.php b/Source/application/views/carbon_view.php new file mode 100644 index 0000000..12daf5e --- /dev/null +++ b/Source/application/views/carbon_view.php @@ -0,0 +1,55 @@ + + + + Welcome to CarbonPHP + + + + + +
+

Welcome to CarbonPHP

+ +

You have successfully setup CarbonPHP ready for use. You can begin coding your controllers + in application/controllers and your views in the applicastion/views directory. Once you work + on models they can be stored in application/models.

+ +

CarbonPHP is a framework developed to allow developers to create PHP web applications in less + time than it would than if they were writing from scratch. CarbonPHP offers common libraries for + developers to use, but also allows developers to extend and create their own application specific + libraries.

+ +

Default Controller

+ +
+ $this->load->view('carbon_view'); +
+ +

The default controller contains the above code to load this view. You can create your own + views and controllers.

+ +

Default View

+ +

The default view is the page you're viewing now! It contains the HTML and CSS that is viewed + by the user.

+ +
+ application/views/carbon_view.php +
+ +

You are also able to pass data from the controller/models. This allows for the creation of + dynamic pages. You are free to modify the CarbonPHP code aslong as the copyright notices remiain + at the top of the CarbonPHP files.

+ +

Total execution time: {elapsed_time} seconds

+

Memory usage: {memory_usage}

+ +

+ +
+ + + + diff --git a/Source/application/views/stylesheet.css b/Source/application/views/stylesheet.css new file mode 100644 index 0000000..037ed70 --- /dev/null +++ b/Source/application/views/stylesheet.css @@ -0,0 +1,23 @@ +body { + background: #fff; + color: #000; + font-family: "Lucida Sans Unicode", "Lucida Grande"; + font-size: 12px; +} + +h1 { + font-size: 15px; + font-weight: normal; +} + +.content { + text-align: justify; + width: 500px; +} + +.code { + background: #eee; + border: 1px solid #666; + margin: 5px; + padding: 5px; +} \ No newline at end of file diff --git a/Source/carbon/config/autoload.php b/Source/carbon/config/autoload.php new file mode 100644 index 0000000..bc064b5 --- /dev/null +++ b/Source/carbon/config/autoload.php @@ -0,0 +1,36 @@ + diff --git a/Source/carbon/config/config.php b/Source/carbon/config/config.php new file mode 100644 index 0000000..608117e --- /dev/null +++ b/Source/carbon/config/config.php @@ -0,0 +1,64 @@ + diff --git a/Source/carbon/config/database.php b/Source/carbon/config/database.php new file mode 100644 index 0000000..1c8bdab --- /dev/null +++ b/Source/carbon/config/database.php @@ -0,0 +1,59 @@ + diff --git a/Source/carbon/config/extensions.php b/Source/carbon/config/extensions.php new file mode 100644 index 0000000..cbe6c42 --- /dev/null +++ b/Source/carbon/config/extensions.php @@ -0,0 +1,68 @@ +output->get_output(). +*------------------------------------------------------------*/ +$extension['display_override'] = array(); + +/*------------------------------------------------------------ +* This extension point overrides the c_display_cache() +* function. This allows you to use your own cache display +* methodology. +*------------------------------------------------------------*/ +$extension['cache_override'] = array(); + +/*------------------------------------------------------------ +* This extension point overrides the c_scaffolding() +* functions. It allows you to call your own script when +* scaffolding is requested. +*------------------------------------------------------------*/ +$extension['scaffolding_override'] = array(); + +/*------------------------------------------------------------ +* This extension point is called after the final page +* rendered has been sent to the browser, right as the end +* of the system execution after the data is sent. +*------------------------------------------------------------*/ +$extension['post_system'] = array(); + +?> diff --git a/Source/carbon/config/routing.php b/Source/carbon/config/routing.php new file mode 100644 index 0000000..11d12b4 --- /dev/null +++ b/Source/carbon/config/routing.php @@ -0,0 +1,32 @@ + diff --git a/Source/carbon/core/Base.php b/Source/carbon/core/Base.php new file mode 100644 index 0000000..53f31f4 --- /dev/null +++ b/Source/carbon/core/Base.php @@ -0,0 +1,32 @@ + diff --git a/Source/carbon/core/Carbon_Core.php b/Source/carbon/core/Carbon_Core.php new file mode 100644 index 0000000..56f25fd --- /dev/null +++ b/Source/carbon/core/Carbon_Core.php @@ -0,0 +1,109 @@ +mark('total_execution_time_start'); +$bench->mark('total_base_class_loading_time_start'); + +$ext = load_class('Extensions'); + +$ext->c_call_extension('pre_system'); + +$config = load_class('Config'); +$router = load_class('Router'); +$output = load_class('Output'); + +if ($ext->c_call_extension('cache_override') === false) +{ + if ($output->display_cache($config, $router) == true) + { + exit(); + } +} + +$input = load_class('Input'); +$lang = load_class('Language'); +$uri = load_class('Uri'); + +require(CARBON_PATH . 'core/Base' . FILE_EXT); + +load_class('Controller', false); + +if (!@include(APP_PATH . 'controllers/' . $router->get_directory_name() . $router->get_class_name() . FILE_EXT)) +{ + display_error('Unable to load the default controller. Make sure the default controller in the routing.php file is correct.'); +} + +$bench->mark('total_base_class_loading_time_end'); + +$class_name = $router->get_class_name(); +$method_name = $router->get_method_name(); + +if (!class_exists($class_name) || $method_name == 'controller' || substr($method_name, 0, 1) == '_' || in_array($method_name, get_class_methods('Controller'), true)) +{ + display_not_found(); +} + +$ext->c_call_extension('pre_controller'); + +$bench->mark('controller_execution_time_( ' . $class_name . ' / ' . $method_name . ')_start'); + +$carbon = new $class_name(); + +if ($router->is_scaffolding_request() === true) +{ + if ($ext->c_call_extension('scaffolding_override') === false) + { + $carbon->c_scaffolding(); + } +} +else +{ + $ext->c_call_extension('post_controller_constructor'); + + if (!method_exists($carbon, $method_name)) + { + display_not_found(); + } + + call_user_func_array(array(&$carbon, $method_name), array_slice($router->get_ruri_segment_array(), (($router->get_directory_name() == '') ? 2 : 3))); +} + +$bench->mark('controller_execution_time_( ' . $class_name . ' / ' . $method_name . ')_end'); + +$ext->c_call_extension('post_controller'); + +if ($ext->c_call_extension('display_override') === false) +{ + $output->display_output(); +} + +$ext->c_call_extension('post_system'); + +if (class_exists('Carbon_Database') && isset($carbon->db)) +{ + $carbon->db->close(); +} + +?> diff --git a/Source/carbon/core/Common.php b/Source/carbon/core/Common.php new file mode 100644 index 0000000..0b151e6 --- /dev/null +++ b/Source/carbon/core/Common.php @@ -0,0 +1,163 @@ +display_error('An error has been encountered', $error_message); + exit(); +} + +function display_not_found($page = '') +{ + $exception = load_class('Exception'); + $exception->display_not_found($page); + exit(); +} + +function log_message($level = 'error', $message, $php_error = false) +{ + static $logging; + $config = load_config(); + + if (get_config_value('logging_threshold') == 0) + { + return false; + } + + $logging = load_class('Logging'); + $logging->write_log_message($level, $message, $php_error); +} + +function exception_handler($severity, $message, $file_path, $line_number) +{ + if ($severity == E_STRICT) + { + return true; + } + + $exception = load_class('Exception'); + + if (($severity & error_reporting()) == $severity) + { + $exception->display_php_error($severity, $message, $file_path, $line_number); + } + + $config = load_config(); + + if (get_config_value('logging_threshold') == 0) + { + return true; + } + + $exception->log_exception($severity, $message, $file_path, $line_number); +} + +?> diff --git a/Source/carbon/database/Database.php b/Source/carbon/database/Database.php new file mode 100644 index 0000000..a85e88c --- /dev/null +++ b/Source/carbon/database/Database.php @@ -0,0 +1,65 @@ + diff --git a/Source/carbon/database/Database_active_record.php b/Source/carbon/database/Database_active_record.php new file mode 100644 index 0000000..2cba940 --- /dev/null +++ b/Source/carbon/database/Database_active_record.php @@ -0,0 +1,545 @@ +ar_select[] = $value; + } + } + + return $this; + } + + public function distinct($value = true) + { + $this->ar_distinct = (is_bool($value)) ? $value : true; + + return $this; + } + + public function from($from) + { + foreach ((array) $from as $value) + { + $this->ar_from[] = $this->dbprefix . $value; + } + + return $this; + } + + public function join($table, $condition, $type = '') + { + if ($type != '') + { + $type = strtoupper(trim($type)); + + if (!in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), true)) + { + $type = ''; + } + else + { + $type .= ' '; + } + } + + if ($this->dbprefix) + { + $condition = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $condition); + } + + if ($this->dbprefix) + { + $condition = preg_replace('|(' . $this->dbprefix . ')([\w\.]+)([\W\s]+)|' . "$2$3", $condition); + $condition = preg_replace('|([\w\.]+)([\W\s]+)(.+)|', $this->dbprefix . "$1$2" . $this->dbprefix . "$3", $condition); + } + + $this->ar_join[] = $type . 'JOIN ' . $this->dbprefix . $table . ' ON ' . $condition; + + return $this; + } + + public function where($key, $value = null) + { + return $this->database_where($key, $value, 'AND '); + } + + public function orwhere($key, $value = null) + { + return $this->database_where($key, $value, 'OR '); + } + + private function database_where($key, $value = null, $type = 'AND ') + { + if (!is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_where) == 0) ? '' : $type; + + if (!is_null($v)) + { + if ((!$this->database_has_operator($k))) + { + $k .= ' ='; + } + + $v = ' ' . $this->escape($v); + } + + $this->ar_where[] = $prefix . $k . $v; + } + + return $this; + } + + public function like($field, $match = '') + { + return $this->database_like($field, $match, 'AND '); + } + + public function orlike($field, $match = '') + { + return $this->database_like($field, $match, 'ON '); + } + + private function database_like($field, $match = '', $type = 'AND ') + { + if (!is_array($field)) + { + $field = array($field => $match); + } + + foreach ($field as $k => $v) + { + $prefix = (count($this->ar_like) == 0) ? '' : $type; + $v = $this->escape_string($v); + $this->ar_like[] = $prefix . " $k LIKE '%{%v}%'"; + } + + return $this; + } + + public function groupby($by) + { + if (is_string($by)) + { + $by = explode(',', $by); + } + + foreach ($by as $val) + { + $val = trim($val); + + if ($val != '') + { + $this->ar_groupby[] = $val; + } + } + + return $this; + } + + public function having($key, $value = '') + { + return $this->database_having($key, $value, 'AND '); + } + + public function orhaving($key, $value = '') + { + return $this->database_having($key, $value, 'ON '); + } + + private function database_having($key, $value, $type = 'AND ') + { + if (!is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $prefix = (count($this->ar_having) == 0) ? '' : $type; + + if ($v != '') + { + $v = ' ' . $this->escape($v); + } + + $this->ar_having[] = $prefix . $k . $v; + } + + return $this; + } + + public function orderby($orderby, $direction = '') + { + if (trim($direction) != '') + { + $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC', 'RAND()'), true)) ? ' ' . $direction : ' ASC'; + } + + $this->ar_orderby[] = $orderby . $direction; + + return $this; + } + + public function limit($value, $offset = '') + { + $this->ar_limit = $value; + + if ($offset != '') + { + $this->ar_offset = $offset; + } + + return $this; + } + + public function offset($value) + { + $this->ar_offset = $value; + + return $this; + } + + public function set($key, $value = '') + { + $key = $this->database_object_to_array($key); + + if (!is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + $this->ar_set[$k] = $this->escape($v); + } + + return $this; + } + + public function get($table = '', $limit = null, $offset = null) + { + if ($table != '') + { + $this->from($table); + } + + if (!is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->database_compile_select(); + $result = $this->query($sql); + $this->database_reset_select(); + + return $result; + } + + public function getwhere($table = '', $where = null, $limit = null, $offset = null) + { + if ($table != '') + { + $this->from($table); + } + + if (!is_null($where)) + { + $this->where($where); + } + + if (!is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->database_compile_select(); + $result = $this->query($sql); + $this->database_reset_select(); + + return $result; + } + + public function insert($table = '', $set = null) + { + if (!is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('database_must_use_set'); + } + + return false; + } + + if ($table == '') + { + if (!isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('database_must_set_table'); + } + + return false; + } + + $table = $this->ar_from[0]; + } + + $sql = $this->database_insert($this->dbprefix . $table, array_keys($this->ar_set), array_values($this->ar_set)); + $this->database_reset_write(); + + return $this->query($sql); + } + + public function update($table = '', $set = null, $where = null) + { + if (!is_null($set)) + { + $this->set($set); + } + + if (count($this->ar_set) == 0) + { + if ($this->db_debug) + { + return $this->display_error('database_must_use_set'); + } + + return false; + } + + if ($table == '') + { + if (!isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('database_must_set_table'); + } + + return false; + } + + $table = $this->ar_from[0]; + } + + if (!is_null($where)) + { + $this->where($where); + } + + $sql = $this->database_update($this->dbprefix . $table, $this->ar_set, $this->ar_where); + $this->database_reset_write(); + + return $this->query($sql); + } + + public function delete($table = '', $where = '') + { + if ($table == '') + { + if (!isset($this->ar_from[0])) + { + if ($this->db_debug) + { + return $this->display_error('database_must_set_table'); + } + + return false; + } + + $table = $this->ar_from[0]; + } + + if ($where != '') + { + $this->where($where); + } + + if (count($this->ar_where) == 0) + { + if ($this->db_debug) + { + return $this->display_error('database_del_must_use_where'); + } + + return false; + } + + $sql = $this->database_delete($this->dbprefix . $table, $this->ar_where); + $this->database_reset_write(); + + return $this->query($sql); + } + + public function database_has_operator($string) + { + $string = trim($string); + + if (!preg_match("/(\s|<|>|!|=|is null|is not null)/i", $string)) + { + return false; + } + + return true; + } + + private function database_compile_select() + { + $sql = (!$this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT '; + $sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select); + + if (count($this->ar_from) > 0) + { + $sql .= "\nFROM "; + $sql .= implode(', ', $this->ar_from); + } + + if (count($this->ar_join) > 0) + { + $sql .= "\n"; + $sql .= implode("\n", $this->ar_join); + } + + if (count($this->ar_where) > 0 || count($this->ar_like) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $this->ar_where); + + if (count($this->ar_like) > 0) + { + if (count($this->ar_where) > 0) + { + $sql .= " AND "; + } + + $sql .= implode("\n", $this->ar_like); + } + + if (count($this->ar_groupby) > 0) + { + $sql .= "\nGROUP BY "; + $sql .= implode(', ', $this->ar_groupby); + } + + if (count($this->ar_having) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $this->ar_having); + } + + if (count($this->ar_orderby) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $this->ar_orderby); + + if ($this->ar_order !== false) + { + $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC'; + } + } + + if (is_numeric($this->ar_limit)) + { + $sql .= "\n"; + $sql = $this->database_limit($sql, $this->ar_limit, $this->ar_offset); + } + + return $sql; + } + + private function database_object_to_array($object) + { + if (!is_object($object)) + { + return $object; + } + + $array = array(); + + foreach (get_object_vars($object) as $key => $val) + { + if (!is_object($val) && !is_array($val)) + { + $array[$key] = $val; + } + } + + return $array; + } + + private function database_reset_select() + { + $this->ar_select = array(); + $this->ar_distinct = false; + $this->ar_from = array(); + $this->ar_join = array(); + $this->ar_where = array(); + $this->ar_like = array(); + $this->ar_groupby = array(); + $this->ar_having = array(); + $this->ar_limit = false; + $this->ar_offset = false; + $this->ar_order = false; + $this->ar_orderby = array(); + } + + private function database_reset_write() + { + $this->ar_set = array(); + $this->ar_from = array(); + $this->ar_where = array(); + } +} + +?> diff --git a/Source/carbon/database/Database_cache.php b/Source/carbon/database/Database_cache.php new file mode 100644 index 0000000..1402272 --- /dev/null +++ b/Source/carbon/database/Database_cache.php @@ -0,0 +1,129 @@ +carbon = get_instance(); + $this->carbon->load->utility('filesystem'); + } + + public function check_path($path = '') + { + if ($path == '') + { + if ($this->carbon->db->cachedir == '') + { + return $this->carbon->db->cache_off(); + } + + $path = $this->carbon->db->cachedir; + } + + $path = preg_replace("/(.+?)\/*$/", "\\1/", $path); + + if (!is_dir($path) || !is_writable($path)) + { + if ($this->carbon->db->db_debug) + { + return $this->carbon->db->display_error('database_invalid_cache_path'); + } + + return $this->carbon->db->cache_off(); + } + + $this->cache->db->cachedir = $path; + + return true; + } + + public function read($sql) + { + if (!$this->check_path()) + { + return $this->carbon->db->cache_off(); + } + + $uri = ($this->carbon->uri->get_segment(1) == false) ? 'default.' : $this->carbon->uri->get_segment(1) . '+'; + $uri .= ($this->carbon->uri->get_segment(2) == false) ? 'index' : $this->carbon->uri->get_segment(2); + + $filepath = $uri . '/' . md5($sql); + + $cachedata = read_file($this->carbon->db->cachedir . $filepath); + + if ($cachedata === false) + { + return false; + } + + return unserialize($cachedata); + } + + public function write($sql, $object) + { + if (!$this->check_path()) + { + return $this->carbon->db->cache_off(); + } + + $uri = ($this->carbon->uri->get_segment(1) == false) ? 'default.' : $this->carbon->uri->get_segment(1) . '+'; + $uri .= ($this->carbon->uri->get_segment(2) == false) ? 'index' : $this->carbon->uri->get_segment(2); + + $dir_path = $this->carbon->db->cachedir . $uri . '/'; + $filename = md5($sql); + + if (!@is_dir($dir_path)) + { + if (!@mkdir($dir_path, 0777)) + { + return false; + } + + @chmod($dir_path, 0777); + } + + if (write_file($dir_path . $filename, serialize($object)) === false) + { + return false; + } + + @chmod($dir_path, $filename, 0777); + + return true; + } + + public function delete($segment_one = '', $segment_two = '') + { + if ($segment_one == '') + { + $segment_one = ($this->carbon->uri->get_segment(1) == false) ? 'default' : $this->carbon->uri->get_segment(2); + } + + if ($segment_two == '') + { + $segment_two = ($this->carbon->uri->get_segment(2) == false) ? 'index' : $this->carbon->uri->get_segment(2); + } + + $dir_path = $this->carbon->db->cachedir . $segment_one . '+' . $segment_two . '/'; + + delete_files($dir_path, true); + } + + public function delete_all() + { + delete_files($this->carbon->db->cachedir, true); + } +} + +?> diff --git a/Source/carbon/database/Database_driver.php b/Source/carbon/database/Database_driver.php new file mode 100644 index 0000000..18d340e --- /dev/null +++ b/Source/carbon/database/Database_driver.php @@ -0,0 +1,714 @@ +initialise($params); + } + + public function initialise($params = '') + { + if (is_array($params)) + { + $defaults = array( + 'hostname' => '', + 'username' => '', + 'password' => '', + 'database' => '', + 'conn_id' => false, + 'dbdriver' => 'mysql', + 'dbprefix' => '', + 'port' => '', + 'pconnect' => false, + 'db_debug' => false, + 'cachedir' => '', + 'cache_on' => false + ); + + foreach ($defaults as $key => $val) + { + $this->$key = (!isset($params[$key])) ? $val : $params[$key]; + } + } + elseif (strpos($params, '://')) + { + $dsn = @parse_url($params); + + if ($dsn === false) + { + log_message('error', 'Invalid database connection string.'); + + if ($this->db_debug) + { + return $this->display_error('database_invalid_connection_str'); + } + + return false; + } + + $this->hostname = (!isset($dsn['host'])) ? '' : rawurldecode($dsn['host']); + $this->username = (!isset($dsn['user'])) ? '' : rawurldecode($dsn['user']); + $this->password = (!isset($dsn['pass'])) ? '' : rawurldecode($dsn['pass']); + $this->database = (!isset($dsn['path'])) ? '' : rawurldecode(substr($dsn['path'], 1)); + } + + if (is_resource($this->conn_id)) + { + return true; + } + + $this->conn_id = ($this->pconnect == false) ? $this->database_connect() : $this->database_pconnect(); + + if (!$this->conn_id) + { + log_message('error', 'Unable to connect to the database server.'); + + if ($this->db_debug) + { + $this->display_error('database_unable_to_connect'); + } + + return false; + } + + if ($this->database != '') + { + if (!$this->database_select()) + { + log_message('error', 'Unable to select database: ' . $this->database); + + if ($this->db_debug) + { + $this->display_error('database_unable_to_select', $this->database); + } + + return false; + } + } + + return true; + } + + public function platform() + { + return $this->dbdriver; + } + + public function version() + { + $sql = $this->database_version(); + + if ($sql === false) + { + if ($this->db_debug) + { + return $this->display_error('database_unsupported_function'); + } + + return false; + } + + if ($this->dbdriver == 'oci8') + { + return $sql; + } + + $query = $this->query($sql); + $row = $query->row(); + + return $row->ver; + } + + public function query($sql, $binds = false, $return_object = true) + { + if ($sql == '') + { + log_message('error', 'Invalid query: ' . $sql); + + if ($this->db_debug) + { + return $this->display_error('database_invalid_query'); + } + + return false; + } + + if ($this->cache_on == true && stristr($sql, 'SELECT')) + { + if ($this->database_cache_init()) + { + $this->load_result_driver(); + $cache = $this->cache->read($sql); + + if ($cache !== false) + { + return $cache; + } + } + } + + if ($binds !== false) + { + $sql = $this->compile_binds($sql, $binds); + } + + $this->queries[] = $sql; + $time_start = list($sm, $ss) = explode(' ', microtime()); + $this->result_id = $this->simple_query($sql); + + if ($this->result_id === false) + { + $this->_trans_status = false; + + log_message('error', 'Query error: ' . $this->database_error_message()); + + if ($this->db_debug) + { + return $this->display_error(array('Error number: ' . $this->database_error_number(), $this->database_error_message(), $sql)); + } + + return false; + } + + $time_end = list($em, $es) = explode(' ', microtime()); + $this->benchmark += ($em + $es) - ($sm + $ss); + $this->query_count++; + + if ($this->is_write_type($sql) === true) + { + if ($this->cache_on == true && $this->cache_autodel == true && $this->database_cache_init()) + { + $this->cache->delete(); + } + + return true; + } + + if ($return_object !== true) + { + return true; + } + + $driver = $this->load_result_driver(); + + $result = new $driver(); + + $result->conn_id = $this->conn_id; + $result->result_id = $this->result_id; + $result->num_rows = $result->num_rows(); + + if ($this->dbdriver == 'oci8') + { + $result->stmt_id = $this->stmt_id; + $result->curs_id = $this->curs_id; + $result->limit_used = $this->limit_used; + } + + if ($this->cache_on == true && $this->database_cache_init()) + { + $cache_result = new Carbon_Database_result(); + + $cache_result->num_rows = $result->num_rows(); + $cache_result->result_object = $result->result_object(); + $cache_result->result_array = $result->result_array(); + + $cache_result->conn_id = null; + $cache_result->result_id = null; + + $this->cache->write($sql, $cache_result); + } + + return $result; + } + + public function load_result_driver() + { + $driver = 'Carbon_Database_' . $this->dbdriver . '_result'; + + if (!class_exists($driver)) + { + include_once(CARBON_PATH . 'database/Database_result' . FILE_EXT); + include_once(CARBON_PATH . 'database/drivers/' . $this->dbdriver . '/' . $this->dbdriver . '_result' . FILE_EXT); + } + + return $driver; + } + + public function simple_query($sql) + { + if (!$this->conn_id) + { + $this->initialise(); + } + + return $this->database_execute($sql); + } + + public function trans_off() + { + $this->trans_enabled = false; + } + + public function trans_start($test_mode = false) + { + if (!$this->trans_enabled) + { + return false; + } + + if ($this->_trans_depth > 0) + { + $this->_trans_depth += 1; + return true; + } + + $this->trans_begin($test_mode); + } + + public function trans_complete() + { + if (!$this->trans_enabled) + { + return false; + } + + if ($this->_trans_depth > 1) + { + $this->_trans_depth -= 1; + return true; + } + + if ($this->_trans_status === false) + { + $this->trans_rollback(); + + if ($this->db_debug) + { + return $this->display_error('database_transaction_failure'); + } + + return false; + } + + $this->trans_commit(); + + return true; + } + + public function trans_status() + { + return $this->_trans_status; + } + + public function compile_binds($sql, $binds) + { + if (strpos($sql, $this->bind_marker) === false) + { + return $sql; + } + + if (!is_array($bind)) + { + $binds = array($binds); + } + + foreach ($binds as $val) + { + $val = $this->escape($val); + $val = str_replace($this->bind_marker, '{%bind_marker%}', $val); + $sql = preg_replace("#" . preg_quote($this->bind_marker, '#') . "#", str_replace('$', '\$', $val), $sql, 1); + } + + return str_replace('{%bind_marker%}', $this->bind_marker, $sql); + } + + public function is_write_type($sql) + { + if (!preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) + { + return false; + } + + return true; + } + + public function elapsed_time($precision = 6) + { + return number_format($this->benchmark, $precision); + } + + public function total_queries() + { + return $this->query_count; + } + + public function last_query() + { + return end($this->queries); + } + + public function escape($string) + { + switch (gettype($string)) + { + case 'string': + $string = "'" . $this->escape_string($string) . "'"; + break; + + case 'boolean': + $string = ($string === false) ? 0 : 1; + break; + + default: + break; + } + + return $string; + } + + public function primary($table = '') + { + $fields = $this->list_fields($table); + + if (!is_array($fields)) + { + return false; + } + + return current($fields); + } + + public function list_tables() + { + if (isset($this->data_cache['table_names'])) + { + return $this->data_cache['table_names']; + } + + $sql = $this->database_list_tables(); + + if ($sql === false) + { + if ($this->db_debug) + { + return $this->display_error('database_unsupported_function'); + } + + return false; + } + + $retval = array(); + $query = $this->query($sql); + + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + if (isset($row['TABLE_NAME'])) + { + $retval[] = $row['TABLE_NAME']; + } + else + { + $retval[] = array_shift($row); + } + } + } + + $this->data_cache['table_names'] = $retval; + + return $this->data_cache['table_names']; + } + + public function table_exist($table_name) + { + return (!in_array($this->dbprefix . $table_name, $this->list_tables())) ? false : true; + } + + public function list_fields($table = '') + { + if (isset($this->data_cache['field_names'][$table])) + { + return $this->data_cache['field_names'][$table]; + } + + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('database_field_param_missing'); + } + + return false; + } + + $sql = $this->database_list_columns($this->dbprefix . $table); + + if ($sql === false) + { + if ($this->db_debug) + { + return $this->display_error('database_unsupported_function'); + } + + return false; + } + + $query = $this->query($sql); + + $retval = array(); + + foreach ($query->result_array() as $row) + { + if (isset($row['COLUMN_NAME'])) + { + $retval[] = $row['COLUMN_NAME']; + } + else + { + $retval[] = current($row); + } + } + + $this->data_cache['field_names'][$table] = $retval; + + return $this->data_cache['field_names'][$table]; + } + + public function field_exists($field_names, $table_name) + { + return (!in_array($field_name, $this->list_fields($table_name))) ? false : true; + } + + public function field_names($table = '') + { + return $this->list_fields($table); + } + + public function field_data($table = '') + { + if ($table == '') + { + if ($this->db_debug) + { + return $this->display_error('database_field_param_missing'); + } + + return false; + } + + $query = $this->query($this->database_field_data($this->dbprefix . $table)); + + return $query->field_data(); + } + + public function insert_string($table, $data) + { + $fields = array(); + $values = array(); + + foreach ($data as $key => $val) + { + $fields[] = $key; + $values[] = $this->escape($val); + } + + return $this->database_insert($this->dbprefix . $table, $fields, $values); + } + + public function update_string($table, $data, $where) + { + if ($where == '') + { + return false; + } + + $fields = array(); + + foreach ($data as $key => $val) + { + $fields[$key] = $this->escape($val); + } + + if (!is_array($where)) + { + $dest = array($where); + } + else + { + $dest = array(); + + foreach ($where as $key => $val) + { + $prefix = (count($dest) == 0) ? '' : ' AND '; + + if ($val != '') + { + if (!$this->database_has_operator($key)) + { + $key .= ' ='; + } + + $val = ' ' . $this->escape($val); + } + + $dest[] = $prefix . $key . $val; + } + } + + return $this->database_update($this->dbprefix . $table, $fields, $dest); + } + + public function call_function($function) + { + $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver . '_'; + + if (strpos($driver, $function) === false) + { + $function = $driver . $function; + } + + if (!function_exists($function)) + { + if ($this->db_debug) + { + return $this->display_error('database_unsupported_function'); + } + + return false; + } + else + { + $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null; + + return call_user_func_array($function, $args); + } + } + + public function cache_set_path($path = '') + { + $this->cachedir = $path; + } + + public function cache_on() + { + $this->cache_on = true; + + return true; + } + + public function cache_off() + { + $this->cache_on = false; + + return false; + } + + public function cache_delete($segment_one = '', $segment_two = '') + { + if (!$this->_cache_init()) + { + return false; + } + + return $this->cache->delete($segment_one, $segment_two); + } + + public function cache_delete_all() + { + if (!$this->_cache_init()) + { + return false; + } + + return $this->cache->delete_all(); + } + + public function database_cache_init() + { + if (is_object($this->cache) && class_exists('Carbon_Database_Cache')) + { + return true; + } + + if (!@include(CARBON_PATH . 'database/Database_cache' . FILE_EXT)) + { + return $this->cache_off(); + } + + $this->cache = new Carbon_Database_Cache; + + return true; + } + + public function close() + { + if (is_resource($this->conn_id)) + { + $this->database_close($this->conn_id); + } + + $this->conn_id = false; + } + + public function display_error($error = '', $swap = '', $native = false) + { + $lang = load_class('Language'); + $lang->load('database'); + + if ($native == true) + { + $message = $error; + } + else + { + $message = (!is_array($error)) ? array(str_replace('%s', $swap, $lang->line($error))) : $error; + } + + $error = load_class('Exception'); + echo $error->display_error('An error has been encountered', $message, 'error_database'); + exit(); + } +} + +?> diff --git a/Source/carbon/database/Database_result.php b/Source/carbon/database/Database_result.php new file mode 100644 index 0000000..e64c716 --- /dev/null +++ b/Source/carbon/database/Database_result.php @@ -0,0 +1,208 @@ +result_object() : $this->result_array(); + } + + public function result_object() + { + if (count($this->result_object) > 0) + { + return $this->result_object; + } + + if ($this->result_id === false || $this->num_rows() == 0) + { + return array(); + } + + $this->database_data_seek(0); + + while($row = $this->database_fetch_object()) + { + $this->result_object[] = $row; + } + + return $this->result_object; + } + + public function result_array() + { + if (count($this->result_array) > 0) + { + return $this->result_array; + } + + if ($this->result_id === false || $this->num_rows() == 0) + { + return array(); + } + + $this->database_data_seek(0); + + while ($row = $this->database_fetch_assoc()) + { + $this->result_array[] = $row; + } + + return $this->result_array; + } + + public function row($index = 0, $type = 'object') + { + return ($type == 'object') ? $this->row_object($index) : $this->row_array($index); + } + + public function row_object($index = 0) + { + $result = $this->result_object(); + + if (count($result) == 0) + { + return $result; + } + + if ($index != $this->current_row && isset($result[$index])) + { + $this->current_row = $index; + } + + return $result[$this->current_row]; + } + + public function row_array($index = 0) + { + $result = $this->result_array(); + + if (count($result) == 0) + { + return $result; + } + + if ($index != $this->current_row && isset($result[$index])) + { + $this->current_row = $index; + } + + return $result[$this->current_row]; + } + + public function first_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + return $result[0]; + } + + public function last_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + return $result[count($result) - 1]; + } + + public function next_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row + 1])) + { + $this->current_row++; + } + + return $result[$this->current_row]; + } + + public function previous_row($type = 'object') + { + $result = $this->result($type); + + if (count($result) == 0) + { + return $result; + } + + if (isset($result[$this->current_row - 1])) + { + $this->current_row--; + } + + return $result[$this->current_row]; + } + + public function num_rows() + { + return $this->num_rows; + } + + public function num_fields() + { + return 0; + } + + public function list_fields() + { + return array(); + } + + public function field_data() + { + return array(); + } + + public function free_result() + { + return true; + } + + public function database_data_seek() + { + return true; + } + + public function database_fetch_assoc() + { + return array(); + } + + public function database_fetch_object() + { + return array(); + } +} + +?> diff --git a/Source/carbon/database/Database_utility.php b/Source/carbon/database/Database_utility.php new file mode 100644 index 0000000..56bda75 --- /dev/null +++ b/Source/carbon/database/Database_utility.php @@ -0,0 +1,296 @@ +db = $carbon->db; + } + + public function create_database($db_name) + { + $sql = $this->database_create_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + public function drop_database($db_name) + { + $sql = $this->database_drop_database($db_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + public function list_databases() + { + if (isset($this->data_cache['db_names'])) + { + return $this->data_cache['db_names']; + } + + $query = $this->db->query($this->database_list_databases()); + $dbs = array(); + + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $dbs[] = current($row); + } + } + + $this->data_cache['db_names'] = $dbs; + + return $this->data_cache['db_names']; + } + + public function optimize_table($table_name) + { + $sql = $this->database_optimize_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + $result = $query->result_array(); + + return current($result); + } + + public function optimize_database() + { + $result = array(); + + foreach ($this->db->list_tables() as $table_name); + { + $sql = $this->database_optimize_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $query = $this->db->query($sql); + + $res = $query->result_array(); + $res = current($res); + $key = str_replace($this->db->database . '.', '', current($res)); + $keys = array_keys($res); + unset($res[$keys[0]]); + + $result[$key] = $result; + } + + return $results; + } + + public function repair_table($table_name) + { + $sql = $this->database_repair_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + $sql = $this->db->query($sql); + + $result = $query->result_array(); + return current($result); + } + + public function drop_table($table_name) + { + $sql = $this->database_drop_table($table_name); + + if (is_bool($sql)) + { + return $sql; + } + + return $this->db->query($sql); + } + + public function csv_from_result($query, $delim = "\t", $newline = "\n") + { + if (!is_object($query) || !method_exists($query, 'field_data')) + { + display_error('You must supply a valid result object'); + } + + $output = ''; + + foreach ($query->list_fields() as $name) + { + $output .= $name . $delim; + } + + $output = rtrim($output); + $output .= $newline; + + foreach ($query->result_array() as $row) + { + foreach ($row as $item) + { + $output .= $item . $delim; + } + + $output = rtrim($output); + $output .= $newline; + } + + return $output; + } + + public function xml_from_result($query, $params = array()) + { + if (!is_object($query) || !method_exists($query, 'field_data')) + { + display_error('You must supply a valid result object'); + } + + foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val) + { + if (!isset($params[$key])) + { + $params[$key] = $val; + } + } + + extract($params); + + $carbon = get_instance(); + $carbon->load->utility('xml'); + + $xml = "<{$root}>" . $newline; + + foreach ($query->result_array() as $row) + { + $xml .= $tab . "<{$element}>" . $newline; + + foreach ($row as $key => $val) + { + $xml .= $tab . $tab . "<{$key}>" . xml_entities($val) . "" . $newline; + } + + $xml .= $tab . "" . $newline; + } + + $xml .= "" . $newline; + + return $xml; + } + + public function backup($params = array()) + { + if (is_string($params)) + { + $params = array('table' => $params); + } + + $prefs = array( + 'tables' => array(), + 'ignore' => array(), + 'filename' => '', + 'format' => 'gzip', + 'add_drop' => true, + 'add_insert' => true, + 'newline' => "\n" + ); + + if (count($params) > 0) + { + foreach ($prefs as $key => $val) + { + if (isset($params[$key])) + { + $prefs[$key] = $params[$key]; + } + } + } + + if (count($prefs['tables']) == 0) + { + $prefs['tables'] = $this->db->list_tables(); + } + + if (!in_array($prefs['format'], array('gzip', 'zip', 'txt'), true)) + { + $prefs['format'] = 'txt'; + } + + if (($prefs['format'] == 'gzip' && !@function_exists('gzencode')) || ($prefs['format'] == 'zip' && !@function_exists('gzcompress'))) + { + if ($this->db->db_debug) + { + return $this->db->display_error('database_unsupported_compression'); + } + + $prefs['format'] = 'txt'; + } + + if ($prefs['filename'] == '' && $prefs['format'] == 'zip') + { + $prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database; + $prefs['filename'] .= '_' . date('Y-m-d_H-i', time()); + } + + if ($prefs['format'] == 'gzip') + { + return gzencode($this->database_backup($prefs)); + } + + if ($prefs['format'] == 'txt') + { + return $this->database_backup($prefs); + } + + if ($prefs['format'] == 'zip') + { + if (preg_match("|.+?\.zip$|", $prefs['filename'])) + { + $prefs['filename'] = str_replace('.zip', '', $prefs['filename']); + } + + if (!preg_match("|.+?\.sql$|", $prefs['filename'])) + { + $prefs['filename'] .= '.sql'; + } + + $carbon = get_instance(); + $carbon->load->library('zip'); + $carbon->zip->add_data($prefs['filename'], $this->database_backup($prefs)); + + return $carbon->zip->get_zip(); + } + } +} + +?> diff --git a/Source/carbon/database/drivers/mssql/mssql_driver.php b/Source/carbon/database/drivers/mssql/mssql_driver.php new file mode 100644 index 0000000..c2c2217 --- /dev/null +++ b/Source/carbon/database/drivers/mssql/mssql_driver.php @@ -0,0 +1,199 @@ +hostname, $this->username, $this->password); + } + + public function database_pconnect() + { + return @mssql_pconnect($this->hostname, $this->username, $this->password); + } + + public function database_select() + { + return @mssql_select_db($this->database, $this->conn_id); + } + + public function database_version() + { + return "SELECT @@VERSION AS ver"; + } + + public function database_execute($sql) + { + $sql = $this->database_prep_query($sql); + return @mssql_query($sql, $this->conn_id); + } + + public function database_prep_query($sql) + { + return $sql; + } + + public function trans_begin($test_mode = false) + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->_trans_failure = ($test_mode === true) ? true : false; + $this->simple_query('BEGIN TRAN'); + return true; + } + + public function trans_commit() + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->simple_query('COMMIT TRAN'); + return true; + } + + public function trans_rollback() + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->simple_query('ROLLBACK TRAN'); + return true; + } + + public function escape_string($string) + { + return str_replace("'", "''", $string); + } + + public function affected_rows() + { + return @mssql_row_affected($this->conn_id); + } + + public function insert_id() + { + $ver = self::database_parse_major_version($this->database_version()); + $sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id"); + $query = $this->query($sql); + $row = $query->row(); + return $row->last_id; + } + + private function database_parse_major_version($version) + { + preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info); + return $ver_info[1]; + } + + public function count_all($table = '') + { + if ($table == '') + { + return '0'; + } + + $query = $this->query('SELECT COUNT(*) AS numrows FROM ' . $this->dbprefix . $table); + + if ($query->num_rows() == 0) + { + return '0'; + } + + $row = $query->row(); + return $row->numrows; + } + + public function database_list_tables() + { + return 'SELECT name FROM sysobjects WHERE type = \'U\' ORDER BY name'; + } + + public function database_list_columns($table = '') + { + return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '" . $this->database_escape_table($table) . "'"; + } + + public function database_field_data($table) + { + 'SELECT TOP 1 * FROM ' . $this->database_escape_table($table); + } + + public function database_error_message() + { + return ''; + } + + public function database_error_number() + { + return ''; + } + + public function database_escape_table($table) + { + return $table; + } + + public function database_insert($table, $keys, $values) + { + return "INSERT INTO " . $this->database_escape_table($table) . " (" . implode(', ', $key) . ") VALUES (" . implode(', ', $values) . ")"; + } + + public function database_update($table, $values, $where) + { + foreach($values as $key => $val) + { + $valstr[] = $key . " = " . $val; + } + + return "UPDATE " . $this->database_escape_table($table) . " SET " . implode(', ', $valstr) . " WHERE " . implode(" ", $where); + } + + public function database_delete($table, $where) + { + return "DELETE FROM " . $this->database_escape_table($table) . " WHERE " . implode(" ", $where); + } + + public function database_limit($sql, $limit, $offset) + { + $i = $limit + $offset; + return preg_replace('/(^\SELECT (DISTINCT)?)/i', '\\1 TOP ' . $i . ' ' . $sql); + } + + public function database_close($conn_id) + { + @mssql_close($conn_id); + } +} + +?> diff --git a/Source/carbon/database/drivers/mssql/mssql_result.php b/Source/carbon/database/drivers/mssql/mssql_result.php new file mode 100644 index 0000000..bad6bb4 --- /dev/null +++ b/Source/carbon/database/drivers/mssql/mssql_result.php @@ -0,0 +1,80 @@ +result_id); + } + + public num_fields() + { + return @mssql_num_fields($this->result_id); + } + + public list_fields() + { + $field_names = array(); + + while ($field = mssql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + public function field_data() + { + $retval = array(); + + while ($field = mssql_fetch_field($this->result_id)) + { + $f = new stdClass(); + $f->name = $field->name; + $f->type = $field->type; + $f->max_length = $field->max_length; + $f->primary_key = 0; + $f->default = ''; + + $retval[] = $f; + } + + return $retval; + } + + public free_result() + { + if (is_resource($this->result_id)) + { + mssql_free_result($this->result_id); + $this->result_id = false; + } + } + + public database_data_seek($index = 0) + { + return mssql_data_seek($this->result_id, $index); + } + + public database_fetch_assoc() + { + return mssql_fetch_assoc($this->result_id); + } + + public database_fetch_object() + { + return mssql_fetch_object($this->result_id); + } +} + +?> diff --git a/Source/carbon/database/drivers/mssql/mssql_utility.php b/Source/carbon/database/drivers/mssql/mssql_utility.php new file mode 100644 index 0000000..4f1a21f --- /dev/null +++ b/Source/carbon/database/drivers/mssql/mssql_utility.php @@ -0,0 +1,50 @@ +db->database_escape_table($table); + } + + public function database_list_databases() + { + return "EXEC sp_databases"; + } + + public function database_optimise_table($table) + { + return false; + } + + public function database_repair_table($table) + { + return false; + } + + public function database_backup($params = array()) + { + return $this->db->display_error('db_unsupported_feature'); + } +} + +?> diff --git a/Source/carbon/database/drivers/mysql/mysql_driver.php b/Source/carbon/database/drivers/mysql/mysql_driver.php new file mode 100644 index 0000000..91b3da5 --- /dev/null +++ b/Source/carbon/database/drivers/mysql/mysql_driver.php @@ -0,0 +1,226 @@ +hostname, $this->username, $this->password, true); + } + + public function database_pconnect() + { + return @mysql_pconnect($this->hostname, $this->username, $this->password); + } + + public function database_select() + { + return @mysql_select_db($this->database, $this->conn_id); + } + + public function database_version() + { + return "SELECT version() AS ver"; + } + + public function database_execute($sql) + { + $sql = $this->database_prep_query($sql); + return @mysql_query($sql, $this->conn_id); + } + + public function database_prep_query($sql) + { + if ($this->delete_hack === true) + { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql); + } + } + + return $sql; + } + + public function trans_begin($test_mode = false) + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->_trans_failure = ($test_mode === true) ? true : false; + + $this->simple_query('SET AUTOCOMMIT=0'); + $this->simple_query('START TRANSACTION'); + return true; + } + + public function trans_commit() + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->simple_query('COMMIT'); + $this->simple_query('SET AUTOCOMMIT=1'); + return true; + } + + public function trans_rollback() + { + if (!$this->trans_enabled) + { + return true; + } + + if ($this->_trans_depth > 0) + { + return true; + } + + $this->simple_query('ROLLBACK'); + $this->simple_query('SET AUTOCOMMIT=1'); + } + + public function escape_string($string) + { + if (function_exists('mysql_real_escape_string')) + { + return mysql_real_escape_string($string, $this->conn_id); + } + elseif (function_exists('mysql_escape_string')) + { + return mysql_escape_string($string); + } + else + { + return addslashes($string); + } + } + + public function affected_rows() + { + return @mysql_affected_rows($this->conn_id); + } + + public function insert_id() + { + return @mysql_insert_id($this->conn_id); + } + + public function count_all($table = '') + { + if ($table == '') + { + return '0'; + } + + $query = $this->query("SELECT COUNT(*) AS numrows FROM `" . $this->dbprefix . $table . "`"); + + if ($query->num_rows() == 0) + { + return '0'; + } + + $row = $query->row(); + return $row->numrows; + } + + public function database_list_tables() + { + return "SHOW TABLES FROM `" . $this->database . "`"; + } + + public function database_list_columns($table = '') + { + return "SHOW COLUMNS FROM " . $this->database_escape_table($table); + } + + public function database_field_data($table) + { + return "SELECT * FROM " . $this->database_escape_table($table) . " LIMIT 1"; + } + + public function database_error_message() + { + return mysql_error($this->conn_id); + } + + public function database_error_number() + { + return mysql_errno($this->conn_id); + } + + public function database_escape_table($table) + { + if (stristr($table, '.')) + { + $table = preg_replace("/\./", "`.`", $table); + } + + return $table; + } + + public function database_insert($table, $key, $values) + { + return "INSERT INTO " . $this->database_escape_table($table) . " (" . implode(', ', $key) . ") VALUES (" . implode(', ', $values) . ")"; + } + + public function database_update($table, $values, $where) + { + foreach($values as $key => $val) + { + $valstr[] = $key . " = " . $val; + } + + return "UPDATE " . $this->database_escape_table($table) . " SET " . implode(', ', $valstr) . " WHERE " . implode(" ", $where); + } + + public function database_delete($table, $where) + { + return "DELETE FROM " . $this->database_escape_table($table) . " WHERE " . implode(" ", $where); + } + + public function database_limit($sql, $limit, $offset) + { + if ($offset == 0) + { + $offset = ''; + } + else + { + $offset .= ", "; + } + + return $sql . "LIMIT " . $offset . $limit; + } + + public function database_close($conn_id) + { + @mysql_close($conn_id); + } +} + +?> diff --git a/Source/carbon/database/drivers/mysql/mysql_result.php b/Source/carbon/database/drivers/mysql/mysql_result.php new file mode 100644 index 0000000..ee5f4c4 --- /dev/null +++ b/Source/carbon/database/drivers/mysql/mysql_result.php @@ -0,0 +1,80 @@ +result_id); + } + + public function num_fields() + { + return @mysql_num_fields($this->result_id); + } + + public function list_fields() + { + $field_names = array(); + + while ($field = mysql_fetch_field($this->result_id)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + public function field_data() + { + $retval = array(); + + while ($field = mysql_fetch_field($this->result_id)) + { + $f = new stdClass(); + $f->name = $field->name; + $f->type = $field->type; + $f->default = $field->def; + $f->max_length = $field->max_length; + $f->primary_key = $field->primary_key; + + $retval[] = $f; + } + + return $retval; + } + + public function free_result() + { + if (is_resource($this->result_id)) + { + mysql_free_result($this->result_id); + $this->result_id = false; + } + } + + public function database_data_seek($index = 0) + { + return mysql_data_seek($this->result_id, $index); + } + + public function database_fetch_assoc() + { + return mysql_fetch_assoc($this->result_id); + } + + public function database_fetch_object() + { + return mysql_fetch_object($this->result_id); + } +} + +?> diff --git a/Source/carbon/database/drivers/mysql/mysql_utility.php b/Source/carbon/database/drivers/mysql/mysql_utility.php new file mode 100644 index 0000000..7600b23 --- /dev/null +++ b/Source/carbon/database/drivers/mysql/mysql_utility.php @@ -0,0 +1,143 @@ +db->database_escape_table($table); + } + + public function database_optimise_table($table) + { + return 'OPTIMIZE TABLE ' . $this->db->database_escape_table($table); + } + + public function database_repair_table($table) + { + return 'REPAIR TABLE ' . $this->db->database_escape_table($table); + } + + public function database_backup($params = array()) + { + if (count($params) == 0) + { + return false; + } + + extract($params); + + $output = ''; + + foreach ((array) $tables as $table) + { + if (in_array($table, (array) $ignore, true)) + { + continue; + } + + $query = $this->db->query("SHOW CREATE TABLE `" . $this->db->database . "`." . $table); + + if ($query === false) + { + continue; + } + + $output .= '#' . $newline . '# TABLE STRUCTURE FOR: ' . $table . $newline . '#' . $newline . $newline; + + if ($add_drop == true) + { + $output .= 'DROP TABLE IF EXISTS ' . $table . ';' . $newline . $newline; + } + + $i = 0; + $result = $query->result_array(); + + foreach ($result[0] as $val) + { + if ($i++ % 2) + { + $output .= $val . ';' . $newline . $newline; + } + } + + if ($add_insert == false) + { + continue; + } + + $query = $this->db->query("SELECT * FROM $table"); + + if ($query->num_rows() == 0) + { + continue; + } + + $i = 0; + $field_string = ''; + $is_int = array(); + + while ($field = mysql_fetch_field($query->result_id)) + { + $is_int[$i] = (in_array(strtolower(mysql_field_type($query->result_id, $i)), array('tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'timestamp'), true)) ? true : false; + $field_string .= $field->name . ', '; + $i++; + } + + $field_string = preg_replace("/, $/", "", $field_string); + + foreach ($query->result_array() as $row) + { + $value_string = ''; + $i = 0; + + foreach ($row as $value) + { + $value = str_replace(array("\x00", "\x0a", "\x0d", "\x1a"), array('\0', '\n', '\r', '\Z'), $value); + $value = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $value); + $value = str_replace('\\', '\\\\', $value); + $value = str_replace('\'', '\\\'', $value); + $value = str_replace('\\\n', '\n', $value); + $value = str_replace('\\\r', '\r', $value); + $value = str_replace('\\\t', '\t', $value); + + $value_string .= ($is_int[$i] == false) ? $this->db->escape($value) : $value; + $value_string .= ', '; + $i++; + } + + $value_string = preg_replace("/, $/", "", $value_string); + $output .= 'INSERT INTO ' . $table . ' (' . $field_string . ') VALUES (' . $value_string . ');' . $newline; + } + + $output .= $newline . $newline; + } + + return $output; + } +} + +?> diff --git a/Source/carbon/languages/english/database_lang.php b/Source/carbon/languages/english/database_lang.php new file mode 100644 index 0000000..0e68ae5 --- /dev/null +++ b/Source/carbon/languages/english/database_lang.php @@ -0,0 +1,30 @@ + diff --git a/Source/carbon/languages/english/scaffolding_lang.php b/Source/carbon/languages/english/scaffolding_lang.php new file mode 100644 index 0000000..b7fa93e --- /dev/null +++ b/Source/carbon/languages/english/scaffolding_lang.php @@ -0,0 +1,24 @@ + diff --git a/Source/carbon/libraries/Benchmark.php b/Source/carbon/libraries/Benchmark.php new file mode 100644 index 0000000..eb1bcad --- /dev/null +++ b/Source/carbon/libraries/Benchmark.php @@ -0,0 +1,55 @@ +marker[$mark] = microtime(); + } + + public function elapsed_time($point1 = '', $point2 = '', $precision = 4) + { + if ($point1 == '') + { + return '{elapsed_time}'; + } + + if (!isset($this->marker[$point1])) + { + return ''; + } + + if (!isset($this->marker[$point2])) + { + $this->marker[$point2] = microtime(); + } + + list($sm, $ss) = explode(' ', $this->marker[$point1]); + list($em, $es) = explode(' ', $this->marker[$point2]); + + return number_format(($em + $es) - ($sm + $ss), $precision); + } + + public function memory_usage() + { + return '{memory_usage}'; + } +} + +?> diff --git a/Source/carbon/libraries/Config.php b/Source/carbon/libraries/Config.php new file mode 100644 index 0000000..d60bf4f --- /dev/null +++ b/Source/carbon/libraries/Config.php @@ -0,0 +1,158 @@ +config_files = load_config(); + + log_message('debug', 'Config class initialised'); + } + + public function load($file_name = '', $use_sections = false, $fail_gracefully = false) + { + if (in_array($file_name, $this->is_loaded, true)) + { + return true; + } + + if (!file_exists(APP_PATH . 'config' . $file_name . FILE_EXT)) + { + if ($fail_gracefully === true) + { + return false; + } + + display_error('The configuration file ' . $file_name . FILE_EXT . ' does not exist.'); + } + + require_once(APP_PATH . 'config/' . $file_name . FILE_EXT); + + if (!isset($config) || is_array($config)) + { + if ($fail_gracefully === true) + { + return false; + } + + display_error('The configuration file ' . $file_name . FILE_EXT . ' does not appear to contain a valid configuration array.'); + } + + if ($use_sections === true) + { + if (isset($this->config_files[$file_name])) + { + $this->config_files[$file_name] = array_merge($this->config_files[$file_name], $config); + } + else + { + $this->config_files[$file_name] = $config; + } + } + else + { + $this->config_files = array_merge($this->config_files, $config); + } + + $this->is_loaded[] = $file_name; + unset($config); + + log_message('debug', 'Config file loaded: config/' . $file_name . FILE_EXT); + + return true; + } + + public function get_config_value($config_item, $index = '') + { + if ($index == '') + { + if (!isset($this->config_files[$config_item])) + { + return false; + } + + $pref = $this->config_files[$config_item]; + } + else + { + if (!isset($this->config_files[$index])) + { + return false; + } + + if (!isset($this->config_files[$index][$config_item])) + { + return false; + } + + $pref = $this->config_files[$index][$config_item]; + } + + return $pref; + } + + public function slash_config_item($config_item) + { + if (!isset($this->config_files[$config_item])) + { + return false; + } + + $pref = $this->config_files[$config_item]; + + if ($pref != '') + { + if (ereg("/$", $pref) === false) + { + $pref .= '/'; + } + } + + return $pref; + } + + public function get_site_url($uri = '') + { + if (is_array($uri)) + { + $uri = implode('/', $uri); + } + + if ($uri == '') + { + return $this->slash_config_item('carbon_url') . $this->get_config_value('url_postfix'); + } + else + { + $postfix = ($this->get_config_value('url_postfix') == false) ? '' : $this->get_config_value('url_postfix'); + + return $this->slash_config_item('carbon_url') . $this->slash_config_item('index_page') . preg_replace("|^/*(.+?)/*$|", "\\1", $uri) . $postfix; + } + } + + public function get_system_url() + { + $x = explode('/', preg_replace("|^/*(.+?)/*$|", "\\1", CARBON_PATH)); + + return $this->slash_config_item('carbon_url') . end($x) . '/'; + } + + public function set_config_item($config_item, $item_value) + { + $this->config_files[$config_item] = $item_value; + } +} + +?> diff --git a/Source/carbon/libraries/Controller.php b/Source/carbon/libraries/Controller.php new file mode 100644 index 0000000..016eec1 --- /dev/null +++ b/Source/carbon/libraries/Controller.php @@ -0,0 +1,71 @@ +c_initialise(); + + log_message('debug', 'Controller class initialised.'); + } + + private function c_initialise() + { + $classes = array( + 'config' => 'Config', + 'input' => 'Input', + 'benchmark' => 'Benchmark', + 'uri' => 'Uri', + 'lang' => 'Language', + 'output' => 'Output' + ); + + foreach ($classes as $class => $class_name) + { + $this->$class = load_class($class_name); + } + + $this->load = load_class('Loader'); + $this->load->autoloader(); + } + + public function c_scaffolding() + { + if ($this->c_scaffolding === false || $this->c_scaff_table === false) + { + display_not_found('Scaffolding not available'); + } + + $method = (!in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), true)) ? 'view' : $this->uri->segment(3); + + require_once(CARBON_PATH . 'scaffolding/Scaffolding' . FILE_EXT); + + $scaffold = new Scaffolding($this->c_scaff_table); + $scaffold->$method(); + } + + public function set_scaffolding($scaffolding) + { + $this->c_scaffolding = $scaffolding; + } + + public function set_scaff_table($scaff_table) + { + $this->c_scaff_table = $scaff_table; + } +} + +?> diff --git a/Source/carbon/libraries/Exception.php b/Source/carbon/libraries/Exception.php new file mode 100644 index 0000000..c5a0c90 --- /dev/null +++ b/Source/carbon/libraries/Exception.php @@ -0,0 +1,97 @@ + 'Error', + E_WARNING => 'Warning', + E_PARSE => 'Parsing error', + E_NOTICE => 'Notice', + E_CORE_ERROR => 'Core error', + E_CORE_WARNING => 'Core warning', + E_COMPILE_ERROR => 'Compile error', + E_COMPILE_WARNING => 'Compile warning', + E_USER_ERROR => 'User error', + E_USER_WARNING => 'User warning', + E_USER_NOTICE => 'User notice', + E_STRICT => 'Runtime notice' + ); + + private $exc_action; + private $exc_severity; + private $exc_message; + private $exc_ob_level; + + public function __construct() + { + $this->exc_ob_level = ob_get_level(); + } + + public function log_exception($severity, $message, $file_path, $line_number) + { + $severity = (!isset($this->exc_levels[$severity])) ? $severity : $this->exc_levels[$severity]; + log_message('error', 'Severity: ' . $severity. ' -> ' . $message . ' ' . $file_path . ' ' . $line_number, true); + } + + public function display_not_found($page = '') + { + $page_heading = '404: Page Not Found'; + $page_message = 'The page you have requested could not be found.'; + log_message('error', '404 page not found -> ' . $page); + echo $this->display_error($page_heading, $page_message, 'error_404'); + exit(); + } + + public function display_error($heading, $message, $template = 'error') + { + $message = '

' . implode('

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

'; + + if (ob_get_level() > $this->exc_ob_level + 1) + { + ob_end_flush(); + } + + ob_start(); + include(APP_PATH . 'errors/' . $template . FILE_EXT); + $buffer = ob_get_contents(); + ob_end_clean(); + + return $buffer; + } + + public function display_php_error($severity, $message, $file_path, $line_number) + { + $severity = (!isset($this->exc_levels[$severity])) ? $severity : $this->exc_levels[$severity]; + $file_path = str_replace('\\', '/', $file_path); + + if (!strpos($file_path, '/')) + { + $x = explode('/', $file_path); + $file_path = $x[count($x) - 2] . '/' . end($x); + } + + if (ob_get_level() > $this->exc_ob_level + 1) + { + ob_end_flush(); + } + + ob_start(); + + include(APP_PATH . 'errors/error_php' . FILE_EXT); + + $buffer = ob_get_contents(); + ob_end_clean(); + echo $buffer; + } +} + +?> diff --git a/Source/carbon/libraries/Extensions.php b/Source/carbon/libraries/Extensions.php new file mode 100644 index 0000000..4b3e4bf --- /dev/null +++ b/Source/carbon/libraries/Extensions.php @@ -0,0 +1,143 @@ +c_initialise(); + + log_message('debug', 'Extensions class initialised.'); + } + + private function c_initialise() + { + $config = load_class('Config'); + + if ($config->get_config_value('enable_extensions') == false) + { + return false; + } + + @include(APP_PATH . 'config/extensions' . FILE_EXT); + + if (!isset($extension) || !is_array($extension)) + { + return false; + } + + $this->extensions = $extension; + $this->extensions_enabled = true; + } + + public function c_call_extension($which = '') + { + if (!$this->extensions_enabled || !isset($this->extenions[$which])) + { + return false; + } + + if (isset($this->extensions[$which][0]) && is_array($this->extensions[$which][0])) + { + foreach ($this->extensions[$which] as $val) + { + $this->c_run_extension($val); + } + } + else + { + $this->c_run_extension($this->extensions[$which]); + } + + return true; + } + + private function c_run_extension($data) + { + if (!is_array($data)) + { + return false; + } + + if ($this->in_progress == true) + { + return true; + } + + if (!isset($data['filepath']) || !isset($data['filename'])) + { + return false; + } + + $filepath = APP_PATH . $data['filepath'] . '/' . $data['filename']; + + if (!file_exists($filepath)) + { + return false; + } + + $class = false; + $method = false; + $params = ''; + + if (isset($data['class']) && $data['class'] != '') + { + $class = $data['class']; + } + + if (isset($data['method'])) + { + $method = $data['method']; + } + + if (isset($data['params'])) + { + $params = $data['params']; + } + + if ($class === false && $method === false) + { + return false; + } + + $this->in_progess = true; + + if ($class !== false) + { + if (!class_exists($class)) + { + require($filepath); + } + + $ext = new $class; + $ext->$method($params); + } + else + { + if (!function_exists($method)) + { + require($filepath); + } + + $method($params); + } + + $this->in_progress = false; + + return true; + } +} + +?> diff --git a/Source/carbon/libraries/Input.php b/Source/carbon/libraries/Input.php new file mode 100644 index 0000000..0ea9258 --- /dev/null +++ b/Source/carbon/libraries/Input.php @@ -0,0 +1,524 @@ +use_xss_clean = ($config->get_config_value('use_xss_filtering') === true) ? true : false; + $this->allow_get_array = ($config->get_config_value('use_query_strings') === true) ? true : false; + + $this->c_sanitise_globals(); + } + + private function c_sanitise_globals() + { + $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA'); + + foreach (array($_GET, $_POST, $_COOKIE) as $global) + { + if (!is_array($global)) + { + if (!in_array($global, $protected)) + { + global $global; + $$global = null; + } + } + else + { + foreach ($global as $key => $val) + { + if (!in_array($key, $protected)) + { + global $$key; + $$key = null; + } + } + } + } + + if ($this->allow_get_array == false) + { + $_GET = array(); + } + else + { + if (is_array($_GET) && count($_GET) > 0) + { + foreach ($_GET as $key => $val) + { + $_GET[$this->c_clean_input_keys($key)] = $this->c_clean_input_data($val); + } + } + } + + if (is_array($_POST) && count($_POST) > 0) + { + foreach ($_POST as $key => $val) + { + $_POST[$this->c_clean_input_keys($key)] = $this->c_clean_input_data($val); + } + } + + if (is_array($_COOKIE) && count($_COOKIE) > 0) + { + foreach ($_COOKIE as $key => $val) + { + $_COOKIE[$this->c_clean_input_keys($key)] = $this->c_clean_input_data($val); + } + } + + log_message('debug', 'Global POST and COOKIE arrays have been sanitised.'); + } + + private function c_clean_input_data($string) + { + if (is_array($string)) + { + $new_array = array(); + + foreach ($string as $key => $val) + { + $new_array[$this->c_clean_input_keys($key)] = $this->c_clean_input_data($val); + } + + return $new_array; + } + + if (get_magic_quotes_gpc()) + { + $string = stripslashes($string); + } + + if ($this->use_xss_clean === true) + { + $string = $this->xss_clean($string); + } + + return preg_replace("/\015\012|\015|\012/", "\n", $string); + } + + private function c_clean_input_keys($string) + { + if (!preg_match("/^[a-z0-9:_\/-]+$/i", $string)) + { + exit('Disallowed characters in the array key.'); + } + + return $string; + } + + public function get($index = '', $xss_clean = false) + { + if (!isset($_GET[$index])) + { + return false; + } + + if ($xss_clean === true) + { + if (is_array($_GET[$index])) + { + foreach ($_GET[$index] as $key => $val) + { + $_GET[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_GET[$index]); + } + } + + return $_GET[$index]; + } + + public function post($index = '', $xss_clean = false) + { + if (!isset($_POST[$index])) + { + return false; + } + + if ($xss_clean === true) + { + if (is_array($_POST[$index])) + { + foreach ($_POST[$index] as $key => $val) + { + $_POST[$index][$key] = $this->xss_clean($val); + } + } + else + { + return $this->xss_clean($_POST[$index]); + } + } + + return $_POST[$index]; + } + + public function cookie($index = '', $xss_clean = false) + { + if (!isset($_COOKIE[$index])) + { + return false; + } + + if ($xss_clean === true) + { + if (is_array($_COOKIE[$index])) + { + $cookie = array(); + + foreach ($_COOKIE[$index] as $key => $val) + { + $cookie[$key] = $this->xss_clean($val); + } + + return $cookie; + } + else + { + return $this->xss_clean($_COOKIE[$index]); + } + } + else + { + return $_COOKIE[$index]; + } + } + + public function server($index = '', $xss_clean = false) + { + if (!isset($_SERVER[$index])) + { + return false; + } + + if ($xss_clean === true) + { + return $this->xss_clean($_SERVER[$index]); + } + + return $_SERVER[$index]; + } + + public function ip_address() + { + if ($this->ip_address !== false) + { + return $this->ip_address; + } + + if ($this->server('REMOTE_ADDR') && $this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + else if ($this->server('REMOTE_ADDR')) + { + $this->ip_address = $_SERVER['REMOTE_ADDR']; + } + else if ($this->server('HTTP_CLIENT_IP')) + { + $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; + } + else if ($this->server('HTTP_X_FORWARDED_FOR')) + { + $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + + if ($this->ip_address === false) + { + $this->ip_address = '0.0.0.0'; + + return $this->ip_address; + } + + if (strstr($this->ip_address, ',')) + { + $x = explode(',', $this->ip_address); + $this->ip_address = end($x); + } + + if (!$this->valid_ip($this->ip_address)) + { + $this->ip_address = '0.0.0.0'; + } + + return $this->ip_address; + } + + public function valid_ip($ip) + { + $ip_segments = explode('.', $ip); + + if (count($ip_segments) != 4) + { + return false; + } + + if (substr($ip_segments[0], 0, 1) == '0') + { + return false; + } + + foreach ($ip_segments as $segment) + { + if (preg_match("/[^0-9]/", $segment) || $segment > 255 || strlen($segment) > 3) + { + return false; + } + } + + return true; + } + + public function user_agent() + { + if ($this->user_agent !== false) + { + return $this->user_agent; + } + + $this->user_agent = (!isset($_SERVER['HTTP_USER_AGENT'])) ? false : $_SERVER['HTTP_USER_AGENT']; + + return $this->user_agent; + } + + public function filename_security($string) + { + $bad = array( + "../", + "./", + "", + "<", + ">", + "'", + '"', + '&', + '$', + '#', + '{', + '}', + '[', + ']', + '=', + ';', + '?', + "%20", + "%22", + "%3c", + "%253c", + "%3e", + "%0e", + "%28", + "%29", + "%2528", + "%26", + "%24", + "%3f", + "%3b", + "%3d" + ); + + return stripslashes(str_replace($bad, '', $string)); + } + + public function xss_clean($string) + { + $string = preg_replace('/\0+/', '', $string); + $string = preg_replace('/(\\\\0)+/', '', $string); + + $string = preg_replace('#(&\#?[0-9a-z]+)[\x00-\x20]*;?#i', "\\1;", $string); + + $string = preg_replace('#(&\#x?)([0-9A-F]+);?#i', "\\1\\2;", $string); + + $string = preg_replace("/(%20)+/", '9u3iovBnRThju941s89rKozm', $string); + $string = preg_replace("/%u0([a-z0-9]{3})/i", "&#x\\1;", $string); + $string = preg_replace("/%([a-z0-9]{2})/i", "&#x\\1;", $string); + $string = str_replace('9u3iovBnRThju941s89rKozm', "%20", $string); + + $string = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, 'c_attribute_conversion'), $string); + $string = preg_replace_callback("/<([\w]+)[^>]*>/si", array($this, 'c_html_entity_decode_callback'), $string); + + $string = str_replace("\t", " ", $string); + + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $string = str_replace($key, $val, $string); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $string = preg_replace("#" . $key . "#i", $val, $string); + } + + $string = str_replace(array(''), array('<?php', '<?PHP', '<?', '?>'), $string); + + $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); + + foreach ($words as $word) + { + $temp = ''; + + for ($i = 0; $i < strlen($word); $i++) + { + $temp .= substr($word, $i, 1) . "\s*"; + } + + $string = preg_replace('#(' . substr($temp, 0, -3) . ')(\W)#ise', "preg_replace('/\s+/s', '', '\\1') . '\\2'", $string); + } + + do + { + $original = $string; + + if (stripos($string, '') !== false || preg_match("/<\/a>/i", $string)) + { + $string = preg_replace_callback("##si", array($this, 'c_js_link_removal'), $string); + } + + if (stripos($string, '#si", array($this, 'c_js_img_removal'), $string); + } + + if (stripos($string, 'script') !== false || stripos($string, 'xss') !== false || preg_match("/(script|xss)/i", $string)) + { + $string = preg_replace("##si", "", $string); + } + } + while ($original != $string); + + unset($original); + + $event_handlers = array('onblur', 'onchange', 'onclick', 'onfocus', 'onload', 'onmouseover', 'onmouseup', 'onmousedown', 'onselect', 'onsubmit', 'onupload', 'onkeypress', 'onkeydown', 'onkeyup', 'onresize', 'xmlns'); + $string = preg_replace("#<([^>]+)(" . implode('|', $event_handlers) . ")([^>]*)>#iU", "<\\1\\2\\3>", $string); + + $string = preg_replace('#<(/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>#is', "<\\1\\2\\3>", $string); + + $string = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $string); + + $bad = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '' => '-->', + ' '<![CDATA[' + ); + + foreach ($bad as $key => $val) + { + $string = str_replace($key, $val, $string); + } + + $bad = array( + "javascript\s*:" => '[removed]', + "expression\s*\(" => '[removed]', + "Redirect\s+302" => '[removed]' + ); + + foreach ($bad as $key => $val) + { + $string = preg_replace("#" . $key . "#i", $val, $string); + } + + log_message('debug', 'XSS filtering completed.'); + + return $string; + } + + private function c_js_link_removal($match) + { + return preg_replace("#.*?#si", "", $match[0]); + } + + private function c_js_img_removal($match) + { + return preg_replace("##si", "", $match[0]); + } + + private function c_attribute_conversion($match) + { + return str_replace('>', '<', $match[0]); + } + + private function c_html_entity_decode_callback($match) + { + $config = load_class('Config'); + + $charset = $config->get_config_value('charset'); + + return $this->c_html_entity_decode($match[0], strtoupper($charset)); + } + + private function c_html_entity_decode($string, $charset = 'UTF-8') + { + if (stristr($string, '&') === false) + { + return $string; + } + + if (function_exists('html_entitiy_decode') && strtolower($charset) != 'utf-8') + { + $string = html_entity_decode($string, ENT_COMPAT, $charset); + $string = preg_match('~&#x([0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $string); + + return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $string); + } + + $string = preg_replace('~&#x([0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $string); + $string = preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $string); + + if (stristr($string, '&') === false) + { + $string = strtr($string, array(get_html_translation_table(HTML_ENTITIES))); + } + + return $string; + } +} + +?> diff --git a/Source/carbon/libraries/Language.php b/Source/carbon/libraries/Language.php new file mode 100644 index 0000000..b418fe1 --- /dev/null +++ b/Source/carbon/libraries/Language.php @@ -0,0 +1,79 @@ +is_loaded, true)) + { + return true; + } + + if ($idiom == '') + { + $carbon = get_instance(); + $def_lang = $carbon->config->get_config_value('language'); + $idiom = ($def_lang == '') ? 'engliah' : $def_lang; + } + + if (file_exists(APP_PATH . 'languages/' . $idiom . '/' . $langfile)) + { + include(APP_PATH . 'languages/' . $idiom . '/' . $langfile); + } + else + { + if (file_exists(CARBON_PATH . 'languages/' . $idiom . '/' . $langfile)) + { + include(CARBON_PATH . 'languages/' . $idiom . '/' . $langfile); + } + else + { + display_error('Unable to load the language file: languages/' . $langfile); + } + } + + if (!isset($lang)) + { + log_message('error', 'Langauge file contains no data: languages/' . $idiom . '/' . $langfile); + return false; + } + + if ($return == true) + { + return $lang; + } + + $this->is_loaded[] = $langfile; + $this->language = array_merge($this->language, $lang); + unset($lang); + + log_message('debug', 'Language file loaded: languages/' . $idiom . '/' . $langfile); + return true; + } + + public function line($line = '') + { + return ($line == '' || !isset($this->language[$line])) ? false : $this->language[$line]; + } +} + +?> diff --git a/Source/carbon/libraries/Loader.php b/Source/carbon/libraries/Loader.php new file mode 100644 index 0000000..5c0f814 --- /dev/null +++ b/Source/carbon/libraries/Loader.php @@ -0,0 +1,520 @@ +loader_view_path = APP_PATH . 'views/'; + $this->loader_ob_level = ob_get_level(); + + log_message('debug', 'Loader class initialised.'); + } + + public function library($library = '', $params = null) + { + if ($library == '') + { + return false; + } + + if (is_array($library)) + { + foreach ($library as $class_name) + { + $this->c_load_class($class_name, $params); + } + } + else + { + $this->c_load_class($library, $params); + } + + $this->c_assign_to_models(); + } + + public function model($model, $name = '', $db_conn = false) + { + if ($model == '') + { + return false; + } + + if (strpos($model, '/') === false) + { + $path = ''; + } + else + { + $x = explode('/', $model); + $model = end($x); + unset($x[count($x) - 1]); + $path = implode('/', $x) . '/'; + } + + if ($name == '') + { + $name = $model; + } + + if (in_array($name, $this->loader_models, true)) + { + return true; + } + + $carbon = get_instance(); + + if (isset($carbon->$name)) + { + display_error('The model name you are trying to load shared a name with a resource already in use: ' . $name); + } + + $model = strtolower($model); + + if (!file_exists(APP_PATH . 'models/' . $path . $model . FILE_EXT)) + { + display_error('Unable to load the model file you have specified: ' . $model); + } + + if ($db_conn !== false && !class_exists('Carbon_Database')) + { + if ($db_conn == true) + { + $db_conn = ''; + } + + $carbon->load->database($db_conn, false, true); + } + + if (!class_exists('Model')) + { + require_once(CARBON_PATH . 'libraries/Model' . FILE_EXT); + } + + require_once(APP_PATH . 'models/' . $path . $model . FILE_EXT); + + $model = ucfirst($model); + + $carbon->$name = new $model(); + + $carbon->$name->assign_libraries(); + $this->loader_models[] = $name; + } + + public function database($params = '', $return = false, $active_record = false) + { + if (class_exists('Carbon_Database') && $return == false && $active_record == false) + { + return false; + } + + require_once(CARBON_PATH . 'database/Database' . FILE_EXT); + + if ($return === true) + { + return Database($params, $active_record); + } + + $carbon = get_instance(); + $carbon->db = ''; + $carbon->db = Database($params, $active_record); + $this->c_assign_to_models(); + } + + public function dbutils() + { + if (!class_exists('Carbon_Database')) + { + $this->database(); + } + + $carbon = get_instance(); + + require_once(CARBON_PATH . 'database/Database_utility' . FILE_EXT); + require_once(CARBON_PATH . 'database/drivers/' . $carbon->db->dbdriver . '/' . $carbon->db->dbdriver . '_utility' . FILE_EXT); + + $class = 'Carbon_Database_' . $carbon->db->dbdriver . '_utility'; + + $carbon->dbutils = new $class(); + + $carbon->load->c_assign_to_models(); + } + + public function view($view, $vars = array(), $return = false) + { + return $this->c_load(array('view' => $view, 'vars' => $this->c_object_to_array($vars), 'return' => $return)); + } + + public function file($path, $return = false) + { + return $this->c_load(array('path' => $path, 'return' => $return)); + } + + public function vars($vars = array()) + { + $vars = $this->c_object_to_array($vars); + + if (is_array($vars) && count($vars) > 0) + { + foreach ($vars as $key => $val) + { + $this->loader_cached_vars[$key] = $val; + } + } + } + + public function utility($utilities = array()) + { + if (!is_array($utilities)) + { + $utilities = array($utilities); + } + + foreach ($utilities as $utility) + { + $utility = strtolower(str_replace(FILE_EXT, '', str_replace('_utility', '', $utility)) . '_utility'); + + if (isset($this->loader_utilities[$utility])) + { + continue; + } + + if (file_exists(APP_PATH . 'utilities/' . $utility . FILE_EXT)) + { + include_once(APP_PATH . 'utilities/' . $utility . FILE_EXT); + } + else + { + if (file_exists(CARBON_PATH . 'utilities/' . $utility . FILE_EXT)) + { + include(CARBON_PATH . 'utilities/' . $utility . FILE_EXT); + } + else + { + display_error('Unable to load the utility file: utilities/' . $utility . FILE_EXT); + } + } + + $this->loader_utilities[$utility] = true; + } + + log_message('debug', 'Utilities loaded: ' . implode(', ', $utilities)); + } + + public function language($file = array(), $lang = '') + { + $carbon = get_instance(); + + if (!is_array($file)) + { + $file = array($file); + } + + foreach ($file as $langfile) + { + $carbon->lang->load($langfile, $lang); + } + } + + public function scaffold_language($file = '', $lang = '', $return = false) + { + $carbon = get_instance(); + + return $carbon->lang->load($file, $lang, $return); + } + + public function config($file = '', $use_sections = false, $fail_gracefully = false) + { + $carbon = get_instance(); + $carbon->config->load($file, $use_sections, $fail_gracefully); + } + + public function scaffolding($table = '') + { + if ($table === false) + { + display_error('You must include the name of the table you would like to access when you initialise scaffolding'); + } + + $carbon = get_instance(); + $carbon->set_scaffolding(true); + $carbon->set_scaff_table($table); + } + + private function c_load($data) + { + foreach (array('view', 'vars', 'path', 'return') as $val) + { + $$val = (!isset($data[$val])) ? false : $data[$val]; + } + + if ($path == '') + { + $ext = pathinfo($view, PATHINFO_EXTENSION); + $file = ($ext =='') ? $view . FILE_EXT : $view; + $path = $this->loader_view_path . $file; + } + else + { + $x = explode('/', $path); + $file = end($x); + } + + if (!file_exists($path)) + { + display_error('Unable to load the specified file: ' . $file); + } + + $carbon = get_instance(); + + foreach (get_object_vars($carbon) as $key => $var) + { + $this->$key = $carbon->$key; + } + + if (is_array($vars)) + { + $this->loader_cached_vars = array_merge($this->loader_cached_vars, $vars); + } + + extract($this->loader_cached_vars); + + ob_start(); + + if ((bool) @ini_get('short_open_tag') === false && get_config_item('short_tag_rewrite') == true) + { + echo eval('?>' . preg_replace("/;*\s*\?>/", "; ?>", str_replace(' $this->loader_ob_level + 1) + { + ob_end_flush(); + } + else + { + global $output; + $output->set_final_output(ob_get_contents()); + @ob_end_clean(); + } + } + + private function c_load_class($class_name, $params = null) + { + $class_name = str_replace(FILE_EXT, '', $class_name); + + foreach (array(ucfirst($class_name), strtolower($class_name)) as $class) + { + $subclass = APP_PATH . 'libraries/' . get_config_value('subclass_prefix') . $class . FILE_EXT; + + if (file_exists($subclass)) + { + $base_class = CARBON_PATH . 'libraries/' . ucfirst($class) . FILE_EXT; + + if (!file_exists($base_class)) + { + log_message('error', 'Unable to load the requested class file: ' . $class); + display_error('Unable to load the requested class file: ' . $class); + + return false; + } + + if (in_array($subclass, $this->loader_classes)) + { + $is_duplicated = true; + log_message('debug', 'Class already loaded, ignoring second load attempt: ' . $class); + + return false; + } + + include($base_class); + include($subclass); + + $this->loader_classes[] = $subclass; + + return $this->c_init_class($class, get_config_item('subclass_prefix'), $params); + } + + $is_duplicated = false; + + for ($i = 1; $i < 3; $i++) + { + $path = ($i % 2) ? APP_PATH : CARBON_PATH; + $file_path = $path . 'libraries/' . $class . FILE_EXT; + + if (!file_exists($file_path)) + { + continue; + } + + if (in_array($file_path, $this->loader_classes)) + { + $is_duplicated = true; + log_message('debug', 'Class already loaded, ignoring second load attempt: ' . $class); + + return false; + } + + include($file_path); + + $this->loader_classes[] = $file_path; + + return $this->c_init_class($class, '', $params); + } + } + + if ($is_duplicated == false) + { + log_message('error', 'Unable to load the requested class file: ' . $class); + display_error('Unable to load the requested class file: ' . $class); + + return false; + } + } + + private function c_init_class($class, $prefix = '', $config = false) + { + if ($config === null) + { + $config = null; + + if (file_exists(APP_PATH . 'config/' . $class . FILE_EXT)) + { + include(APP_PATH . 'config/' . $class . FILE_EXT); + } + } + + if ($prefix == '') + { + $name = (class_exists('Carbon_' . $class)) ? 'Carbon_' . $class : $class; + } + else + { + $name = $prefix . $class; + } + + $class = strtolower($class); + $classvar = (!isset($this->loader_varmap[$class])) ? $class : $this->loader_varmap[$class]; + + $carbon = get_instance(); + + if ($config !== null) + { + $carbon->$classvar = new $name($config); + } + else + { + $carbon->$classvar = new $name; + } + } + + public function autoloader() + { + include(APP_PATH . 'config/autoload' . FILE_EXT); + + if (!isset($autoload)) + { + return false; + } + + if (count($autoload['config']) > 0) + { + $carbon = get_instance(); + + foreach ($autoload['config'] as $key => $value) + { + $carbon->config->load($value); + } + } + + foreach (array('utility', 'language') as $type) + { + if (isset($autoload[$type]) && count($autoload[$type]) > 0) + { + $this->$type($autoload[$type]); + } + } + + if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) + { + if (in_array('database', $autoload['libraries'])) + { + $this->database(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); + } + + if (in_array('model', $autoload['libraries'])) + { + $this->model(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('model')); + } + + if (in_array('scaffolding', $autoload['libraries'])) + { + $this->scaffolding(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding')); + } + + foreach ($autoload['libraries'] as $library) + { + $this->library($library); + } + } + } + + public function set_view_path($view_path) + { + $this->loader_view_path = $view_path; + } + + private function c_assign_to_models() + { + if (count($this->loader_models) == 0) + { + return false; + } + + $carbon = get_instance(); + + foreach ($this->loader_models as $model) + { + $carbon->$model->assign_libraries(); + } + } + + private function c_object_to_array($object) + { + return (is_object($object)) ? get_object_vars($object) : $object; + } +} + +?> diff --git a/Source/carbon/libraries/Logging.php b/Source/carbon/libraries/Logging.php new file mode 100644 index 0000000..92a2e4f --- /dev/null +++ b/Source/carbon/libraries/Logging.php @@ -0,0 +1,88 @@ + '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4'); + private $logging_path = ''; + private $logging_threshold = 1; + private $logging_date_format = 'Y-m-d H:i:s'; + private $logging_enabled = true; + + public function __construct() + { + $this->logging_path = (get_config_value('logging_path') != '') ? get_config_value('logging_path') : APP_PATH . 'logs/'; + + if (!is_dir($this->logging_path) || !is_writeable($this->logging_path)) + { + $this->logging_enabled = false; + } + + if (is_numeric(get_config_value('logging_threshold'))) + { + $this->logging_threshold = get_config_value('logging_threshold'); + } + + if (get_config_value('logging_date_format') != '') + { + $this->logging_date_format = get_config_value('logging_date_format'); + } + } + + public function write_log_message($level = 'error', $message, $php_eror = false) + { + if ($this->logging_enabled === false) + { + return false; + } + + $level = strtoupper($level); + + if (!isset($this->logging_levels[$level]) || ($this->logging_levels[$level] > $this->logging_threshold)) + { + return false; + } + + $file_path = $this->logging_path . 'log-' . date('Y-m-d') . FILE_EXT; + $log_message = ''; + + if (!file_exists($file_path)) + { + $log_message .= "<" . "?php\n"; + $log_message .= "if (!defined('CARBON_PATH'))\n"; + $log_message .= "{\n"; + $log_message .= "\texit('Direct script access is not allowed.');\n"; + $log_message .= "}\n"; + $log_message .= "?" . ">\n\n"; + } + + $file = @fopen($file_path, "a"); + + if (!$file) + { + echo 'Could not open file...'; + return false; + } + + $log_message .= $level . ' ' . (($level == 'INFO') ? ' -' : '-') . ' ' . date($this->logging_date_format) . ' -> ' . $message . "\n"; + + flock($file, LOCK_EX); + fwrite($file, $log_message); + flock($file, LOCK_UN); + fclose($file); + + @chmod($file_path, 0666); + + return true; + } +} + +?> diff --git a/Source/carbon/libraries/Model.php b/Source/carbon/libraries/Model.php new file mode 100644 index 0000000..2b02638 --- /dev/null +++ b/Source/carbon/libraries/Model.php @@ -0,0 +1,46 @@ +assign_libraries((method_exists($this, '__set') || method_exists($this, '__get')) ? false : true); + $this->model_parent_class_name = ucfirst(get_class($this)); + + log_message('debug', 'Model class initialised'); + } + + public function assign_libraries($use_references = true) + { + $carbon = get_instance(); + + foreach (array_keys(get_object_vars($carbon)) as $key) + { + if (!isset($this->$key) && $key != $this->model_parent_class_name) + { + if ($use_references) + { + $this->$key = ''; + $this->$key = $carbon->$key; + } + else + { + $this->$key = $carbon->$key; + } + } + } + } +} + +?> diff --git a/Source/carbon/libraries/Output.php b/Source/carbon/libraries/Output.php new file mode 100644 index 0000000..319f0a9 --- /dev/null +++ b/Source/carbon/libraries/Output.php @@ -0,0 +1,204 @@ +final_output = $final_output; + } + + public function get_final_output() + { + return $this->final_output; + } + + public function set_header_data($http_header) + { + $this->http_headers[] = $http_header; + } + + public function set_cache_expiration($expiration) + { + $this->cache_expiration = (!is_numeric($expiration) ? 0 : $expiration); + } + + public function display_output($output = '') + { + global $config; + global $bench; + + if ($output == '') + { + $output = $this->final_output; + } + + if ($this->cache_expiration > 0) + { + $this->carbon_write_cache($output); + } + + $elapsed = $bench->elapsed_time('total_execution_time_start', 'total_execution_time_end'); + $output = str_replace('{elapsed_time}', $elapsed, $output); + + $memory = (!function_exists('memory_get_usage')) ? '0' : round(memory_get_usage() / 1024 / 1024, 2) . 'MB'; + $output = str_replacE('{memory_usage}', $memory, $output); + + if ($config->get_config_value('compress_output') === true) + { + if (extension_loaded('zlib')) + { + if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) + { + ob_start('ob_gzhandler'); + } + } + } + + if (count($this->http_headers) > 0) + { + foreach ($this->http_headers as $http_header) + { + @header($http_header); + } + } + + if (!function_exists('get_instance')) + { + echo $output; + log_message('debug', 'Output sent to browser.'); + log_message('debug', 'Total execution time: ' . $elapsed); + + return true; + } + + $carbon = get_instance(); + + if (method_exists($carbon, 'output')) + { + $carbon->output($output); + } + else + { + echo $output; + } + + log_message('debug', 'Output sent to browser.'); + log_message('debug', 'Total execution time: ' . $elapsed); + + return true; + } + + private function c_write_cache($output) + { + $carbon = get_instance(); + $cache_path = $carbon->config->get_config_value('cache_path'); + $cache_path = ($cache_path == '') ? APP_PATH . 'cache/' : $cache_path; + + if (!is_dir($cache_path) || !is_writable($cache_path)) + { + return false; + } + + $uri = $carbon->config->get_config_value('carbon_url') . $carbon->config->get_config_value('index_page') . $carbon->uri->get_uri_string(); + + $cache_path .= md5($uri); + $file = @fopen($cache_path, 'wb'); + + if (!$file) + { + echo 'Debug'; + log_message('error', 'Unable to write to the cache file: ' . $cache_path); + + return false; + } + + $expire = time() + ($this->cache_expiration * 60); + + flock($file, LOCK_EX); + fwrite($file, $expire . 'time--->' . $output); + flock($file, LOCK_UN); + fclose($file); + + @chmod($cache_path, 0777); + log_message('debug', 'Written cache file: ' . $cache_path); + } + + public function display_cache(&$config, &$router) + { + $config = load_class('Config'); + $router = load_class('Router'); + + $cache_path = ($config->get_config_value('cache_path') == '') ? APP_PATH . 'cache/' : $config->get_config_value('cache_path'); + + if (!is_dir($cache_path) || !is_writable($cache_path)) + { + return false; + } + + $uri = $config->get_config_value('carbon_url') . $config->get_config_value('index_page') . $router->get_uri_string(); + + $file_path = $cache_path . md5($uri); + + if (!@file_exists($file_path)) + { + return false; + } + + $file = @fopen($file_path, 'rb'); + + if (!$file) + { + return false; + } + + flock($file, LOCK_EX); + + $cache = ''; + + if (filesize($file_path) > 0) + { + $cache = fread($file, filesize($file_path)); + } + + flock($file, LOCK_UN); + fclose($file); + + if (!preg_match("/(\d+time--->)/", $cache, $match)) + { + return false; + } + + if (time() >= trim(str_replace('time--->', '', $match['1']))) + { + @unlink($file_path); + log_message('debug', 'Cache file has expired, removing cache file.'); + + return false; + } + + $this->display_output(str_replace($match['0'], '', $cache)); + log_message('debug', 'Cache file is up to date, sending cache file to browser.'); + + return true; + } +} + +?> diff --git a/Source/carbon/libraries/Pagination.php b/Source/carbon/libraries/Pagination.php new file mode 100644 index 0000000..6500d69 --- /dev/null +++ b/Source/carbon/libraries/Pagination.php @@ -0,0 +1,158 @@ +'; + private $cur_tag_close = ''; + private $next_tag_open = ' '; + private $next_tag_close = ' '; + private $prev_tag_open = ' '; + private $prev_tag_close = ''; + private $num_tag_open = ' '; + private $num_tag_close = ''; + + public function __construct($params = array()) + { + if (count($params) > 0) + { + $this->initialise($params); + } + + log_message('debug', 'Pagination class initialised.'); + } + + public function initialise($params = array()) + { + if (count($params) > 0) + { + foreach ($params as $key => $val) + { + if (isset($this->$key)) + { + $this->$key = $val; + } + } + } + } + + public function create_links() + { + if ($this->total_rows == 0 || $this->per_page == 0) + { + return ''; + } + + $num_pages = ceil($this->total_rows / $this->per_page); + + if ($num_pages == 1) + { + return ''; + } + + $carbon = get_instance(); + + if ($carbon->uri->segment($this->uri_segment) != 0) + { + $this->cur_page = $carbon->uri->segment($this->uri_segment); + $this->cur_page = (int) $this->cur_page; + } + + if (!is_numeric($this->cur_page)) + { + $this->cur_page = 0; + } + + if ($this->cur_page > $this->total_rows) + { + $this->cur_pge = ($num_pages - 1) * $this->per_page; + } + + $uri_page_number = $this->cur_page; + $this->cur_page = floor(($this->cur_page / $this->per_page) + 1); + + $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1; + $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages; + + $this->base_url = rtrim($this->base_url, '/') . '/'; + + $output = ''; + + if ($this->cur_page > $this->num_links) + { + $output .= $this->first_tag_open . '' . $this->first_link . '' . $this->first_tag_close; + } + + if (($this->cur_page - $this->num_links) >= 0) + { + $i = $uri_page_number - $this->per_page; + + if ($i == 0) + { + $i = ''; + } + + $output .= $this->prev_tag_open . '' . $this->prev_link . '' . $this->prev_tag_close; + } + + for ($loop = $start - 1; $loop <= $end; $loop++) + { + $i = ($loop * $this->per_page) - $this->per_page; + + if ($i >= 0) + { + if ($this->cur_page == $loop) + { + $output .= $this->cur_tag_open . $loop . $this->cur_tag_close; + } + else + { + $n = ($i == 0) ? '' : $i; + $output .= $this->num_tag_open . '' . $loop . '' . $this->num_tag_close; + } + } + } + + if ($this->cur_page < $num_pages) + { + $output .= $this->next_tag_open . '' . $this->next_link . '' . $this->next_tag_close; + } + + if (($this->cur_page + $this->num_links) < $num_pages) + { + $i = (($num_pages * $this->per_page) - $this->per_page); + $output .= $this->last_tag_open . '' . $this->last_link . '' . $this->last_tag_close; + } + + $output = preg_replace("#([^:])//+#", "\\1/", $output); + $output = $this->full_tag_open . $output . $this->full_tag_close; + + return $output; + } +} + +?> diff --git a/Source/carbon/libraries/Router.php b/Source/carbon/libraries/Router.php new file mode 100644 index 0000000..9bc56cf --- /dev/null +++ b/Source/carbon/libraries/Router.php @@ -0,0 +1,393 @@ +config = load_class('Config'); + $this->c_set_route_mapping(); + + log_message('debug', 'Router class initialised.'); + } + + private function c_set_route_mapping() + { + if ($this->config->get_config_value('use_query_strings') === true && isset($_GET[$this->config->get_config_value('controller_trigger')])) + { + $this->set_class_name(trim($this->c_filter_uri_chars($_GET[$this->config->get_config_value('controller_trigger')]))); + + if (isset($_GET[$this->config->get_config_value('method_trigger')])) + { + $this->set_method_name(trim($this->c_filter_uri_chars($_GET[$this->config->get_config_value('method_trigger')]))); + } + + return true; + } + + @include(APP_PATH . 'config/routing' . FILE_EXT); + + $this->routes = (!isset($routing) || !is_array($routing)) ? array() : $routing; + unset($routing); + + $this->default_controller = (!isset($this->routes['default_controller']) || $this->routes['default_controller'] == '') ? false : strtolower($this->routes['default_controller']); + + $this->uri_string = $this->get_uri_string(); + + if ($this->uri_string == '/' || strpos($this->uri_string, '/index.php') == (strlen($this->uri_string) - 10)) + { + $this->uri_string = ''; + } + + if ($this->uri_string == '') + { + if ($this->default_controller === false) + { + display_error('Could not determine what should be display. No default routing has been specified in the routing configuration file.'); + } + + $this->set_class_name($this->default_controller); + $this->set_method_name('index'); + + log_message('debug', 'No URI is present. Setting the controller to default.'); + + return true; + } + + unset($this->routes['default_controller']); + + if ($this->config->get_config_value('url_postfix') != '') + { + $this->uri_string = preg_replace('|' . preg_quote($this->config->get_config_value('url_postfix')) . '$|', '', $this->uri_string); + } + + foreach (explode('/', preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $uri_segment) + { + $uri_segment = trim($this->c_filter_uri_chars($uri_segment)); + + if ($uri_segment != '') + { + $this->uri_segments[] = $uri_segment; + } + } + + $this->c_parse_routes(); + $this->c_reindex_segments(); + } + + private function c_compile_uri_segments($segments = array()) + { + $segments = $this->c_validate_uri_segments($segments); + + if (count($segments) == 0) + { + return false; + } + + $this->set_class_name($segments[0]); + + if (isset($segments[1])) + { + if ($this->routes['scaffolding_trigger'] == $segments[1] && $segments[1] != 'c_scaffolding') + { + $this->scaffolding_request = true; + unset($this->routes['scaffolding_trigger']); + } + else + { + $this->set_method_name($segments[1]); + } + } + + $this->uri_rsegments = $segments; + } + + private function c_validate_uri_segments($segments) + { + if (file_exists(APP_PATH . 'controllers/' . $segments[0] . FILE_EXT)) + { + return $segments; + } + + if (is_dir(APP_PATH . 'controllers/' . $segments[0])) + { + $this->set_directory_name($segments[0]); + $segments = array_slice($segments, 1); + + if (count($segments) > 0) + { + if (!file_exists(APP_PATH . 'controllers/' . $this->get_directory_name() . $segments[0] . FILE_EXT)) + { + display_not_found(); + } + } + else + { + $this->set_class_name($this->default_controller); + $this->set_method_name('index'); + + if (!file_exists(APP_PATH . 'controllers/' . $this->get_directory_name() . $this->default_controller . FILE_EXT)) + { + $this->directory_name = ''; + + return array(); + } + } + + return $segments; + } + + display_not_found(); + } + + private function c_reindex_segments() + { + $difference = (count(array_diff($this->uri_rsegments, $this->uri_segments)) == 0) ? false : true; + $i = 1; + + foreach ($this->uri_segments as $uri_segment) + { + $this->uri_segments[$i++] = $uri_segment; + } + + unset($this->uri_segments[0]); + + if (!$difference) + { + $this->uri_rsegments = $this->uri_segments; + } + else + { + $i = 1; + + foreach ($this->uri_rsegments as $uri_rsegment) + { + $this->uri_rsegments[$i++] = $uri_rsegment; + } + + unset($this->uri_rsegments[0]); + } + } + + public function get_uri_string() + { + if (strtoupper($this->config->get_config_value('uri_protocol')) == 'AUTO') + { + if (is_array($_GET) && count($_GET) == 1) + { + $keys = array_keys($_GET); + + return current($keys); + } + + $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); + + if ($path != '' && $path != '/' . INDEX_FILE) + { + return $path; + } + + $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + + if ($path != '' && $path != '/' . INDEX_FILE) + { + return $path; + } + + $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'); + + if ($path != '' && $path != '/' . INDEX_FILE) + { + return $path; + } + + return ''; + } + else + { + $uri = strtoupper($this->config->get_config_value('uri_protocol')); + + if ($uri == 'REQUEST_URI') + { + return $this->c_parse_request_uri(); + } + + return (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); + } + } + + private function c_parse_request_uri() + { + if (!isset($_SERVER['REQUEST_URI']) || $_SERVER['REQUEST_URI'] == '') + { + return ''; + } + + $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI'])); + + if ($request_uri == '' || $request_uri == INDEX_FILE) + { + return ''; + } + + $index_path = INDEX_PATH; + + if (strpos($request_uri, '?') !== false) + { + $index_path .= '?'; + } + + $parsed_uri = explode('/', $request_uri); + $i = 0; + + foreach (explode('/', $index_path) as $segment) + { + if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i]) + { + $i++; + } + } + + $parsed_uri = implode('/', array_slice($parsed_uri, $i)); + + if ($parsed_uri != '') + { + $parsed_uri = '/' . $parsed_uri; + } + + $parsed_uri; + } + + private function c_filter_uri_chars($uri_string) + { + if ($this->config->get_config_value('allowed_uri_chars') != '') + { + if (!preg_match("|^[" . preg_quote($this->config->get_config_value('allowed_uri_chars')) . "]+$|i", $uri_string)) + { + exit('The submitted URI contains characters that are disallowed.'); + } + } + + return $uri_string; + } + + private function c_parse_routes() + { + if (count($this->routes) == 1) + { + $this->c_compile_uri_segments($this->uri_segments); + + return true; + } + + $uri = implode('/', $this->uri_segments); + + if (isset($this->routes[$uri])) + { + $this->c_compile_uri_segments(explode('/', $this->routes[$uri])); + + return true; + } + + foreach (array_slice($this->routes, 1) as $key => $val) + { + $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); + + if (preg_match('#^' . $key . '$#', $uri)) + { + if (strpos($val, '$') !== false && strpos($key, '(') !== false) + { + $val = preg_replace('#^' . $key . '$#', $val, $uri); + } + + $this->c_compile_uri_segments(explode('/', $val)); + + return true; + } + } + + $this->c_compile_uri_segments($this->uri_segments); + } + + public function set_class_name($class_name) + { + $this->class_name = $class_name; + } + + public function get_class_name() + { + return $this->class_name; + } + + public function set_method_name($method_name) + { + $this->method_name = $method_name; + } + + public function get_method_name() + { + if ($this->method_name == $this->get_class_name()) + { + return 'index'; + } + + return $this->method_name; + } + + public function set_directory_name($directory_name) + { + $this->directory_name = $directory_name . '/'; + } + + public function get_directory_name() + { + return $this->directory_name; + } + + public function segment($index) + { + return $this->uri_segments[$index]; + } + + public function rsegment($index) + { + return $this->uri_rsegments[$index]; + } + + public function get_uri_segment_array() + { + return $this->uri_segments; + } + + public function get_ruri_segment_array() + { + return $this->uri_rsegments; + } + + public function is_scaffolding_request() + { + return $this->scaffolding_request; + } +} + +?> diff --git a/Source/carbon/libraries/Table.php b/Source/carbon/libraries/Table.php new file mode 100644 index 0000000..b319157 --- /dev/null +++ b/Source/carbon/libraries/Table.php @@ -0,0 +1,307 @@ +template = $template; + + return true; + } + + public function set_heading() + { + $args = func_get_args(); + $this->heading = (is_array($args[0])) ? $args[0] : $args; + } + + public function make_columns($array = array(), $col_limit = 0) + { + if (!is_array($array) || count($array) == 0) + { + return false; + } + + $this->auto_heading = false; + + if ($col_limit == 0) + { + return $array; + } + + $new = array(); + + while (count($array) > 0) + { + $temp = array_slice($array, 0, $col_limit); + $array = array_diff($array, $temp); + + if (count($temp) < $col_limit) + { + for ($i = count($temp); $i < $col_limit; $i++) + { + $temp[] = ' '; + } + } + + $new[] = $temp; + } + + return $new; + } + + public function set_empty($value) + { + $this->empty_cells = $value; + } + + public function add_row() + { + $args = func_get_args(); + $this->rows[] = (is_array($args[0])) ? $args[0] : $args; + } + + public function set_caption($caption) + { + $this->caption = $caption; + } + + public function generate($table_data = null) + { + if (!is_null($table_data)) + { + if (is_object($table_data)) + { + $this->c_set_from_object($table_data); + } + elseif (is_array($table_data)) + { + $set_heading = (count($this->heading) == 0 && $this->auto_heading == false) ? false : true; + $this->c_set_from_array($table_data, $set_heading); + } + } + + if (count($this->heading) == 0 && count($this->rows) == 0) + { + return 'Undefined table data'; + } + + $this->c_compile_template(); + + $out = $this->template['table_open']; + $out .= $this->newline; + + if ($this->caption) + { + $out .= $this->newline; + $out .= '' . $this->caption . ''; + $out .= $this->newline; + } + + if (count($this->heading) > 0) + { + $out .= $this->template['heading_row_start']; + $out .= $this->newline; + + foreach ($this->heading as $heading) + { + $out .= $this->template['heading_cell_start']; + $out .= $heading; + $out .= $this->template['heading_cell_end']; + } + + $out .= $this->template['heading_row_end']; + $out .= $this->newline; + } + + if (count($this->rows) > 0) + { + $i = 1; + + foreach ($this->rows as $row) + { + if (!is_array($row)) + { + break; + } + + $name = (fmod($i++, 2)) ? '' : 'alt_'; + + $out .= $this->template['row_' . $name . 'start']; + $out .= $this->newline; + + foreach ($row as $cell) + { + $out .= $this->template['cell_' . $name . 'start']; + + if ($cell == '') + { + $out .= $this->empty_cells; + } + else + { + $out .= $cell; + } + + $out .= $this->template['cell_' . $name . 'end']; + } + + $out .= $this->template['row_' . $name . 'end']; + $out .= $this->newline; + } + } + + $out .= $this->template['table_close']; + + return $out; + } + + public function clear() + { + $this->rows = array(); + $this->heading = array(); + $this->auto_heading = true; + } + + private function c_set_from_object($query) + { + if (!is_object($query)) + { + return false; + } + + if (count($this->heading) == 0) + { + if (!method_exists($query, 'list_fields')) + { + return false; + } + + $this->heading = $query->list_fields(); + } + + if ($query->num_rows() > 0) + { + foreach ($query->result_array() as $row) + { + $this->rows[] = $row; + } + } + } + + private function c_set_from_array($data, $set_heading = true) + { + if (!is_array($data) || count($data) == 0) + { + return false; + } + + $i = 0; + + foreach ($data as $row) + { + if (!is_array($row)) + { + $this->rows[] = $data; + break; + } + + if ($i == 0 && count($data) > 1 && count($this->heading) == 0 && $set_heading == true) + { + $this->heading = $row; + } + else + { + $this->rows[] = $row; + } + + $i++; + } + } + + private function c_compile_template() + { + if ($this->template == null) + { + $this->template = $this->c_default_template(); + return true; + } + + $this->temp = $this->c_default_template(); + $template = 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', + 'call_alt_end', + 'table_close' + ); + + foreach ($template as $value) + { + if (!isset($this->template[$value])) + { + $this->template[$value] = $this->temp[$value]; + } + } + } + + private function c_default_template() + { + $template = array( + 'table_open' => '', + 'heading_row_start' => '', + 'heading_row_end' => '', + 'heading_cell_start' => '', + 'row_start' => '', + 'row_end' => '', + 'cell_start' => '', + 'row_alt_start' => '', + 'row_alt_end' => '', + 'cell_alt_start' => '', + 'table_close' => '
', + 'heading_cell_end' => '
', + 'cell_end' => '
', + 'cell_alt_end' => '
' + ); + + return $template; + } +} + +?> diff --git a/Source/carbon/libraries/Uri.php b/Source/carbon/libraries/Uri.php new file mode 100644 index 0000000..f7cc55c --- /dev/null +++ b/Source/carbon/libraries/Uri.php @@ -0,0 +1,198 @@ +router = load_class('Router'); + + log_message('debug', 'URI class initialised.'); + } + + public function segment($index, $no_result = false) + { + $uri_segments = $this->router->get_uri_segment_array(); + + return (!isset($uri_segments[$index]) ? $no_result : $uri_segments[$index]); + } + + public function rsegment($index, $no_result = false) + { + $uri_rsegments = $this->router->get_ruri_segment_array(); + + return (!isset($uri_rsegments[$index]) ? $no_result : $uri_rsegments[$index]); + } + + public function get_uri_to_assoc($index = 3, $default = array()) + { + return $this->c_uri_to_assoc($index, $default, 'segment'); + } + + public function get_ruri_to_assoc($index = 3, $default = array()) + { + return $this->c_uri_to_assoc($index, $default, 'rsegment'); + } + + private function c_uri_to_assoc($index = 3, $default, $which = 'segment') + { + if ($which == 'segment') + { + $total_segments = 'total_segments'; + $segment_array = 'segment_array'; + } + else + { + $total_segments = 'total_rsegments'; + $segment_array = 'rsegment_array'; + } + + if (!is_numeric($index)) + { + return $default; + } + + if (isset($this->keyval[$index])) + { + return $this->keyval[$index]; + } + + if ($this->$total_segments() < $index) + { + if (count($default) == 0) + { + return array(); + } + + $retval = array(); + + foreach ($default as $value) + { + $retval[$value] = false; + } + + return $retval; + } + + $segments = array_slice($this->segment_array(), ($index - 1)); + $i = 0; + $lastval = ''; + + foreach ($segments as $segment) + { + if ($i % 2) + { + $retval[$lastval] = $segment; + } + else + { + $retval[$$segment] = false; + $lastval = $segment; + } + + $i++; + } + + if (count($default) > 0) + { + foreach ($default as $value) + { + if (!array_key_exists($value, $retval)) + { + $retval[$value] = false; + } + } + } + + $this->keyval[$index] = $retval; + + return $retval; + } + + public function assoc_to_uri($array) + { + $temp = array(); + + foreach ((array) $array as $key => $value) + { + $temp[] = $key; + $temp[] = $value; + } + + return implode('/', $temp); + } + + public function slash_segment($index, $where = 'trailing') + { + return $this->c_slash_segment($index, $where, 'segment'); + } + + public function slash_rsegment($index, $where = 'trailing') + { + return $this->c_slash_segment($index, $where, 'rsegment'); + } + + private function c_slash_segment($index, $where = 'trailing', $which = 'segment') + { + if ($where == 'trailing') + { + $trailing = '/'; + $leading = ''; + } + else if ($where == 'leading') + { + $trailing = ''; + $leading = '/'; + } + else + { + $trailing = '/'; + $leading = '/'; + } + + return $leading . $this->$which($index) . $trailing; + } + + public function get_segment_array() + { + return $this->router->get_uri_segment_array(); + } + + public function get_rsegment_array() + { + return $this->router->get_ruri_segment_array(); + } + + public function total_segments() + { + return count($this->router->get_uri_segment_array()); + } + + public function total_rsegments() + { + return count($this->router->get_uri_rsegment_array()); + } + + public function get_uri_string() + { + return $this->router->get_uri_string(); + } + + public function get_ruri_string() + { + return '/' . implode('/', $this->get_rsegment_array()) . '/'; + } +} + +?> diff --git a/Source/carbon/libraries/Zip.php b/Source/carbon/libraries/Zip.php new file mode 100644 index 0000000..9593ce5 --- /dev/null +++ b/Source/carbon/libraries/Zip.php @@ -0,0 +1,258 @@ +c_add_dir($dir); + } + } + + private function c_add_dir($directory) + { + $directory = str_replace("\\", "/", $directory); + + $this->zipdata[] = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + . pack('V', 0) + . pack('V', 0) + . pack('V', 0) + . pack('v', strlen($directory)) + . pack('v', 0) + . $directory + . pack('V', 0) + . pack('V', 0) + . pack('V', 0); + + $newoffset = strlen(implode('', $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + . pack('V', 0) + . pack('V', 0) + . pack('V', 0) + . pack('v', strlen($directory)) + . pack('v', 0) + . pack('v', 0) + . pack('v', 0) + . pack('v', 0) + . pack('V', 16) + . pack('V', $this->offset) + . $directory; + + $this->offset = $newoffset; + $this->directory[] = $record; + } + + public function add_data($filepath, $data = null) + { + if (is_array($filepath)) + { + foreach ($filepath as $path => $data) + { + $this->c_add_data($path, $data); + } + } + else + { + $this->c_add_data($filepath, $data); + } + } + + private function c_add_data($filepath, $data) + { + $filepath = str_replace("\\", "/", $filepath); + + $oldlen = strlen($data); + $crc32 = crc32($data); + + $gzdata = gzcompress($data); + $gzdata = substr($gzdata, 2, -4); + $newlen = strlen($gzdata); + + $this->zipdata[] = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + . pack('V', $crc32) + . pack('V', $newlen) + . pack('V', $oldlen) + . pack('v', strlen($filepath)) + . pack('v', 0) + . $filepath + . $gzdata; + + $newoffset = strlen(implode('', $this->zipdata)); + + $record = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + . pack('V', $crc32) + . pack('V', $newlen) + . pack('V', $oldlen) + . pack('v', strlen($filepath)) + . pack('v', 0) + . pack('v', 0) + . pack('v', 0) + . pack('v', 0) + . pack('V', 32) + . pack('V', $this->offset); + + $this->offset = $newoffset; + $this->directory[] = $record . $filepath; + } + + public function read_file($path, $preserver_filepath = false) + { + if (!file_exists($path)) + { + return false; + } + + $data = file_get_contents($path); + + if ($data !== false) + { + $name = str_replace("\\", "/", $path); + + if ($preserve_filepath === false) + { + $name = preg_replace("|.*/(.+)|", "\\1", $name); + } + + $this->add_data($name, $data); + + return true; + } + + return false; + } + + public function read_dir($path) + { + $file = opendir($path); + + if ($file != false) + { + while (($file = readdir($file)) !== false) + { + if (@is_dir($path . $file) && substr($file, 0, 1) != '.') + { + $this->read_dir($path . $file . '/'); + } + elseif (substr($file, 0, 1) != '.') + { + $data = file_get_contents($path . $file); + + if ($data !== false) + { + $this->add_data(str_replace("\\", "/", $path) . $file, $data); + } + } + } + + return true; + } + } + + public function get_zip() + { + if ($this->zipfile != '') + { + return $this->zipfile; + } + + if (count($this->zipdata) == 0) + { + return false; + } + + $data = implode('', $this->zipdata); + $dir = implode('', $this->directory); + + $this->zipfile = $data . $dir . "\x50\x4b\x05\x06\x00\x00\x00\x00" + . pack('v', sizeof($this->directory)) + . pack('v', sizeof($this->directory)) + . pack('V', strlen($dir)) + . pack('V', strlen($data)) + . "\x00\x00"; + + return $this->zipfile; + } + + public function archive($filepath) + { + $file = @fopen($filepath, 'wb'); + + if ($file == false) + { + return false; + } + + flock($file, LOCK_EX); + fwrite($file, $this->get_zip()); + flock($file, LOCK_UN); + fclose($file); + + return true; + } + + public function download($filename = 'backup.zip') + { + if (!preg_match("|.+?\.zip$|", $filename)) + { + $filename .= '.zip'; + } + + if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: inline; filename="' . $filename . '"'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Content-Transfer-Encoding: binary'); + header('Pragma: public'); + header('Content-Length: ' . strlen($this->get_zip())); + } + else + { + header('Content-Type: application/x-zip'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Content-Transfer-Encoding: binary'); + header('Expires: 0'); + header('Pragma: no-cache'); + header('Content-Length: ' . strlen($this->get_zip())); + } + + echo $this->get_zip(); + } + + public function clear_data() + { + $this->zipfile = ''; + $this->zipdata = array(); + $this->directory = array(); + $this->offset = array(); + } +} + +?> diff --git a/Source/carbon/scaffolding/Scaffolding.php b/Source/carbon/scaffolding/Scaffolding.php new file mode 100644 index 0000000..fbced32 --- /dev/null +++ b/Source/carbon/scaffolding/Scaffolding.php @@ -0,0 +1,180 @@ +carbon = get_instance(); + + $this->carbon->load->database('', false, true); + $this->carbon->load->library('pagination'); + + $this->carbon->db->cache_off(); + + $this->current_table = $db_table; + + $this->carbon->load->set_view_path(CARBON_PATH . 'scaffolding/views/'); + + $this->base_url = $this->carbon->config->get_site_url() . '/' . $this->carbon->uri->segment(1) . $this->carbon->uri->slash_segment(2, 'both'); + $this->base_uri = $this->carbon->uri->segment(1) . $this->carbon->uri->slash_segment(2, 'leading'); + + $data = array( + 'image_url' => $this->carbon->config->get_system_url() . 'scaffolding/images/', + 'base_uri' => $this->base_uri, + 'base_url' => $this->base_url, + 'title' => $this->current_table + ); + + $this->carbon->load->vars($data); + + $this->lang = $this->carbon->load->scaffold_language('scaffolding', '', true); + $this->carbon->load->vars($this->lang); + + $this->carbon->load->utility(array('url', 'form')); + } + + public function add() + { + $data = array( + 'title' => (!isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'], + 'fields' => $this->carbon->db->field_data($this->current_table), + 'action' => $this->base_uri . '/insert' + ); + + $this->carbon->load->view('add', $data); + } + + public function insert() + { + if ($this->carbon->db->insert($this->current_table, $_POST) === false) + { + $this->add(); + } + else + { + redirect($this->base_uri . '/view/'); + } + } + + public function view() + { + $total_rows = $this->carbon->db->count_all($this->current_table); + + if ($total_rows < 1) + { + return $this->carbon->load->view('no_data'); + } + + $per_page = 20; + $offset = $this->carbon->uri->segment(4, 0); + + $query = $this->carbon->db->get($this->current_table, $per_page, $offset); + $fields = $this->carbon->db->list_fields($this->current_table); + $primary = current($fields); + + $pagination = array( + 'base_url' => $this->base_url . '/view', + 'total_rows' => $total_rows, + 'per_page' => $per_page, + 'uri_segment' => 4, + 'full_tag_open' => '

', + 'full_tag_close' => '

' + ); + + $this->carbon->pagination->initialise($pagination); + + $data = array( + 'title' => (!isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'], + 'query' => $query, + 'fields' => $fields, + 'primary' => $primary, + 'paginate' => $this->carbon->pagination->create_links() + ); + + $this->carbon->load->view('view', $data); + } + + public function edit() + { + $id = $this->carbon->uri->segment(4); + + if ($id === false) + { + return $this->view(); + } + + $primary = $this->carbon->db->primary($this->current_table); + $query = $this->carbon->db->getwhere($this->current_table, array($primary => $id)); + + $data = array( + 'title' => (!isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'], + 'fields' => $query->field_data(), + 'query' => $query->row(), + 'action' => $this->base_uri . '/update/' . $this->carbon->uri->segment(4) + ); + + $this->carbon->load->view('edit', $data); + } + + public function update() + { + $id = $this->carbon->uri->segment(4); + + $primary = $this->carbon->db->primary($this->current_table); + + $this->carbon->db->update($this->current_table, $_POST, array($primary => $id)); + + redirect($this->base_uri . '/view/'); + } + + public function delete() + { + if (!isset($this->lang['scaff_del_confirm'])) + { + $message = 'Are you sure you want to delete the following row: ' . $this->carbon->uri->segment(4); + } + else + { + $message = $this->lang['scaff_del_confirm'] . ' ' . $this->carbon->uri->segment(4); + } + + $data = array( + 'title' => (!isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'], + 'message' => $message, + 'no' => anchor(array($this->base_uri, 'view'), (!isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']), + 'yes' => anchor(array($this->base_uri, 'do_delete', $this->carbon->uri->segment(4)), (!isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes']) + ); + + $this->carbon->load->view('delete', $data); + } + + public function do_delete() + { + $id = $this->carbon->uri->segment(4); + $primary = $this->carbon->db->primary($this->current_table); + + $this->carbon->db->where($primary, $id); + $this->carbon->db->delete($this->current_table); + + header('Refresh:0; url=' . site_url(array($this->base_uri, 'view'))); + exit(); + } +} + +?> diff --git a/Source/carbon/scaffolding/images/background.jpg b/Source/carbon/scaffolding/images/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d5bdcea1d5b12024146ac223011123defe25635 GIT binary patch literal 410 zcwYN|6fzL4|KPi69p>!^+v> Zu|a>CQOCmw&YndUVJrload->view('header'); ?> + +

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

+ +

  |   + +load->view('footer'); ?> diff --git a/Source/carbon/scaffolding/views/edit.php b/Source/carbon/scaffolding/views/edit.php new file mode 100644 index 0000000..214d3c7 --- /dev/null +++ b/Source/carbon/scaffolding/views/edit.php @@ -0,0 +1,30 @@ +load->view('header'); ?> + +

+ + + + + + + +primary_key == 1) continue; ?> + + + + + type == 'blob'): ?> + + + + + + + +
name; ?>
+ + + + + +load->view('footer'); ?> diff --git a/Source/carbon/scaffolding/views/footer.php b/Source/carbon/scaffolding/views/footer.php new file mode 100644 index 0000000..0540643 --- /dev/null +++ b/Source/carbon/scaffolding/views/footer.php @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Source/carbon/scaffolding/views/header.php b/Source/carbon/scaffolding/views/header.php new file mode 100644 index 0000000..59adf1e --- /dev/null +++ b/Source/carbon/scaffolding/views/header.php @@ -0,0 +1,29 @@ + + + + <?php echo $title; ?> + + + + + + + + + + + + +
+ +
diff --git a/Source/carbon/scaffolding/views/no_data.php b/Source/carbon/scaffolding/views/no_data.php new file mode 100644 index 0000000..0e5e776 --- /dev/null +++ b/Source/carbon/scaffolding/views/no_data.php @@ -0,0 +1,6 @@ +load->view('header'); ?> + +

+

+ +load->view('footer'); ?> diff --git a/Source/carbon/scaffolding/views/stylesheet.css b/Source/carbon/scaffolding/views/stylesheet.css new file mode 100644 index 0000000..e8adae7 --- /dev/null +++ b/Source/carbon/scaffolding/views/stylesheet.css @@ -0,0 +1,143 @@ +body { + background: #fff url(background.jpg) repeat-x left top; + color: #4F5155; + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + margin: 0; + padding: 0; +} + +a { + color: #8B0D00; + background-color: transparent; + text-decoration: none; + font-weight: bold; +} + +a:visited { + color: #8B0D00; + background-color: transparent; + text-decoration: none; +} + +a:hover { + color: #000; + text-decoration: none; + background-color: transparent; +} + + +#header { + margin: 0; + padding: 0; +} + +#header_left { + background-color: transparent; + float: left; + padding: 21px 0 0 32px; + margin: 0; +} + +#header_right { + background-color: transparent; + float: right; + text-align: right; + padding: 35px 50px 20px 0; + margin: 0; +} + +#footer { + margin: 20px 0 15px 0; + padding: 0; +} + +#footer p { + font-size: 10px; + color: #999; + text-align: center; +} + +#outer { + margin: 30px 40px 30px 40px; +} + +img { + padding:0; + border: 0; + margin: 0; +} + +.nopad { + padding:0; + border: 0; + margin: 0; +} + +table { + background-color: #efefef; +} + +th { + background-color: #eee; + font-weight: bold; + padding: 6px; + text-align: left; +} + +td { + background-color: #fff; + padding: 6px; +} + + +form { + margin: 0; + padding: 0; +} + +.input { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 11px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + font-size: 11px; + height: 2em; + padding: 0; + margin: 0; +} + +.textarea { + font-family: Lucida Grande, Verdana, Geneva, Sans-serif; + font-size: 12px; + width: 600px; + color: #333; + border: 1px solid #B3B4BD; + padding: 0; + margin: 0; +} + +.select { + background-color: #fff; + font-size: 11px; + font-weight: normal; + color: #333; + padding: 0; + margin: 0 0 3px 0; +} + +.checkbox { + background-color: transparent; + padding: 0; + border: 0; +} + +.submit { + background-color: #8B0D00; + color: transparent; + font-weight: normal; + border: 1px solid #000; + margin: 6px 0 0 0; + padding: 1px 5px 1px 5px; +} diff --git a/Source/carbon/scaffolding/views/view.php b/Source/carbon/scaffolding/views/view.php new file mode 100644 index 0000000..8e685fb --- /dev/null +++ b/Source/carbon/scaffolding/views/view.php @@ -0,0 +1,29 @@ +load->view('header'); ?> + + + + + + + + + + + + result() as $row): ?> + + + + + + + + + + + +
EditDelete
 $primary), $scaff_edit); ?> $primary), $scaff_delete); ?>$field);?>
+ + + +load->view('footer'); ?> diff --git a/Source/carbon/utilities/filesystem_utility.php b/Source/carbon/utilities/filesystem_utility.php new file mode 100644 index 0000000..cc5c88c --- /dev/null +++ b/Source/carbon/utilities/filesystem_utility.php @@ -0,0 +1,122 @@ + 0) + { + $data =& fread($file, filesize($file)); + } + + flock($file, LOCK_UN); + fclose($file); + + return $data; +} + +function write_file($path, $data, $mode = 'wb') +{ + $file = fopen($path, $mode); + + if ($file == false) + { + return false; + } + + flock($file, LOCK_EX); + fwrite($file, $data); + flock($file, LOCK_UN); + fclose($file); + + return true; +} + +function delete_files($path, $del_dir = false, $level = 0) +{ + $path = preg_replace("|^(.+?)/*$|", "\\1", $path); + + $current_dir = @opendir($path); + + if ($current_dir == false) + { + return true; + } + + while (($filename = @readdir($current_dir)) !== false) + { + if ($filename != "." && $filename != "..") + { + if (is_dir($path . '/' . $filename)) + { + $level++; + delete_files($path . '/' . $filename, $del_dir, $level); + } + else + { + unlink($path . '/' . $filename); + } + } + } + + @closedir($current_dir); + + if ($del_dir == true && $level > 0) + { + @rmdir($path); + } +} + +function get_filenames($source_dir, $include_path = false) +{ + static $filedata = array(); + + $file = @opendir($source_dir); + + if ($file == true) + { + while (($filename = readdir($file)) !== false) + { + if (@is_dir($source_dir . $filename) && substr($filename, 0, 1) != '.') + { + get_filenames($source_dir . $filename . '/', $include_path); + } + elseif (substr($filename, 0, 1) != ".") + { + $filedata[] = ($include_path == true) ? $source_dir . $filename : $filename; + } + } + + return $filedata; + } +} + +?> diff --git a/Source/carbon/utilities/form_utility.php b/Source/carbon/utilities/form_utility.php new file mode 100644 index 0000000..af6b67e --- /dev/null +++ b/Source/carbon/utilities/form_utility.php @@ -0,0 +1,265 @@ +config->get_site_url($action) . '"'; + + if (!isset($attributes['method'])) + { + $form .= ' method="post"'; + } + + if (is_array($attributes) && count($attributes) > 0) + { + foreach ($attributes as $key => $val) + { + $form .= ' ' . $key . '="' . $val . '"'; + } + } + + $form .= '>'; + + if (is_array($hidden) && count($hidden) > 0) + { + $form .= form_hidden($hidden); + } + + return $form; +} + +function form_open_multipart($action, $attributes = array(), $hidden = array()) +{ + $attributes['enctype'] = 'multipart/form-data'; + + return form_open($action, $attributes, $hidden); +} + +function form_hidden($name, $value = '') +{ + if (!is_array($name)) + { + return ''; + } + + $form = ''; + + foreach ($name as $name => $value) + { + $form .= ''; + } + + return $form; +} + +function form_input($data = '', $value = '', $extra = '') +{ + $defaults = array( + 'type' => 'text', + 'name' => ((!is_array($data)) ? $data : ''), + 'value' => $value, + 'maxlength' => '500', + 'size' => '50' + ); + + return "\n"; +} + +function form_password($data = '', $value = '', $extra = '') +{ + if (!is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'password'; + + return form_input($data, $value, $extra); +} + +function form_upload($data = '', $value = '', $extra = '') +{ + if (!is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'file'; + + return form_input($data, $value, $extra); +} + +function form_textarea($data = '', $value = '', $extra = '') +{ + $defaults = array( + 'name' => ((!is_array($data)) ? $data : ''), + 'cols' => '90', + 'rows' => '12' + ); + + if (!is_array($data) || !isset($data['value'])) + { + $val = $value; + } + else + { + $val = $data['value']; + unset($data['value']); + } + + return "\n"; +} + +function form_dropdown($name = '', $options = array(), $selected = '', $extra = '') +{ + if ($extra != '') + { + $extra = ' ' . $extra; + } + + $form = ''; + + return $form; +} + +function form_checkbox($data = '', $value = '', $checked = true, $extra = '') +{ + $defaults = array( + 'type' => 'checkbox', + 'name' => ((!is_array($data)) ? $data : ''), + 'value' => $value + ); + + if (is_array($data) && array_key_exists('checked', $data)) + { + $checked = $data['checked']; + + if ($checked == false) + { + unset($data['checked']); + } + else + { + $data['checked'] = 'checked'; + } + } + + if ($checked == true) + { + $defaults['checked'] = 'checked'; + } + else + { + unset($defaults['checked']); + } + + return "\n"; +} + +function form_radio($data = '', $value = '', $checked = true, $extra = '') +{ + if (!is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'radio'; + + return form_checkbox($data, $value, $checked, $extra); +} + +function form_submit($data = '', $value = '', $extra = '') +{ + $defaults = array( + 'type' => 'submit', + 'name' => ((!is_array($data)) ? $data : ''), + 'value' => $value + ); + + return "\n"; +} + +function form_close($extra = '') +{ + return "\n" . $extra; +} + +function form_prep($string = '') +{ + if ($string === '') + { + return ''; + } + + $temp = '__TEMP_AMPERSANDS__'; + + $string = preg_replace("/&#(\d+);/", "$temp\\1;", $string); + $stirng = preg_replace("/&(\w+);/", "$temp\\1;", $string); + + $string = htmlspecialchars($string); + + $string = str_replace(array("'", '"'), array("'", """), $string); + + $string = preg_replace("/$temp(\d+);/", "&#\\1;", $string); + $string = preg_replace("/$temp(\w+);/", "&\\1;", $string); + + return $string; +} + +function parse_form_attributes($attributes, $default) +{ + if (is_array($attributes)) + { + foreach ($default as $key => $val) + { + if (isset($attributes[$key])) + { + $default[$key] = $attributes[$key]; + unset($attributes[$key]); + } + } + + if (count($attributes) > 0) + { + $default = array_merge($default, $attributes); + } + } + + $attr = ''; + + foreach ($default as $key => $val) + { + if ($key == 'value') + { + $val = form_prep($val); + } + + $attr .= $key . '="' . $val . '" '; + } + + return $attr; +} + +?> diff --git a/Source/carbon/utilities/url_utility.php b/Source/carbon/utilities/url_utility.php new file mode 100644 index 0000000..a910b45 --- /dev/null +++ b/Source/carbon/utilities/url_utility.php @@ -0,0 +1,376 @@ +config->get_site_url($uri); +} + +function base_url() +{ + $carbon =& get_instance(); + + return $carbon->config->slash_item('base_url'); +} + +function index_page() +{ + $carbon =& get_instance(); + + return $carbon->config->get_item_value('index_page'); +} + +function anchor($uri = '', $title = '', $attributes = '') +{ + $title = (string) $title; + + if (!is_array($uri)) + { + $site_url = (!preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + } + else + { + $site_url = site_url($uri); + } + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes == '') + { + $attributes = ' title="' . $title . '"'; + } + else + { + $attributes = parse_attributes($attributes); + } + + return '' . $title . ''; +} + +function anchor_popup($uri = '', $title = '', $attributes = false) +{ + $title = (string) $title; + $site_url (!preg_match('!^\w+://!i', $uri)) ? site_url($uri) : $uri; + + if ($title == '') + { + $title = $site_url; + } + + if ($attributes === false) + { + return "" . $title . ""; + } + + if (!is_array($attributes)) + { + $attributes = array(); + } + + $default = array( + 'width' => '800', + 'height' => '600', + 'scrollbars' => 'yes', + 'status' => 'yes', + 'resizable' => 'yes', + 'screenx' => '0', + 'screeny' => '0' + ); + + foreach ($default as $key => $val) + { + $attr[$key] = (!isset($attributes[$key])) ? $val : $attributes[$key]; + } + + return "" . $title . ""; +} + +function mailto($email, $title = '', $attributes = '') +{ + $title = (string) $title; + + if ($title == '') + { + $title = $email; + } + + $attributes = parse_attributes($attributes); + + return '' . $title . ''; +} + +function safe_mailto($email, $title = '', $attributes = '') +{ + $title = (string) $title; + + if ($title == '') + { + $title = $email; + } + + for ($i = 0; $i < 16; $i++) + { + $x[] = substr(' $val) + { + $x[] = ' ' . $key . '="'; + + for ($i = 0; $i < strlen($val); $i++) + { + $x[] = '|' . ord(substr($val, $i, 1)); + } + + $x[] = '"'; + } + } + else + { + for ($i = 0; $i < strlen($attributes); $i++) + { + $x[] = substr($attributes, $i, 1); + } + } + } + + $x[] = '>'; + + $temp = array(); + + for ($i = 0; $i < strlen($title); $i++) + { + $ordinal = ord($title[$i]); + + if ($ordinal < 128) + { + $x[] = '|' . $ordinal; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + $x[] = '|' . $number; + $count = 1; + $temp = array(); + } + } + } + + $x[] = '<'; + $x[] = '/'; + $x[] = 'a'; + $x[] = '>'; + + $x = array_reverse($x); + + ob_start(); +?> + + + +http' . + $matches['4'][$i] . '://' . + $matches['5'][$i] . + $matches['6'][$i] . '' . + $period, $string); + } + } + } + + if ($type != 'url') + { + if (preg_match_all("/([a-zA-Z0-9_\.\-]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $string, $matches)) + { + for ($i = 0; $i < sizeof($matches['0']); $i++) + { + $period = '.'; + $matches['3'][$i] = substr($matches['3'][$i], 0, -1); + } + + $string = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i] . '@' . $matches['2'][$i] . '.' . $matches['3'][$i]) . $period, $string); + } + } + + return $string; +} + +function prep_url($string = '') +{ + if ($string == 'http://' || $string == '') + { + return ''; + } + + if (substr($string, 0, 7) != 'http://' && substr($string, 0, 8) != 'https://') + { + $string = 'http://' . $string; + } + + return $string; +} + +function url_title($string, $separator = 'dash') +{ + if ($separator == 'dash') + { + $search = '_'; + $replace = '-'; + } + else + { + $search = '-'; + $replace = '_'; + } + + $trans = array( + $search => $replace, + "\s+" => $replace, + "[^a-z0-9]" . $replace . "]" => '', + $replace . "+" => $replace, + $replace . "$" => '', + "^" . $replace => '' + ); + + $string = strip_tags(strtolower($string)); + + foreach ($trans as $key => $val) + { + $string = preg_replace("#" . $key . "#", $val, $string); + } + + return trim(stripslashes($string)); +} + +function redirect($uri = '', $method = 'location') +{ + switch ($method) + { + case 'refresh': + header('Refresh:0; url= ' . site_url($uri)); + break; + + default: + header('Location: ' . site_url($uri)); + break; + } + + exit(); +} + +function parse_attributes($attributes, $javascript = false) +{ + if (is_string($attributes)) + { + return ($attributes != '') ? ' ' . $attributes : ''; + } + + $attr = ''; + + foreach ($attributes as $key => $val) + { + if ($javascript == true) + { + $attr .= $key . '=' . $val . ','; + } + else + { + $attr .= ' ' . $key . '="' . $val . '"'; + } + } + + if ($javascript == true && $attr != '') + { + $attr = substr($attr, 0, -1); + } + + return $attr; +} + +?> diff --git a/Source/carbon/utilities/uuid_utility.php b/Source/carbon/utilities/uuid_utility.php new file mode 100644 index 0000000..b159de9 --- /dev/null +++ b/Source/carbon/utilities/uuid_utility.php @@ -0,0 +1,24 @@ + diff --git a/Source/carbon/utilities/xml_utility.php b/Source/carbon/utilities/xml_utility.php new file mode 100644 index 0000000..ded9523 --- /dev/null +++ b/Source/carbon/utilities/xml_utility.php @@ -0,0 +1,25 @@ +", "\"", "'", "-"), array("&", "<", ">", """, "'", "-"), $string); + $string = preg_replace("/$temp(\d+);/", "&#\\1;", $string); + $string = preg_replace("/$temp(\w+);/", "&\\1;", $string); + + return $string; +} + +?> diff --git a/Source/index.php b/Source/index.php new file mode 100644 index 0000000..400894f --- /dev/null +++ b/Source/index.php @@ -0,0 +1,37 @@ + diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..6d2e7a6 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,41 @@ +CarbonPHP (C) Tom Bell 2007 +http://tombell.org.uk + +CarbonPHP 2.0 +- Began implementation of new directory structure + +CarbonPHP 0.3.0 +- Began implementation for PHP6 support +- Added: MSSQL database driver mssql_driver.php +- Added: MSSQL database results driver mssql_result.php +- Added: MSSQL database utilities driver mssql_utility.php +- Changed: carbonPHP to CarbonPHP +- Changed: Call time pass by references (=& to =) +- Removed: Carbon_Core.php set_magic_quotes_runtime() + + +CarbonPHP 0.2.0 + +- Added: benchmark library +- Added: pagination library +- Added: table library +- Added: form utilities +- Added: URL utilities +- Added: database scaffolding +- Added: comments to configuration files +- Added: input library +- Added: extension library +- Added: Remapping code +- Added: Output overriding code +- Added: uuid generating utility +- Fixed: Database_active_record.php (Incorrect method name called) +- Fixed: Database_active_record.php (Missing space within query) +- Fixed: loader.php (Incorrect method name called) +- Fixed: loader.php (Changed loaded_view_path member to public) +- Fixed: Carbon_Core.php (Added @ to include() call) +- Fixed: Router.php (Set scaffolding_request to private, and added a method is_scaffolding_request()) +- Fixed: Controller.php (Set scaffolding members to private, and added setter methods) +- Fixed: Router.php (Added a missing $ on a variable) +- Fixed: form_utility.php (Corrected variable name) +- Fixed: Pagination.php (Corrected variable name) +- Fixed: Router.php (Corrected a typo) -- 2.11.4.GIT