From 1caf1cceb4142693de059db96a9ccce03cba0c94 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Thu, 27 Sep 2018 10:31:34 -0700 Subject: [PATCH 1/4] Release prep part 1 --- admin/release | 1 + system/View/Parser.php | 2 +- tests/_support/HTTP/MockResponse.php | 2 +- user_guide_src/autodoc.php | 333 ------------------ user_guide_src/source/changelog.rst | 7 +- user_guide_src/source/general/helpers.rst | 2 +- user_guide_src/source/index.rst | 1 - .../source/installation/upgrade_4xx.rst | 208 ++++++----- .../source/libraries/validation.rst | 2 +- 9 files changed, 108 insertions(+), 450 deletions(-) delete mode 100644 user_guide_src/autodoc.php diff --git a/admin/release b/admin/release index 6f6f82bb9cd5..0625bac77018 100755 --- a/admin/release +++ b/admin/release @@ -47,6 +47,7 @@ echo -e "${BOLD}Creating $which $branch to $action ${NORMAL}" git checkout develop git branch -d $branch # remove the branch if there git checkout -b $branch +composer update #--------------------------------------------------- # Update version dependencies diff --git a/system/View/Parser.php b/system/View/Parser.php index 1fc36fdc8b3d..63d76f7177bd 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -44,7 +44,7 @@ * ClassFormerlyKnownAsTemplateParser * * @todo Views\Parser_Test - * @tofo Common::parse + * @todo Common::parse * @todo user guide * @todo options -> delimiters * diff --git a/tests/_support/HTTP/MockResponse.php b/tests/_support/HTTP/MockResponse.php index f995444ec33a..01e7b3e4d948 100755 --- a/tests/_support/HTTP/MockResponse.php +++ b/tests/_support/HTTP/MockResponse.php @@ -45,7 +45,7 @@ public function setCookie( $_COOKIE[$prefix . $name] = $value; /* - TODO: Find a way to use setcookie() + @todo: Find a way to use setcookie() without it throwing header issues. setcookie ( diff --git a/user_guide_src/autodoc.php b/user_guide_src/autodoc.php deleted file mode 100644 index 498a67fe67fb..000000000000 --- a/user_guide_src/autodoc.php +++ /dev/null @@ -1,333 +0,0 @@ -initialize(new Autoload()); -$loader->register(); - -//-------------------------------------------------------------------- -// The Class -//-------------------------------------------------------------------- - -/** - * Class Document - * - * Represents a single document, and provides a simple workflow to - * read in a source file, generate the results, and then write it out: - * - * Example: - * $doc = new Document(); - * $doc->readSource('path/to/file.php') - * ->build() - * ->writeTo('user_guide_src/source/...'); - */ -class Document -{ - protected $source; - protected $destination; - - /** - * @var string The current text of the parsed docComment, if any. - */ - protected $currentDocString; - protected $currentDocAttributes = []; - - public $prose = ''; - - //-------------------------------------------------------------------- - - public function readSource(string $source) - { - if (! is_file($source)) - { - CLI::error('Not a valid source file: '. $source); - die(); - } - - $this->source = $source; - - return $this; - } - - //-------------------------------------------------------------------- - - public function writeTo(string $dest) - { - if (file_exists($dest)) - { - if ('n' == CLI::prompt('Destination exists. Overwrite?', ['y', 'n'])) - { - die(); - } - } - - if (strpos($dest, 'user_guide_src/source/') !== false) - { - $dest = substr($dest, strlen('user_guide_src/source/')); - } - - str_ireplace('.rst', '', $dest); - - $dest = dirname(__FILE__).'/source/'.$dest.'.rst'; - - if (! $fp = fopen($dest, 'wb')) - { - die('Unable to write to: '. $dest); - } - - fwrite($fp, $this->prose."\n"); - fclose($fp); - } - - //-------------------------------------------------------------------- - - /** - * @todo Needs to describe interface and parent methods? - * @todo Needs to describe parent class, if any - * @param string $className - */ - public function build(string $className) - { - require_once $this->source; - - $mirror = new ReflectionClass($className); - - $this->parseDocComment($mirror->getDocComment(), 0); - - $namespace = $mirror->getNamespaceName(); - $className = str_replace($namespace.'\\', '', $mirror->getName()); - $namespace = str_replace('\\', '\\\\', $namespace); - - $output = $className." Class\n"; - $output .= str_repeat('#', strlen($output))."\n\n"; - - $output .= $this->currentDocString."\n"; - - $output .= ".. php:class:: ". $namespace.'\\\\'.$className."\n\n"; - - $output .= $this->describeInterfaces($mirror); - - $methods = $mirror->getMethods(); - - foreach ($methods as $methodMirror) - { - $output .= $this->describeMethod($methodMirror); - } - - $this->prose = $output; - } - - //-------------------------------------------------------------------- - - public function describeInterfaces(ReflectionClass $mirror): string - { - $interfaces = $mirror->getInterfaceNames(); - - if (! count($interfaces)) return ''; - - $output = "\tImplements: ". implode(', ', $interfaces); - - return $output."\n\n"; - } - - //-------------------------------------------------------------------- - - - /** - * @param $methodMirror - * - * @return string - */ - protected function describeMethod(ReflectionMethod $methodMirror): string - { - if ($methodMirror->isProtected() || $methodMirror->isPrivate()) return ''; - - $this->parseDocComment($methodMirror->getDocComment(), 2); - - $output = "\t.. php:method:: ".$methodMirror->name." ( "; - - $output .= $this->buildParameterList($methodMirror->getParameters()) ." )\n\n"; - - $output .= $this->describeParameters($methodMirror->getParameters()); - - if ($methodMirror->hasReturnType()) - { - $output .= "\t\t:returns: \n\t\t:rtype: {$methodMirror->getReturnType()}"; - } - - $output .= "\n\n"; - - $output .= $this->currentDocString."\n\n"; - - return $output; - } - - //-------------------------------------------------------------------- - - protected function buildParameterList(array $params=[]): string - { - if (! count($params)) return ''; - - $output = ''; - $optionalCount = 0; - - foreach ($params as $paramMirror) - { - if ($paramMirror->isOptional()) - { - $output .= $optionalCount > 0 ? "[, " : "[ "; - ++$optionalCount; - } - - if ($paramMirror->hasType()) - { - $output .= (string)$paramMirror->getType()." "; - } - - if ($paramMirror->isPassedByReference()) $output .= "&"; - - if ($paramMirror->isVariadic()) $output .= "..."; - - $output .= "\${$paramMirror->getName()} "; - } - - if ($optionalCount > 0) - { - $output .= str_repeat(']', $optionalCount); - } - - return $output; - } - - //-------------------------------------------------------------------- - - protected function describeParameters(array $params = []): string - { - if (! count($params)) return ''; - - $output = ''; - - foreach ($params as $paramMirror) - { - $output .= "\t\t:param "; - - if ($paramMirror->hasType()) - { - $output .= $paramMirror->getType()." "; - } - - $output .= "\${$paramMirror->getName()}: \n"; - } - - return $output; - } - - //-------------------------------------------------------------------- - - protected function parseDocComment(string $docblock, $nesting=0) - { - $this->currentDocString = ''; - $this->currentDocAttributes = []; - - $lines = explode("\n", $docblock); - - $output = ''; - $attributes = []; - - foreach ($lines as $line) - { - $line = trim($line); - - if ($line == '/**' || $line == '*/') continue; - - if ($line == '*') - { - $output .= "\n"; - continue; - } - - $line = trim($line); - - if (substr($line, 0, 1) == '*') - { - $line = trim(substr($line, 1)); - } - - if (substr($line, 0, 1) == '@') - { - $tempLine = trim(substr($line, 1)); - $segments = explode(' ', $tempLine); - - $att = [ - 'paramType' => array_shift($segments), - 'valueType' => array_shift($segments) - ]; - - if (count($segments)) $att['valueName'] = array_shift($segments); - if (count($segments)) $att['valueDesc'] = implode(' ', $segments); - - $attributes[] = $att; - continue; - } - - $output .= str_repeat("\t", $nesting)."{$line}\n"; - } - - $this->currentDocString = $output; - $this->currentDocAttributes = $attributes; - } - - //-------------------------------------------------------------------- - -} - -//-------------------------------------------------------------------- -// Take Input and make it work -//-------------------------------------------------------------------- - -$source_file = CLI::prompt('Source file'); -$source_file = realpath($source_file); - -if (empty($source_file)) -{ - CLI::error('Unable to locate the source file.'); - die(); -} - -/* - * Try to determine the class name based on the file - */ -$class_name = 'CodeIgniter\\'. str_ireplace(realpath(BASEPATH).'/', '', $source_file); -$class_name = str_replace('.php', '', $class_name); -$class_name = str_replace('/', '\\', $class_name); - -$doc = new Document(); -$doc->readSource(realpath($source_file))->build($class_name); - -$dest_file = CLI::prompt('Destination in user_guide_src'); - -$doc->writeTo($dest_file); - -CLI::write('Done'); diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 6a43c2cb713b..b0df6ee34fcf 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -9,6 +9,11 @@ Release Date: Not Released **Rewrite of the CodeIgniter framework** +Non-code changes: + - User Guide adapted or rewritten + - [System message translations repository](https://github.com/bcit-ci/CodeIgniter4-translations) + - [Roadmap subforum](https://forum.codeigniter.com/forum-33.html) for more transparent planning + New core classes: - CodeIgniter (bootstrap) - Common (shared functions) @@ -101,5 +106,3 @@ New packages: - \\ CreditCardRules, FileRules, FormatRules, Rules, Validation, ValidationInterface - View - \\ Cell, Filters, Parser, Plugins, RendererInterface, View - -User Guide adapted or rewritten. diff --git a/user_guide_src/source/general/helpers.rst b/user_guide_src/source/general/helpers.rst index 105721aa0495..09a6580001b3 100644 --- a/user_guide_src/source/general/helpers.rst +++ b/user_guide_src/source/general/helpers.rst @@ -100,7 +100,7 @@ URI to the controller/method you wish to link to. "Extending" Helpers =================== -TODO: Determine how these can be extended... namespaces, etc? +@todo: Determine how these can be extended... namespaces, etc? To "extend" Helpers, create a file in your **application/helpers/** folder with an identical name to the existing Helper, but prefixed with **MY\_** diff --git a/user_guide_src/source/index.rst b/user_guide_src/source/index.rst index 45df559347d6..4233873f7d3f 100644 --- a/user_guide_src/source/index.rst +++ b/user_guide_src/source/index.rst @@ -13,7 +13,6 @@ Getting Started *************** .. toctree:: - :includehidden: :maxdepth: 2 :titlesonly: diff --git a/user_guide_src/source/installation/upgrade_4xx.rst b/user_guide_src/source/installation/upgrade_4xx.rst index 8edea4b538d6..a86a0d8a0104 100644 --- a/user_guide_src/source/installation/upgrade_4xx.rst +++ b/user_guide_src/source/installation/upgrade_4xx.rst @@ -1,114 +1,102 @@ -TODO: rewrite for CodeIgniter4 - ############################# Upgrading from 3.x to 4.x ############################# -Before performing an update you should take your site offline by -replacing the index.php file with a static one. - -Step 1: Update your CodeIgniter files -===================================== - -Replace all files and directories in your *system/* directory. - -.. note:: If you have any custom developed files in these directories, - please make copies of them first. - -Step 2: Change database connection handling -=========================================== - -"Loading" a database, whether by using the *config/autoload.php* settings -or manually via calling ``$this->load->database()`` or the less-known -``DB()`` function, will now throw a ``RuntimeException`` in case of a -failure. - -In addition, being unable to set the configured character set is now also -considered a connection failure. - -.. note:: This has been the case for most database drivers in the in the - past as well (i.e. all but the 'mysql', 'mysqli' and 'postgre' - drivers). - -What this means is that if you're unable to connect to a database, or -have an erroneous character set configured, CodeIgniter will no longer -fail silently, but will throw an exception instead. - -You may choose to explicitly catch it (and for that purpose you can't use -*config/autoload.php* to load the :doc:`Database Class <../database/index>`) -:: - - try - { - $this->load->database(); - } - catch (RuntimeException $e) - { - // Handle the failure - } - -Or you may leave it to CodeIgniter's default exception handler, which would -log the error message and display an error screen if you're running in -development mode. - -Remove db_set_charset() calls ------------------------------ - -With the above-mentioned changes, the purpose of the ``db_set_charset()`` -method would now only be to change the connection character set at runtime. -That doesn't make sense and that's the reason why most database drivers -don't support it at all. -Thus, ``db_set_charset()`` is no longer necessary and is removed. - -Step 3: Check logic related to URI parsing of CLI requests -========================================================== - -When running a CodeIgniter application from the CLI, the -:doc:`URI Library <../libraries/uri>` will now ignore the -``$config['url_suffix']`` and ``$config['permitted_uri_chars']`` -configuration settings. - -These two options don't make sense under the command line (which is why -this change was made) and therefore you shouldn't be affected by this, but -if you've relied on them for some reason, you'd probably have to make some -changes to your code. - -Step 4: Check Cache Library configurations for Redis, Memcache(d) -================================================================= - -The new improvements for the 'redis' and 'memcached' drivers of the -:doc:`Cache Library <../libraries/caching>` may require some small -adjustments to your configuration values ... - -Redis ------ - -If you're using the 'redis' driver with a UNIX socket connection, you'll -have to move the socket path from ``$config['socket']`` to -``$config['host']`` instead. - -The ``$config['socket_type']`` option is also removed, although that won't -affect your application - it will be ignored and the connection type will -be determined by the format used for ``$config['host']`` instead. - -Memcache(d) ------------ - -The 'memcached' will now ignore configurations that don't specify a ``host`` -value (previously, it just set the host to the default '127.0.0.1'). - -Therefore, if you've added a configuration that only sets e.g. a ``port``, -you will now have to explicitly set the ``host`` to '127.0.0.1' as well. - -Step 5: Check usage of doctype() HTML helper -============================================ - -The :doc:`HTML Helper <../helpers/html_helper>` function -:php:func:`doctype()` used to default to 'xhtml1-strict' (XHTML 1.0 Strict) -when no document type was specified. That default value is now changed to -'html5', which obviously stands for the modern HTML 5 standard. - -Nothing should be really broken by this change, but if your application -relies on the default value, you should double-check it and either -explicitly set the desired format, or adapt your front-end to use proper -HTML 5 formatting. \ No newline at end of file +CodeIgniter 4 is a rewrite of the framework, and is not backwards compatible. +It is more appropriate to think of converting your app, rather than upgrading it. +Once you have done that, upgrading from one version of CodeIgniter 4 to the next +will be straightforward. + +The "lean, mean and simple" philosophy has been retained, but the +implementation has a lot of differences, compared to CodeIgniter 3. + +There is no 12-step checklist for upgrading. Instead, start with a copy +of CodeIgniter 4 in a new project folder, `however you wish to install and +use it `_, +and then convert and integrate your app components. +We'll try to point out the most important considerations here. + +Not all of the CI3 libraries have been ported or rewritten for CI4! +See the threads in the `CodeIgniter 4 Roadmap `_ +subforum for an uptodate list! + +**Downloads** +- CI4 is still available as a ready-to-run zip or tarball, which +includes the user guide (though in the `docs` subfolder +- It can also be installed using Composer + +**Namespaces** +- CI4 is built for PHP7.1+, and everything in the framework is namespaced, even the helpers + +**Application Structure** +- The framework still has `application` and `system` folders, with the same +interpretation as before +- The framework now provides for a `public` folder, intended as the document +root for your app +- There is also a `writable` folder, to hold cache data, logs, and session data +- The `application` folder looks very similar to that for CI3, with some +name changes (eg Filters instead of hooks) and capitalization, and some subfolders +moved to the `writable` folder +- There is no longer a nested `application/core` folder, as we have +a different mechanism for extending framework components (see below) + +**Class loading** +- There is no longer a CodeIgniter superobject, with framework component +references magically as properties of your controller +- Classes are instantiated where needed, and components are managed +by `Services` +- The class loader automatically handles PSR4 style class locating, +within the `App` (application) and `CodeIgniter` (i.e. system) top level +namespaces; with composer autoloading support, and even using educated +guessing to find your models and libraries if they are in the right +folder even though not namespaced +- You can configure the class loading to support whatever application structure +you are most comfortable with, including the "HMVC" style + +**Controllers** +- Controllers extend \CodeIgniter\Controller instead of CI_Controller +- They don't use a constructor any more (to invoke CI "magic"); they +instead call `initController` +- CI provides `Request` and `Response` objects for you to work with - +more powerful than the CI3-way +- If you want a base controller (MY_Controller in CI3), make it +where you like, e.g. BaseController extends Controller, and then +have your controllers extend it + +**Models** +- Models extend \CodeIgniter\Model instead of CI_Model +- The CI4 model has much more functionality, including automatic +database connection, basic CRUD, in-model validation, and +automatic pagination +- CI4 also has the `Entity` class you can build on, for +richer data mapping to your database tables +- Instead of CI3's `$this->load->model(x);`, you would now use +`$this->x = new X();`, providing the fully-qualified path +of your component + +**Views** +- Your views look much like before, but they are invoked differently ... +instead of CI3's `$this->load->view(x);` you can use `view(x);` +- CI4 supports view "cells", to build your response in pieces +- The template parser is still there, but substantially +enhanced + +**Libraries** +- Your app classes can still go inside `application\Libraries`, but they +don't have to +- Instead of CI3's `$this->load->library(x);` you can now use +`$this->x = new X();`, providing the fully-qualified path of your +component + +**Helpers** +- Helpers are pretty much the same as before, except that instead +of `$this->load->helper(x);` you would now use `helper(x);` + +**Extending the framework** +- You don't need a `core` folder to hold `MY_...` framework +component extensions or replacements +- You don't need `MY_x` classes inside your libraries folder +to extend or replace CI4 pieces +- Make any such classes where you like, and add appropriate +service methods in `application/Config/Services.php` to load +your components instead of the default ones diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 80f0957d91c8..baf1bf172179 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -398,7 +398,7 @@ custom error messages, and retrieve one or more errors to display. By default, error messages are derived from language strings in ``system/Language/en/Validation.php``, where each rule has an entry. -**TODO: Determine how to easily add custom rule messages.** +@todo: Determine how to easily add custom rule messages.** .. _validation-custom-errors: From 3cb4e17a8a2474470b32971ad00dba84a5c06a59 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Thu, 27 Sep 2018 11:33:19 -0700 Subject: [PATCH 2/4] Improve the upgrading guide --- user_guide_src/source/installation/upgrade_4xx.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/user_guide_src/source/installation/upgrade_4xx.rst b/user_guide_src/source/installation/upgrade_4xx.rst index a86a0d8a0104..2bf3365231b8 100644 --- a/user_guide_src/source/installation/upgrade_4xx.rst +++ b/user_guide_src/source/installation/upgrade_4xx.rst @@ -35,7 +35,7 @@ interpretation as before root for your app - There is also a `writable` folder, to hold cache data, logs, and session data - The `application` folder looks very similar to that for CI3, with some -name changes (eg Filters instead of hooks) and capitalization, and some subfolders +name changes, and some subfolders moved to the `writable` folder - There is no longer a nested `application/core` folder, as we have a different mechanism for extending framework components (see below) @@ -55,8 +55,8 @@ you are most comfortable with, including the "HMVC" style **Controllers** - Controllers extend \CodeIgniter\Controller instead of CI_Controller -- They don't use a constructor any more (to invoke CI "magic"); they -instead call `initController` +- They don't use a constructor any more (to invoke CI "magic") unless +that is part of a bvase controller you make - CI provides `Request` and `Response` objects for you to work with - more powerful than the CI3-way - If you want a base controller (MY_Controller in CI3), make it @@ -76,7 +76,7 @@ of your component **Views** - Your views look much like before, but they are invoked differently ... -instead of CI3's `$this->load->view(x);` you can use `view(x);` +instead of CI3's `$this->load->view(x);` you can use `echo view(x);` - CI4 supports view "cells", to build your response in pieces - The template parser is still there, but substantially enhanced @@ -89,8 +89,7 @@ don't have to component **Helpers** -- Helpers are pretty much the same as before, except that instead -of `$this->load->helper(x);` you would now use `helper(x);` +- Helpers are pretty much the same as before, though some have been simplified **Extending the framework** - You don't need a `core` folder to hold `MY_...` framework From e64d3c297d2170a62dbb16c0981e4b104e6a4758 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Thu, 27 Sep 2018 11:44:19 -0700 Subject: [PATCH 3/4] Removed some todos --- system/View/Parser.php | 5 ----- user_guide_src/source/libraries/validation.rst | 2 -- 2 files changed, 7 deletions(-) diff --git a/system/View/Parser.php b/system/View/Parser.php index 63d76f7177bd..c3a0273a1c67 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -43,11 +43,6 @@ * * ClassFormerlyKnownAsTemplateParser * - * @todo Views\Parser_Test - * @todo Common::parse - * @todo user guide - * @todo options -> delimiters - * * @package CodeIgniter\View */ class Parser extends View diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index baf1bf172179..00558b534f24 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -398,8 +398,6 @@ custom error messages, and retrieve one or more errors to display. By default, error messages are derived from language strings in ``system/Language/en/Validation.php``, where each rule has an entry. -@todo: Determine how to easily add custom rule messages.** - .. _validation-custom-errors: Setting Custom Error Messages From cddddd98d347e32da984cda4b99dce5dc6fbd267 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Thu, 27 Sep 2018 11:59:57 -0700 Subject: [PATCH 4/4] Clean up the guide --- .../source/installation/upgrade_4xx.rst | 103 ++++++++++-------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/user_guide_src/source/installation/upgrade_4xx.rst b/user_guide_src/source/installation/upgrade_4xx.rst index 2bf3365231b8..740630a22e5d 100644 --- a/user_guide_src/source/installation/upgrade_4xx.rst +++ b/user_guide_src/source/installation/upgrade_4xx.rst @@ -11,8 +11,8 @@ The "lean, mean and simple" philosophy has been retained, but the implementation has a lot of differences, compared to CodeIgniter 3. There is no 12-step checklist for upgrading. Instead, start with a copy -of CodeIgniter 4 in a new project folder, `however you wish to install and -use it `_, +of CodeIgniter 4 in a new project folder, +:doc:`however you wish to install and use it `, and then convert and integrate your app components. We'll try to point out the most important considerations here. @@ -20,82 +20,93 @@ Not all of the CI3 libraries have been ported or rewritten for CI4! See the threads in the `CodeIgniter 4 Roadmap `_ subforum for an uptodate list! +**Do read the user guide** before embarking on a project conversion! + **Downloads** + - CI4 is still available as a ready-to-run zip or tarball, which -includes the user guide (though in the `docs` subfolder + includes the user guide (though in the `docs` subfolder - It can also be installed using Composer **Namespaces** + - CI4 is built for PHP7.1+, and everything in the framework is namespaced, even the helpers **Application Structure** -- The framework still has `application` and `system` folders, with the same -interpretation as before -- The framework now provides for a `public` folder, intended as the document -root for your app -- There is also a `writable` folder, to hold cache data, logs, and session data -- The `application` folder looks very similar to that for CI3, with some -name changes, and some subfolders -moved to the `writable` folder -- There is no longer a nested `application/core` folder, as we have -a different mechanism for extending framework components (see below) + +- The framework still has ``application`` and ``system`` folders, with the same + interpretation as before +- The framework now provides for a ``public`` folder, intended as the document + root for your app +- There is also a ``writable`` folder, to hold cache data, logs, and session data +- The ``application`` folder looks very similar to that for CI3, with some + name changes, and some subfolders + moved to the ``writable`` folder +- There is no longer a nested ``application/core`` folder, as we have + a different mechanism for extending framework components (see below) **Class loading** -- There is no longer a CodeIgniter superobject, with framework component -references magically as properties of your controller + +- There is no longer a CodeIgniter "superobject", with framework component + references magically injected as properties of your controller - Classes are instantiated where needed, and components are managed -by `Services` + by ``Services`` - The class loader automatically handles PSR4 style class locating, -within the `App` (application) and `CodeIgniter` (i.e. system) top level -namespaces; with composer autoloading support, and even using educated -guessing to find your models and libraries if they are in the right -folder even though not namespaced + within the ``App`` (application) and ``CodeIgniter`` (i.e. system) top level + namespaces; with composer autoloading support, and even using educated + guessing to find your models and libraries if they are in the right + folder even though not namespaced - You can configure the class loading to support whatever application structure -you are most comfortable with, including the "HMVC" style + you are most comfortable with, including the "HMVC" style **Controllers** + - Controllers extend \CodeIgniter\Controller instead of CI_Controller - They don't use a constructor any more (to invoke CI "magic") unless -that is part of a bvase controller you make -- CI provides `Request` and `Response` objects for you to work with - -more powerful than the CI3-way + that is part of a base controller you make +- CI provides ``Request`` and ``Response`` objects for you to work with - + more powerful than the CI3-way - If you want a base controller (MY_Controller in CI3), make it -where you like, e.g. BaseController extends Controller, and then -have your controllers extend it + where you like, e.g. BaseController extends Controller, and then + have your controllers extend it **Models** + - Models extend \CodeIgniter\Model instead of CI_Model - The CI4 model has much more functionality, including automatic -database connection, basic CRUD, in-model validation, and -automatic pagination -- CI4 also has the `Entity` class you can build on, for -richer data mapping to your database tables -- Instead of CI3's `$this->load->model(x);`, you would now use -`$this->x = new X();`, providing the fully-qualified path -of your component + database connection, basic CRUD, in-model validation, and + automatic pagination +- CI4 also has the ``Entity`` class you can build on, for + richer data mapping to your database tables +- Instead of CI3's ``$this->load->model(x);``, you would now use + ``$this->x = new X();``, following namespaced conventions for your component **Views** + - Your views look much like before, but they are invoked differently ... -instead of CI3's `$this->load->view(x);` you can use `echo view(x);` + instead of CI3's ``$this->load->view(x);`` you can use ``echo view(x);`` - CI4 supports view "cells", to build your response in pieces - The template parser is still there, but substantially -enhanced + enhanced **Libraries** -- Your app classes can still go inside `application\Libraries`, but they -don't have to -- Instead of CI3's `$this->load->library(x);` you can now use -`$this->x = new X();`, providing the fully-qualified path of your -component + +- Your app classes can still go inside ``application\Libraries``, but they + don't have to +- Instead of CI3's ``$this->load->library(x);`` you can now use + ``$this->x = new X();``, following namespaced conventions for your + component **Helpers** + - Helpers are pretty much the same as before, though some have been simplified **Extending the framework** -- You don't need a `core` folder to hold `MY_...` framework -component extensions or replacements -- You don't need `MY_x` classes inside your libraries folder -to extend or replace CI4 pieces + +- You don't need a ``core`` folder to hold ``MY_...`` framework + component extensions or replacements +- You don't need ``MY_x`` classes inside your libraries folder + to extend or replace CI4 pieces - Make any such classes where you like, and add appropriate -service methods in `application/Config/Services.php` to load -your components instead of the default ones + service methods in ``application/Config/Services.php`` to load + your components instead of the default ones