How to define the use of utf-8 in Doctrine 2 in Zend Framework application.ini, when using Bisna - zend-framework

The following ZendCasts cast, shows a way to use doctrine 2 in a zend framework environment.
Using this configuration, how can I make the connection use a utf-8 charset so the magic of "SET NAMES 'utf8'" will happen ?
What I'm really searching for is a way to configure it using the application.ini file.
If that's not possible using this configuration, how can this be done by code ? an _initDoctrine method in the Bootstratp file ?
Thank you.
UPDATE
It appears there's a post connect event which handles this, but I don't see how can I set it up via application.ini (if possible at all).
If not, can I set it up via a bootstrap method ? Will the bootstrap method run before any other doctrine connection code run, when relying on the Bisna library ?

If you are not using Bisna, you could simply do something like the following:
Pass the config stuff directly to EntityManager's connection options
(although driverOptions is not documented)
// $options is a simple array to hold your data
$connectionOptions = array(
'driver' => $options['conn']['driv'],
'user' => $options['conn']['user'],
'password' => $options['conn']['pass'],
'dbname' => $options['conn']['dbname'],
'host' => $options['conn']['host'],
'charset' => 'utf8',
'driverOptions' => array(
1002 => 'SET NAMES utf8'
)
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
I'm using the following custom bootstrap resource to initialize doctrine therefore $options is in application.ini and is accessible there by $this->getOptions();
// \library\My\Application\Resource\Doctrine.php
class My_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
public function init()
{
$options = $this->getOptions();
$config = new \Doctrine\ORM\Configuration();
//doctrine autoloader, config and other initializations
...
$connectionOptions = array(
.... //see above
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$registry = Zend_Registry::getInstance();
$registry->em = $em;
return $em;
}
}
It will bootstrap automatically if you put in application.ini
resources.doctrine.conn.host = '127.0.0.1'
resources.doctrine.conn.user = '...'
resources.doctrine.conn.pass = '...'
....

works fine for me
resources.doctrine.dbal.connections.default.parameters.driverOptions.1002 = "SET NAMES 'UTF8'"
1002 is the integer value of PDO::MYSQL_ATTR_INIT_COMMAND:
Command to execute when connecting to the MySQL server. Will
automatically be re-executed when reconnecting.
Note, this constant can only be used in the driver_options array when constructing a new
database handle.

this worked for me. config/autoload/doctrine.local.php
<?php
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => '...',
'password' => '...',
'dbname' => '...',
'driverOptions' => array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
),
)
)
)
);

It is possible to add it via application.ini, provided you use ZendX_Doctrine2 (at https://github.com/mridgway/ZendX_Doctrine2) with MySQL.
Then here's the line you need in application.ini:
resources.entitymanagerfactory.connectionOptions.driverOptions.1002 = "SET NAMES utf8"
(1002 == PDO::MYSQL_ATTR_INIT_COMMAND)
Don't forget to correctly set
default-character-set=utf8
in your my.cnf

Since this is for Doctrine 2, and ZendCasts is using Bisna, I believe you can just add this to your configuration.ini file
resources.doctrine.dbal.connections.default.parameters.driverOptions.charset = "utf8"
I'm not exactly sure how to test if it is sticking or not but let us know.

You could set the default table charset like that to utf8:
// Create new Doctrine Manager instance
$doctrineManager = Doctrine_Manager::getInstance();
// Set charset to UTF8
$doctrineManager->setAttribute(
Doctrine_Core::ATTR_DEFAULT_TABLE_CHARSET,
'utf8'
);
Quote:
an _initDoctrine method in the Bootstratp file ?
Yes.

For LoSo library and Doctrine 2 and MySQL add
resources.doctrine2.connection.driverOptions.1002 = "SET NAMES 'UTF8'"
to your application.ini

I have this in my bootstrap:
protected function _initDoctrineLibrary()
{
require_once('Doctrine/Doctrine.php');
$this->getApplication()->getAutoloader()->pushAutoloader(array('Doctrine', 'autoload'),'Doctrine');
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(
Doctrine::ATTR_MODEL_LOADING,
Doctrine::MODEL_LOADING_CONSERVATIVE
);
$config = $this->getOption('doctrine');
$conn = Doctrine_Manager::connection($config['dsn'],'doctrine');
$conn->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);
return $conn;
}
where in the application.ini you see
doctrine.dsn = "mysql://user:password#host/databasename"
I think you can do something similar

Related

Use Doctrine with REST APIs

Is it possible to use a REST API as Doctrine database?
Regarding the configuration on http://doctrine-orm.readthedocs.org/projects/doctrine-dbal/en/latest/reference/configuration.html I can change the "driver" property.
But in the list of allowed drivers there is no one to use a REST API.
What I would like to do is:
<?php
$config = new \Doctrine\DBAL\Configuration();
//..
$connectionParams = array(
'dbname' => 'my_rest_api',
'user' => 'user',
'password' => 'secret',
'host' => 'localhost:3000',
'driver' => 'rest',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$entityManager = EntityManager::create($conn, $config);
// Sends a GET request to localhost:3000/myentity/1 and maps it properly to my configured entity
$entity = $entityManager->find("MyNamespace\Entity\MyEntity", 1);
// Sends a POST request to localhost:3000/myentity
$entity = new MyEntity();
$entityManager->persist($entity);
$entityManager->flush();
// and so on
Thank you for your answers!!
DoctrineRestDriver is exactly doing what you are looking for!
https://github.com/CircleOfNice/DoctrineRestDriver
Have fun!

CodeIgniter autoloading form validation rules set not working with parameters

Following CI user_guide, I have created a configuration file named "form_validation.php" with in it the following sets:
$config = array(
'user/create' => array(
array(
'field' => 'id',
'label' => '',
'rules' => ''
),
array(
'field' => 'first_name',
'label' => 'lang:First name',
'rules' => 'required|max_length[30]'
),...
),
'user/update' => array(
array(
'field' => 'id',
'label' => '',
'rules' => ''
),
array(
'field' => 'first_name',
'label' => 'lang:First name',
'rules' => 'required|max_length[30]'
),...
)
);
In my 'user' controller, when I call the 'create' method, hence with the URL http://localhost/my_ci_application/user/create, the statement $this->form_validation->run() automatically runs the first set of rules defined in my configuration file. This is the expected behaviour from what I read in the user guide.
But when I run the following URL http://localhost/my_ci_application/user/update/1 to update the user whose ID is 1, it does not automatically load the 'user/update' rules set. It seems like because of the parameter, CI expects to find a 'user/update/1' rules set, which of course I cannot create because the ID of my users will vary all the time when calling this method.
Am I understanding this right? If yes, then that's a pity as I thought standard CI URL were formed like: controller/method/parameters... so I would expect the form validation class to only consider the first two URI segments?!
FYI, if I write in my user.update method the following, my validation rules work fine:
$this->form_validation->run('user/update')
So my question is really if I understood the autoloading of rules properly or not, and if there is anything we can do to autoload those rules even with methods having some parameters.
thank you very much in advance.
In your form_validation.php file:
$CI =& get_instance();
$config = array(
'user/update/' . $CI->uri->segment(3) => array(
....
)
);
if i understant this question u will need call validation, for example:
$this->lang->load('form_validation', 'portuguese'); //if u have order language
if($this->form_validation->run('user/update') == FALSE)
{
//msg error
}
else{
//save
}
To get the value for the url dowel u need:
$this->uri->segment(3);
i hope this has helped
You can extend the library to achieve this
application/libraries/MY_Form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
function run($group = '')
{
if($group == '')
{
$group = '/' . implode('/', array_slice($this->CI->uri->rsegment_array(), 0, 2));
}
return parent::run($group);
}
}

unserialize cache zend doctrine2

Hi can you help me please! I want to use zend cache file since im in shared hosting.
So the problem is i cant retrieve cached doctrine file result. data has serialized coz it 's object. $cache->load($id) return as array i can't unserialize back.
Please i will glad if you could help me or suggest something. Here my code.
$request = $this->getRequest();
$slug = $request->getParam('slug');
$front = Zend_Controller_Front::getInstance();
$bootstrap= $front->getParam('bootstrap');
$cache = $bootstrap->getResource('cachemanager')->getCache('content');
$cacheId = md5('news_' . $slug);
if ( !($news = **unserialize($cache->load($cacheId))**) ) {
$news = $this->_em->getRepository('Custom\Entity\News')
->findOneBySlug($slug);
$cache->save($news, $cacheId);
var_dump('if u see me that mean not from cached');
}
$page = new Zend_Navigation_Page_Mvc(array(
'label' => $news[0]->getTitle(),
'route' => 'news-view',
'module' => 'news',
'controller' => 'index',
'action' => 'view',
'params' => array(
'slug' => $news[0]->getAlias())
)
);
$page->setActive(false);
$this->_helper->navigation->getContainer()
->findOneBy('uri', '/category/' . $news[0]->getCategory()->getSlug())
->addPage($page);
$this->view->ogpa = new OpenGraphProtocolArticle();
$this->view->news = $news;
$this->view->headTitle($news[0]->getTitle());
Do not save any Doctrine2 models in Zend_Cache see: https://ssmusoke.com/2012/03/25/doctrine2-day-3-proxies-associations-relationships/
This is because in the background Doctrine2 uses proxy classes which cannot be unserialized by the Zend auto loader, which will cause you a great deal of grief ...
If you are to cache anything, cache the output not the models.

How mvc works in Zend framework

Thanks for previous replies..
I am trying to print Hello_world using zend framework. I wrote php file in model folder and return string value as a "Hello_world". In controller i access the value of PHP like this
$value = new TextReturner();
$this->view->setValue = $value->hello_world(); . i dont know how to access the value from controller to the view php file. I am new to zend framework. I already go through the outline structure of zend framework, i dont know how to access through codings. If anyone have idea of how to print hello_world through MVC pls guide me.
You are trying to use class $value = new TextReturner(); but your controller doesn't see that class.
Set this in your Bootstrap file that will help:
protected function _initAutoLoad() {
// Add autoloader empty namespace
$autoLoader = Zend_Loader_Autoloader::getInstance();
$resourceLoader = new Zend_Loader_Autoloader_Resource(
array(
'basePath' => APPLICATION_PATH,
'namespace' => '',
'resourceTypes' => array(
'model' => array(
'path' => 'models/',
'namespace' => 'Model_'
),
),
)
);
return $resourceLoader;
}
This will be autoload all of your model class.
in view you can access your variable like this:
<?php echo $this->setValue;?>

No translation for the language - Works on development server but not in production

While translation works fine on the development server we get the following notice on the production server: No translation for the language 'fr' available.
Here is the translation configuration in the bootstrap (forcing the locale for the test) :
$locale = "fr_CA.utf8";
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH . '/lang',
'locale' => $locale,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'disableNotices' => false,
'clear' =>true,
'reload'=>true,
)
);
The .mo file is in APPLICATION_PATH/lang/fr_CA.utf8/LC_MESSAGES/messages.mo
There are translated strings in the .mo file and the locale exists on both servers, according to "locale -a".
Any clue as to why such a setup could work on one server and not the other?
EDIT :
I got it to work with the following configuration :
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH.'/lang/'.$locale.'/LC_MESSAGES/messages.mo',
'locale' => $locale,
'disableNotices' => true,
'clear' =>true,
'reload'=>true,
)
);
It seems like the scanning was not working.
I had a similar problem (using the array adapter)
Reason: production site webroot path contains hidden directory /home/.sites/path/to/my/webroot/
// Settings:
$locale = new Zend_Locale('browser');
$language = $locale->getLanguage();
// Solution: added option 'ignore' => '===' to override
// default $_options settings in Zend_Translate_Adapter
$translate = new Zend_Translate(array(
'adapter' => 'array',
'content' => APPLICATION_PATH . '/languages/' . $language,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'locale' => $locale,
'ignore' => '===', // override default '.'
));
I had a similar problem but using application.ini to configure translation.
These were the Zend_Translate related lines:
resources.translate.adapter = "gettext"
resources.translate.content = APPLICATION_PATH "/languages"
resources.translate.options.scan = 'directory'
This worked fine on our development server but not on our staging server. We had to remove the quotes from the scan option:
resources.translate.options.scan = directory
Without quotes it worked. But I have no idea why this particular config line can't handle quotes on our staging server.