Integrating Doctrine with CodeIgniter - codeigniter

I have successfully installed the latest version of CodeIgniter and have basic MVC pattern working. The problem that I've noticed is that CI doesn't naturally allow for prepared statements when it comes to queries. So, I decided to download Doctrine 1 from GitHub. I'm very new to Doctrine and needed some help integrating it with CI so I followed this tutorial.
In one of my controllers, I have
$this->load->library('doctrine');
$this->em = $this->doctrine->em;
But, when I go to load the view in my browser, I'm greeted with an error reading
Message: require_once(/Applications/MAMP/htdocs/CodeIgniter/application/libraries/Doctrine/Common/ClassLoader.php): failed to open stream: No such file or directory
Upon further inspection of the Doctrine download from GitHub, there doesn't even seem to be a folder titled "common" anywhere in there. I'm very new to CI and especially Doctrine. Does anyone have some advice that can help me get this working? Also, is it possible to use the MySQLi driver instead of the PDO one with Doctrine?

Downloading the Doctrine ORM straight from GitHub doesn't include the other dependencies. These are managed by Composer. If you look inside the composer.json file you can see these dependencies. If you want to install them manually, they are:
doctrine/common
doctrine/inflector
doctrine/cache
doctrine/collections
doctrine/lexer
doctrine/annotations
doctrine/dbal
symfony/console
I believe that's all of them. You will have to merge these files in their appropriate directories as they follow PSR-0 standards for the autoloading of classes.
Alternatively, install Doctrine 2 with Composer with the following composer.json file and any other dependencies will be installed automatically. Then integrate with CodeIgniter.
{
"minimum-stability": "stable",
"require": {
"doctrine/orm": "2.3.*"
}
}
Edit the index.php file of your CodeIgniter app by adding a single line to include the autoloader file before requiring the CodeIgniter core.
require_once BASEPATH.'../vendor/autoload.php';
require_once BASEPATH.'core/CodeIgniter.php';
Also if installing with Composer, use this edited version of the bootstrap as the contents of application/libraries/Doctrine.php, which is what worked for me
<?php
use Doctrine\Common\ClassLoader,
Doctrine\ORM\Tools\Setup,
Doctrine\ORM\EntityManager;
class Doctrine
{
public $em;
public function __construct()
{
// Load the database configuration from CodeIgniter
require APPPATH . 'config/database.php';
$connection_options = array(
'driver' => 'pdo_mysql',
'user' => $db['default']['username'],
'password' => $db['default']['password'],
'host' => $db['default']['hostname'],
'dbname' => $db['default']['database'],
'charset' => $db['default']['char_set'],
'driverOptions' => array(
'charset' => $db['default']['char_set'],
),
);
// With this configuration, your model files need to be in application/models/Entity
// e.g. Creating a new Entity\User loads the class from application/models/Entity/User.php
$models_namespace = 'Entity';
$models_path = APPPATH . 'models';
$proxies_dir = APPPATH . 'models/Proxies';
$metadata_paths = array(APPPATH . 'models');
// Set $dev_mode to TRUE to disable caching while you develop
$config = Setup::createAnnotationMetadataConfiguration($metadata_paths, $dev_mode = true, $proxies_dir);
$this->em = EntityManager::create($connection_options, $config);
$loader = new ClassLoader($models_namespace, $models_path);
$loader->register();
}
}
Note: Version 3 of CodeIgniter when released, will be installable with Composer, but version 2 is not.

For those looking for a tutorial to integrate Doctrine 2 with CodeIgniter, this question and others answers are outdated (for CI 2).
This is a new tutorial for CI 3 I made and I checked is working:
How to install Doctrine 2 in CodeIgniter 3
I repeat it here.
Install Doctrine
Doctrine 2 ORM’s documentation - Installation and Configuration
Doctrine can be installed with Composer.
Define the following requirement in your composer.json file:
{
"require": {
"doctrine/orm": "*"
}
}
Then call composer install from your command line.
Integrating with CodeIgniter
Doctrine 2 ORM’s documentation - Integrating with CodeIgniter
Here are the steps:
Add a php file to your system/application/libraries folder called Doctrine.php. This is going to be your wrapper/bootstrap for the D2 entity manager.
Put the Doctrine folder (the one that contains Common, DBAL, and ORM) inside the third_party folder.
If you want, open your config/autoload.php file and autoload your Doctrine library: $autoload[‘libraries’] = array(‘doctrine’);
Creating your Doctrine CodeIgniter library
Now, here is what your Doctrine.php file should look like. Customize it to your needs.
<?php
/**
* Doctrine 2.4 bootstrap
*
*/
use Doctrine\Common\ClassLoader,
Doctrine\ORM\Configuration,
Doctrine\ORM\EntityManager,
Doctrine\Common\Cache\ArrayCache,
Doctrine\DBAL\Logging\EchoSQLLogger;
class Doctrine {
public $em = null;
public function __construct()
{
// load database configuration from CodeIgniter
require_once APPPATH.'config/database.php';
// include Doctrine's ClassLoader class
require_once APPPATH.'third_party/Doctrine/Common/ClassLoader.php';
// load the Doctrine classes
$doctrineClassLoader = new ClassLoader('Doctrine', APPPATH.'third_party');
$doctrineClassLoader->register();
// load the entities
$entityClassLoader = new ClassLoader('Entities', APPPATH.'models');
$entityClassLoader->register();
// load the proxy entities
$proxiesClassLoader = new ClassLoader('Proxies', APPPATH.'models/proxies');
$proxiesClassLoader->register();
// load Symfony2 classes
// this is necessary for YAML mapping files and for Command Line Interface (cli-doctrine.php)
$symfonyClassLoader = new ClassLoader('Symfony', APPPATH.'third_party/Doctrine');
$symfonyClassLoader->register();
// Set up the configuration
$config = new Configuration;
// Set up caches
if(ENVIRONMENT == 'development') // set environment in index.php
// set up simple array caching for development mode
$cache = new \Doctrine\Common\Cache\ArrayCache;
else
// set up caching with APC for production mode
$cache = new \Doctrine\Common\Cache\ApcCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
// set up annotation driver
$driver = new \Doctrine\ORM\Mapping\Driver\PHPDriver(APPPATH.'models/Mappings');
$config->setMetadataDriverImpl($driver);
// Proxy configuration
$config->setProxyDir(APPPATH.'/models/Proxies');
$config->setProxyNamespace('Proxies');
// Set up logger
$logger = new EchoSQLLogger;
$config->setSQLLogger($logger);
$config->setAutoGenerateProxyClasses( TRUE ); // only for development
// Database connection information
$connectionOptions = array(
'driver' => 'pdo_mysql',
'user' => $db['default']['username'],
'password' => $db['default']['password'],
'host' => $db['default']['hostname'],
'dbname' => $db['default']['database']
);
// Create EntityManager, and store it for use in our CodeIgniter controllers
$this->em = EntityManager::create($connectionOptions, $config);
}
}
Setting up the Command Line Tool
Doctrine ships with a number of command line tools that are very helpful during development.
Check if these lines exists in the Doctrine.php file, to load Symfony classes for using the Command line tools (and for YAML mapping files):
$symfonyClassLoader = new ClassLoader('Symfony', APPPATH.'third_party/Doctrine');
$symfonyClassLoader->register();
You need to register your applications EntityManager to the console tool to make use of the tasks by creating a cli-doctrine.php file in the application directory with the following content:
<?php
/**
* Doctrine CLI bootstrap for CodeIgniter
*
*/
define('APPPATH', dirname(__FILE__) . '/');
define('BASEPATH', APPPATH . '/../system/');
define('ENVIRONMENT', 'development');
require APPPATH.'libraries/Doctrine.php';
$doctrine = new Doctrine;
$em = $doctrine->em;
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);
?>
Now run this script through the PHP command-line and should see a list of commands available to you.
php cli-doctrine.php
Generate mapping classes from database:
php cli-doctrine.php orm:convert-mapping --from-database annotation models/Entities
if you get this error:
Fatal error: Call to undefined function Doctrine\Common\Cache\apc_fetch()
install the APC extension for PHP:
sudo apt-get install php-apc
sudo /etc/init.d/apache2 restart
For production mode you'll want to use a real caching system like APC, get rid of EchoSqlLogger, and turn off autoGenerateProxyClasses in Doctrine.php

Find the link for the doctrine integration in CI
https://github.com/mitul69/codeigniter-doctrine-integration

Please note that code igniter 2 has a little difference in its code organization. In code igniter 2 it is better to put the Doctrine folder in application/third_party folder, instead of application/libraries folder (or else it will not work!).
You can read more about it here

I had the same problem when I tried to follow this tutorial from doctrine user guide
http://doctrine-orm.readthedocs.org/en/latest/cookbook/integrating-with-codeigniter.html
This problem happens when I tried to install via composer so then I went to this web site
http://www.doctrine-project.org/downloads/ and do manually download the DoctrineORM-2.3.3-full.tar.gz version and the error was gone.

The original poster's problem seems to be an issue with autoloading. I was presented with a similar issue when trying to set up CodeIgniter and Doctrine with Composer. In CodeIgniter 3, you can enable the use of composer autoloading, which should allow you to load all Doctrine files correctly. You must point your Composer vendor dir to application/vendor for this to work. You can also do it in older versions, but then you have to include the Composer autoload file manually in your Doctrine library file for CodeIgniter.
If you want more information: I wrote a blog post describing exactly how to do it. http://blog.beheist.com/integrating-codeigniter-and-doctrine-2-orm-with-composer/

you can use this
via composer :
composer create-project rbz/codeigniter your-project
via git :
git clone https://github.com/dandisy/cihmvctwig.git

Related

Fatal error with Stripe Class 'Stripe\Stripe' not found

I'm trying to implement Stripe Checkout into my website. In local the api work normal but in host I get the error :
Class 'Stripe\Stripe' not found
Note: In my host I don't have SSH. And I added files manually with FTP.
\Stripe\Stripe::setApiKey("sk_test_XXXXXX");
$token = $request->stripeToken;
$customer = \Stripe\Customer::create([
'email' => $client->email,
'source' => $token,
]);
As mentioned you have installed Stripe library manually and uploaded on server.
To use this library include init file.
require_once('/path/to/stripe-php/init.php');
ON next step set Api key, Make sure to use test api key for testing.
\Stripe\Stripe::setApiKey( "sk_test_XXXXXX");
Make sure to download latest stripe library from Githut repo
As i have seen mentioned in the comments:
Stripe needs to be installed using (preferably) composer.
This can be done with the command: composer require stripe after having SSHed into the right directory.
You then need to include the vendor/autoload.php that is generated by composer.
In your case where you cant run composer do the following:
Download stripe`s latest release manually from the github page: https://github.com/stripe/stripe-php/releases
Then you need to include the init.php file found in the downloaded stripe-php directory like this require_once('/path/to/stripe-php/init.php');
Ensure you are running at least PHP 5.4 (Note! This version has reached its end of life. Upgrade if possible to PHP 7.2). You also need the PHP extensions curl, json and mbstring.
After having used require_once('/path/to/stripe-php/init.php'); in the file the stripe code will be running in you can then set your API key using \Stripe\Stripe::setApiKey("sk_test_XXXXXX"); and then run your code like f.ex: $customer = \Stripe\Customer::create([
'email' => $client->email,
'source' => $token,
]);
`
Please use stripe library with the below code to resolve the error
$stripe_obj = new Stripe();
$stripe = $stripe_obj->setApiKey(env('STRIPE_SECRET'));

Class 'GuzzleHttp\Client' not found on Laravel production shared server

I'm trying to retrieve data from an API using Guzzle. I followed the steps in Guzzle website, installed it using composer, added the route and the code in a controller.
I tried these two options:
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://jsonplaceholder.typicode.com/',
// You can set any number of default request options.
'timeout' => 2.0,
]);
and...
$client = new \GuzzleHttp\Client([
// Base URI is used with relative requests
'base_uri' => 'https://jsonplaceholder.typicode.com/',
// You can set any number of default request options.
'timeout' => 2.0,
]);
When running I got the error...
Class 'GuzzleHttp\Client' not found.
I have tried:
require( dirname( __FILE__ ) . '/../../../vendor/autoload.php');
use GuzzleHttp\Client;
In composer.json:
"require": {
"guzzlehttp/guzzle": "^6.3",
...
},
Also...
composer update
composer dump-autoload
php artisan config:clear
The project is on shared hosting; I noticed that there was no Guzzle folder inside the /vendor folder, so I uploaded via FTP. But still the same error.
I've tried everything I found in the forum on this topic; I'm running out of ideas, please any advice would be appreciated.
Thanks in advance for your valuable help.
If you can't run composer on shared hosting, you should upload also /vendor/composer directory (after local $ composer require guzzlehttp/guzzle).

Composer classmap autoload does not load new files in folder

The following problem: I have defined a classmap in my composer.json:
"autoload": {
"classmap": [
"app/controllers",
"app/models",
"app/helper.php"
]
}
However, when I create a new file in the "controllers" or "models" folder, it will not load them and I always have to make a composer dump-autoload.
Is this the correct behavior? I thought the autoloader from composer monitors the folder for new files then?
Yes, this is correct behaviour. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
Generating the classmap requires Composer to know the filename that contains a certain class. This can only be done by parsing the whole source code in the directory and scanning for classes, interfaces and trait definitions.
This usually is a CPU and I/O intensive task, so it is only done when Composer does install/update or (on demand) dumps the autoloader, it is not done with every require "vendor/autoload.php";.
Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0. It is not intended for new code - unless you want to pay the price to dump the autoloader again and again during development.
Go to the root of your server by SSH. Now do the following:
Run ls to list all the files.
You will see composer.lock file; remove the file with rm composer.lock command.
Now run php composer update command.
Depending on your linux type you may have to run php-cli composer update.
Step 3 will create a new composer.lock file and all your classes will be loaded again. Do this anytime you add new classes.
or:
Run composer dump-autoload command.
As already pointed out this is correct behavior. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
The classmap autoload type specified is composer.json is mainly used by legacy projects that do not follow PSR-0 or PSR-4. I have recently started working on such a project and wanted to try to automatically run the composer dump-autoload command when a new class is created. This is actually tricky without including all of the composer source inside the project. I came up with this just to remind the developer they need to dump the classmap:
$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}
spl_autoload_register(
function ( $class ) {
if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
}
},
true
);
This registers another autoloader which is run after composer's autoloader so any classes composer did not find would be passed to it. If the class matches a prefix an exception is throw reminding the developer to re-dump the autoloader and update the classmap.
For me, it somehow did not work too with Yii 1 class-map, when I added - required it along with many other libraries present - I don't remember exactly perhaps I manually edited the file or file permissions were to blame, it was not regenerated for some reason, even when I removed the composer.lock and erased completely the vendor folder - perhaps some cache, as far as I remember, but effectively what helped was to install firstly isolatedly only this single library, it generated class-map, then I added all the other remaining libraries separately at once at second step, viola, everything loadable.

composer package only for development in laravel providers

If I have a package (that I have to add to app/config/app.php providers/aliases) that I only really want on my development boxes (b/c I only use for development) is there an approach that will allow me to do this leveraging composer require --dev <package> along w/ composer install --no-dev
I need to add an index into both the providers and aliases array...but I would prefer NOT to manage those large arrays in multiple config environment folders if possible
Create a folder in your config directory that matches your environment name. dev in this case.
Next, recreate any files you wish to override and place them into that folder. app.php in this case
Next open bootstrap/start.php and find $app->detectEnvironment. The array passed to this method determines which environment you are working with. Setting the key to this array as dev will overwrite any of your config files with their counterparts in your dev folder.
If you do not wish to create an entirely new providers array in app.php file for each environment and say you only wanted to add a certain provider to your dev environment, you may use a helper method like so...
'providers' => append_config(array(
'DevOnlyServiceProvider',
))
All this information was pulled from the Laravel documentation found here: http://laravel.com/docs/configuration
For anyone looking how to do this in Laravel 5, you can still emulate the L4 behaviour.
On the top of app/Providers/AppServiceProvider add:
use Illuminate\Foundation\AliasLoader;
And then edit the register() method:
public function register()
{
$path = $this->app->environment() .'.app';
$config = $this->app->make('config');
$aliasLoader = AliasLoader::getInstance();
if ($config->has($path)) {
array_map([$this->app, 'register'], $config->get($path .'.providers'));
foreach ($config->get($path .'.aliases') as $key => $class) {
$aliasLoader->alias($key, $class);
}
}
}
Then just add config/<YOUR ENVIRONMENT NAME>/app.php config file and define additional providers and aliases, same as in app.php
For example:
return [
'providers' => [
Barryvdh\Debugbar\ServiceProvider::class,
],
'aliases' => [
'Debugbar' => Barryvdh\Debugbar\Facade::class,
],
];

CodeIgniter + omnipay installation

I have used ci-merchant before but from everything see that the "V2" of it is now omnipay. I use codeigniter and i'm struggling to get even the example to work.
I have installed omnipay no problems and in my controller have the following:
use Omnipay\Common\GatewayFactory;
class Homepage extends BC_basecontroller {
public function index()
{
$gateway = GatewayFactory::create('PayPal_Express');
$gateway->setUsername('adrian');
$gateway->setPassword('12345');
}
}
Which is the example here: https://github.com/adrianmacneil/omnipay
However I get the error:
PHP Fatal error: Class 'Omnipay\Common\GatewayFactory' not found in......
Does anyone know how to get it to work in CI?
I'm not sure how you installed Omnipay, but you need to use Composer to load the classes before you can use them.
So following the Omnipay installation instructions, add this to a composer.json file in your root directory:
{
"require": {
"omnipay/omnipay": "*"
}
}
Then install the files:
$ curl -s http://getcomposer.org/installer | php
$ php composer.phar update
Now, if you are using CodeIgniter you will need to set it up to include the composer autoloader. Basically, just add this line to the top of your index.php file:
require_once __DIR__.'/vendor/autoload.php';
There is also a tutorial on using Composer with CodeIgniter here which you may find helpful: http://philsturgeon.co.uk/blog/2012/05/composer-with-codeigniter
I had the same error and fixed it by loading vendor/autoload.php before application/core/CodeIgniter.php

Resources