Configuring form_path in Catalyst::Controller::Formbuilder - perl

Using the Catalyst::Controller::FormBuilder module to handle forms in a Catalyst application.
The documentation says you can set the form_path like this:
form_path => File::Spec->catfile( $c->config->{home}, 'root', 'forms' ),
But the call to config() in my application is at the top level of the base module. Therefore, $c is undefined. So I can't call $c->config->{home}.
What is the proper way to configure form_path please?

You should be able to access configuration values that have already been set from your application's main module using the __PACKAGE__->config hash. Example: __PACKAGE__->config->{home} or __PACKAGE__->config->{'Controller::FormBuilder'}->{form_path}.
If you're trying to set the FormBuilder configuration in your applications main module, you should be able to use the code provided in the documentation and just replace $c->config->{home} with __PACKAGE__->config->{home}. I think they might have even made a mistake by not doing it this way, but I'm not sure.

Related

neo4jphp: Cannot instantiate abstract class Everyman\Neo4j\Transport

maybe a simple question but for me as starter with Neo4j a hurdle. I installed the neo4jphp with composer in the same directory as my application. Vendor-Subfolder has been created and the everyman/neo4j folder below is available. For a first test I used this code snippet from the examples:
spl_autoload_register(function ($className) {
$libPath = 'vendor\\';
$classFile = $className.'.php';
$classPath = $libPath.$classFile;
if (file_exists($classPath)) {
require($classPath);
}
});
require('vendor/autoload.php');
use everyman\Neo4j\Client,
everyman\Neo4j\Transport;
$client = new Client(new Transport('localhost', 7474));
print_r($client->getServerInfo());
I always stumple upon the error
Fatal error: Cannot instantiate abstract class Everyman\Neo4j\Transport
Googling brought me to a comment from Josh Adell stating
You can't instantiate Everyman\Neo4j\Transport, since it is an abstract class. You must instantiate Everyman\Neo4j\Transport\Curl or Everyman\Neo4j\Transport\Stream depending on your needs
So I thought I just need to alter the use-statements to
use everyman\Neo4j\Client,
everyman\Neo4j\Transport\Curl;
but this doesnt work, debugging shows, that the autoloader only get "Transport.php" instead of "everyman\Neo4j\Transport\Curl.php". For "Client.php" its still working ("vendor\everyman\Neo4j\Client.php") so I am guessing that the use-statement is wrong or the code is not able to handle an additional subfolder-structure.
Using
require('phar://neo4jphp.phar');
works fine but I read that this is deprecated and should be replaced by composer / autoload.
Anyone has a hint what to change or had the same problem?
Thanks for your time,
Balael
Curl is the default transport. You only need to instantiate your own Transport object if you want to use Stream instead of Curl. If you really want to instantiate your own Curl Transport, the easiest change to your existing code is to modify the use statement to be:
use everyman\Neo4j\Client,
everyman\Neo4j\Transport\Curl as Transport;
Also, you don't need to register your own autoload function if you are using the Composer package. vendor/autoload.php does that for you.
Thanks Josh, I was trying but it seems I still stuck somewhere. I am fine with using the default CURL - so I shrinked the code down to
require('vendor/autoload.php');
use everyman\Neo4j\Client;
$client = new Everyman\Neo4j\Client('localhost', 7474);
print_r($client->getServerInfo());`
The folder structure is main (here are the files and the composer.json with the content
{
"require": {
"everyman/Neo4j": "dev-master"
}
}
and in the subfolder "vendor" we have the "autoload.php" and the subfolder everyman with the related content. When I run the file I come out with
Fatal error: Class 'Everyman\Neo4j\Client' not found
which does not happen when I have the autoloadfunction. I guess I made a mistake somewehere - can you give me a hint?
Thanks a lot, B
Hmmm... I was just trying around and it seems the Transport CLASS is not needed in the use-statement and the class instantiation. This seems to work:
require('vendor/autoload.php');
use everyman\Neo4j\Client;
$client = new Client();
print_r($client->getServerInfo());
also valid for having a dedicated server/port:
$client = new Everyman\Neo4j\Client('localhost', 7474);
If you have more input I would be happy to learn more - thanks, all input & thoughts are very appreciated.
Balael

Where to add guard config information of zfc-rbac?

I am following this guide to add Zfc-Rbac in my application. But I can't figure out where to put this configuration information.
Application\config\application.config.files
or Application\modules\modulename\config\module.config.php
You can also put it in a global config file, ie application/config/autoload/zfcrbac.global.php
Either in application/module or application/vendor, place the config inside the ModuleName/config/module.config.php
Also make sure you have added the ZfcRbac to the application module list
'modules' => array(
'Application',
'ZfcRbac',
'DoctrineModule',
'DoctrineORMModule'

How to handle Zend Framework End User INI/Config settings

I have searched and searched for this but I think my terminology isn't correct as it keeps giving me the application settings for the zend site rather than an application settings for the End User.
I'd like to have a config.ini type file that the end user can edit values in. I'd like it to be ONLY the settings I wish them to see and to be able to create the value names as I think would make sense to them. So it would be something like
[General]
SiteName=MySite
ShowResources=TRUE
[Database]
Server=myServer
databasepath=mydbpath
...
So my two questions.
1. What is this type of file called because when I search application settinsg, I get the ZF application settings not one for an end user (presumably)
What is the best way to handle this type of file?
Thanks
In your bootstrap add:
protected function _initConfig()
{
$config = new Zend_Config_Ini(APPLICATION_PATH.'/configs/config.ini');
Zend_Registry::set('config', $config);
return $config;
}
replace config.ini with whatever you want the filename to be.
You can then access this config object anywhere in your application either as an application resource or through the registry (Zend_Registry::get('config')). So to get the SiteName from your example:
$config = Zend_Registry::get('config');
echo $config->General->SiteName;
For things like database settings, you'll want to access these in the bootstrap so you can use them to setup other resources. I would recommend you don't try and include database settings in your application.ini as well, instead manually setup the DB resource by adding another bootstrap method:
protected function _initDb()
{
$this->bootstrap('config');
$config = $this->getResource('config');
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => $config->Database->Server,
'username' => $config->Database->Username,
'password' => $config->Database->Password,
'dbname' => $config->Database->Dbname
));
return $db;
}
To explain this some more, $this->bootstrap('config'); ensures the config resource is loaded first. $this->getResource('config'); returns the config resource (the one created by the _initConfig() method). It then uses the data from this object to create the DB connection.
It's an INI file, which you can read and write via Zend_Config.
ZF has no concept of "user settings" -- users are defined by you, not by the framework.
Apps usually store user configs in a database, but that's totally up to you. You could store a directory of INI files instead. Either way, you have to do the implementation yourself.
Edit: Given that you have a ZF app that you're distributing to the customer, and they're only ever going to connect to one database with it, that changes things significantly. (I thought you originally meant that you'd have one instance of the app simultaneously connecting to multiple databases.)
In your case, I would use the standard ZF application/configs/application.ini file for your application's "internal" settings. Then, I'd have a separate local.ini (or whatever) in that same application/configs directory, which contains only those settings that you want the customer editing. Distribute a skeleton local.ini file with the app, that has instructions right in it, something like this:
; Remove the comment from this line.
;configured = 1
; You need to put your database credentials in here.
db_host = "PUT YOUR DATABASE SERVER NAME HERE"
db_user = "PUT YOUR DATABASE USERNAME HERE"
db_pass = "PUT YOUR DATABASE PASSWORD HERE"
Then just load the local.ini file via Zend_Config. I'd also add a check to your index controller's init method that checks to see if you're properly configured:
$localConfig = Zend_Registry::get('local_config'); // or wherever you put it
if (!$localConfig->configured) {
$this->_helper->redirector('config', 'error');
}
And then make a error/config view that says:
You didn't read the instructions. Go do that now.
Note there's nothing stopping the customer from editing anything they want, but this makes a logical separation and makes it harder to accidentally screw something up.

Zend Framework unknown module is interpreted as default module

i wanted to support multilingual structure for my work i used the following lines
$controller=Zend_Controller_Front::getInstance();
$router=$controller->getRouter();
$languageRouter=new Zend_Controller_Router_Route(":lang/:module/:controller/:action", array("lang"=>"en","module"=>"default","controller"=>"index","action"=>"index"),
array("lang"=>"[a-zA-Z]{2}"));
$router->addRoute("default",$languageRouter);
it works fine http://localhost/zend/public/en set the lang param to en and call default module
but the problem is that when i use url like this http://localhost/zend/public/en/anything
where anything isn't module it still show the default module how to prevent that???
after the answer of takeshin i added this function to the bootstarp file and now it works as i want it
protected function _initRoutes()
{
$routeLang=new Zend_Controller_Router_Route(':lang',array('lang'=>'en'),array('lang'=>'[a-z]{2}'));
$front = Zend_Controller_Front::getInstance() /*$this->getResource('frontcontroller')*/;
$router = $front->getRouter();
$routeDefault=new Zend_Controller_Router_Route_Module(array(),$front->getDispatcher(),$front->getRequest());
$routeLangDefault=$routeLang->chain($routeDefault);
$router->addRoute('default',$routeLangDefault);
$router->addRoute('lang',$routeLang);
}
It looks like you have overwritten default module defined in Zend Application by your custom one.
You should chain the routes instead.
The settings you are using means module will 'default' to default , if you didn't it would throw a route not found error - which should throw to appropriate error controller
I'm not sure if I unterstood this correctly, but it looks like it works fine, as it should. If you try to call non existing module, Zend Framework automatically "redirects" to the default module.

How do I use add_to in Class::DBI?

I'm trying to use Class::DBI with a simple one parent -> may chidren relationships:
Data::Company->table('Companies');
Data::Company->columns(All => qw/CompanyId Name Url/);
Data::Company->has_many(offers => 'Data::Offer'=>'CompanyId'); # =>'CompanyId'
and
Data::Offer->table('Offers');
Data::Offer->columns(All => qw/OfferId CompanyId MonthlyPrice/);
Data::Offer->has_a(company => 'Data::Company'=>'CompanyId');
I try to add a new record:
my $company = Data::Company->insert({ Name => 'Test', Url => 'http://url' });
my $offer = $company->add_to_offers({ MonthlyPrice => 100 });
But I get:
Can't locate object method "add_to_offers" via package "Data::Company"
I looked at the classical Music::CD example, but I cannot figure out what I am doing wrong.
I agree with Manni, if your package declarations are in the same file, then you need to have the class with the has_a() relationship defined first. Otherwise, if they are in different source files, then the documentation states:
Class::DBI should usually be able to
do the right things, as long as all
classes inherit Class::DBI before
'use'ing any other classes.
As to the three-argument form, you are doing it properly. The third arg for has_many() is the column in the foreign class which is a foreign key to this class. That is, Offer has a CompanyId which points to Company's CompanyId.
Thank you
Well, the issue was actually not my code, but my set up. I realized that this morning after powering on my computer:
* Apache + mod_perl on the server
* SMB mount
When I made changes to several files, not all changes seems to be loaded by mod_perl. Restarting Apache solves the issue. I've actually seen this kind of issue in the past where the client and SMB server's time are out of sync.
The code above works fine with 1 file for each module.
Thank you
I really haven't got much experience with Class:DBI, but I'll give this a shot anyway:
The documentation states that: "the class with the has_a() must be defined earlier than the class with the has_many()".
I cannot find any reference to the way you are using has_a and has_many with three arguments which is always 'CompanyId' in your case.