Zend Framework: Alter .ini-Files - zend-framework

in Zend-Framework, is it possible to save an altered .ini-File?
Because altering the $config-Array is easy, if allowModifications = TRUE in Zend_Config_Ini is enabled.

You can use Zend_Config_Writer to modify your config file
$config = new Zend_Config_Ini('config.ini');
// Modify a value
$config->production->value = 'my_value';
$writer = new Zend_Config_Writer_Ini(array('config' => $config,
'filename' => 'config.ini'));
$writer->write();

You may use Zend_Config_Writer_Ini, it works fine, but has one inconvenience. It doesn't matter that you used inheritance in your *.ini file, if you change something in production dimension, the whole dimension will be copied to its descendants, except entries that overrides production. You will also lost all your comments, so be careful using that.

Related

How to create identifier_hash in typo3's sys_file?

I want to import some files in Typo3 system using external php Script. How do I create hash field value like identifier_hash folder_hash sha1 for sys_file table?
If I leave these fields empty there is error:
Attempt to modify record '3094' (sys_file_reference:3094) without permission. Or non-existing page.
Probably the best way to do this is to call TYPO3 API,
therefore you have to place somewhere in fileadmin/ and then call
TYPO3\CMS\Core\Resource\getFileObjectByStorageAndIdentifier($storageUid,
$fileIdentifier);
The hashIdentifier function in TYPO3 source utilizes the standard php-sha1 function, just in case you do not want to utilize the TYPO3-API.
$file = array(
'folder' => 'images',
'identifier' => 'images/foobar.jpg'
);
$identifierHash = sha1($file['identifier']);
$folderHash = sha1($file['folder']);
$sha1 = sha1_file($file['identifier']);

Using AdditionalConfiguration.php for many TYPO3 Installation?

I use one global AdditionalConfiguration.php for serveral TYPO3 Installation. I just symlink this file.
AdditionalConfiguration.php -> /global/typo3_every_instance/typo3conf/AdditionalConfiguration.php
Now in this AdditionalConfiguration.php I can enforce the use of rsa for every TYPO3 Instance:
$GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'] = 'rsa';
I too have a configuration for maxFileSize there:
$GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'] = '20240'
But on some installation I want to have a bigger maxFileSize, so I have this in my LocalConfiguration.php:
'BE' => array('maxFileSize' => 150000)
Now I changed the AdditionalConfiguration.php to:
/* if not set in LocalConfiguration maxFileSize has default value */
if($GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'] == '10240'){
$GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'] = '20280'; // 10MB
}
What to you think about this?
what happens if the default value changes for some reason?
I do not know whether the AdditionalConfiguration.php is read before or after the
LocalConfiguration.php?
If your LocalConfiguration.php is read after AdditionalConfiguration.php
just set the new value.
if it's the other way round you can try following code
in LocalConfiguration
define("FILESIZE",'150000');
in AdditionalConfiguration
$GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'] = defined("FILESIZE")?FILESIZE:'20240'
Hope it helps
In my opinion the way to go is the TYPO3 Application Context. You can set single values inside an if in your AdditionalConfiguration.php or even just load a specific one for each context, e.g. AdditionalConfigurationTesting.php.
Here is a great article how to set and use this: https://usetypo3.com/application-context.html
In the future in modern docker environments its probably more the way to go with .env files - filled with your local settings.

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.

Perl: command-line override of config file settings?

I'm building a script that utilizes a config file (YAML) to read in all the necessary configuration information, then prints out all the necessary steps a Linux Admin needs to step through to build a server.
A required option is for the Linux Admin that's running the script to be able to override any of the item/value pairs from the config file, at the command-line.
The way I'm currently handling this seems overly cumbersome and I know there's got to be a more innovative and less clunky way to do this.
In the code I:
Parse the YAML config file with YAML::Tiny
location:
continent: na
country: us
city: rh
Create variables with the same names as the config file items, assigning the values from the config file.
my $yaml = YAML::Tiny->new;
$yaml = YAML::Tiny->read($config_yml);
my $continent = $yaml->[0]->{location}->{continent};
my $country = $yaml->[0]->{location}->{country};
my $city = $yaml->[0]->{location}->{city};
Use Getopt::Long and assign the variables, overriding anything passed at the command-line.
GetOptions (
"city=s" => \$city,
"continent=s" => \$continent,
"country=s" => \$country,
);
So those are just 3 item/values pairs, my actual config has over 40 and will change...Which makes for a bit of work to have to keep updating. Any suggestions?
You can let the admin override the YAML settings with a single, flexible switch similar to what ssh(1) does with -o. This is especially appropriate if the config settings are numerous and likely to change.
$ myscript -o location:city=rh --option location:country=us
Now, inside the script, you might keep all your runtime config bundled together in a hash for convenience (rather than having $this_and_that_opt scalars proliferate over time). Option parsing would then look something like this:
# First, set up %GlobalAppCfg from defaults and YAML
# now handle "-o location:country=us"
GetOptions('option|o=s' => sub {
my (undef, $optstring) = #_;
my ($userkey, $val) = split('=', $optstring, 2);
my ($major, $minor) = split(':', $userkey, 2);
$GlobalAppCfg->{$major}->{$minor} = $val;
},
...);
or whatever. You can normalize config keys and values, handle arbitrarily deep key/subkey/subkey configs, etc. This can get slippery, so you might like to key-lock that global hash.
Take a look at some of the Config modules that marry GetOpt and YAML, perhaps Config::YAML or Config::YAML::Tiny
Just a sketch, but
In your GetOptions call, could you use "deep references" into the YAML structure, thereby getting rid of the "intermediate" variables?
By looking at the generated YAML structure, could you not generate the GetOptions call automatically (based on what variables you actually see in the YAML). By generate, I mean, create the call as a string, and then use "eval" to actually execute it.
If you want the "intermediate variables" for convenience, you could probably generate those yourself from the YAML structure, also as a string, and then use "eval" to actually create the variables.
As I said, just a sketch.

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.