Store information about a directory - php

Other than the foldername, is there a way to get/set information about a directory to the actual folder itself?
I want to set a directory priority so folders are displayed in a certain order by assigning a number to each.

This is possible with Extended File Attributes:
https://secure.wikimedia.org/wikipedia/en/wiki/Extended_file_attributes
Extended file attributes is a file system feature that enables users to associate computer files with metadata not interpreted by the filesystem, whereas regular attributes have a purpose strictly defined by the filesystem (such as permissions or records of creation and modification times).
Try the xattr API to get/set them:
http://docs.php.net/manual/en/book.xattr.php
Example from Manual:
$file = 'my_favourite_song.wav';
xattr_set($file, 'Artist', 'Someone');
xattr_set($file, 'My ranking', 'Good');
xattr_set($file, 'Listen count', '34');
/* ... other code ... */
printf("You've played this song %d times", xattr_get($file, 'Listen count'));

You can do it for NTFS for sure: http://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29
Don't know if such a feature exist for *nix file systems.

Why do you want to anchor your program logic in the filesystem of the OS? That isn't a proper way to store such a information. One reason is that you leave your application domain and other programs could override your saved information.
Or if you move your application to a newer server, you may run in trouble that you cant transfer this information (e.g. as the new environment has another filesystem).
It is also bad practice to suppose a specific filesystem where your application is running.
A better way is to store this in your application (e.g. database if you need it persistent).
A simple array can do this job, with key as priority and value an array with objects of Directory for example.
It could look like this:
array(
0 => array( // highest prio
0 => DirObject,
1 => DirObject,
2 => DirObject
),
1 => array(
0 => DirObject,
1 => DirObject,
...
), ...
Then you can present your folders with an flatten function or a simple foreach. And can easily save it as serialized/jsoned string in a database.

Related

The best way to edit slider images and links

I have a slider in the index page, which has 3 pictures and this pictures has links. What is the best way to change pictures and links: make db table sliders:
id
pic
link
and work with it, or make in config->settings.php something like this:
<?php
return [
'new_products_count' => 6,
'popular_products_count' => 6,
'paginate' => 20,
'admin_paginate' => 10,
'slider'=>[
1=>['img'=>'1.jpg','link'=>'www1'],
2=>['img'=>'2.jpg','link'=>'www2'],
3=>['img'=>'3.jpg','link'=>'www3']
]
];
and work with it like this:
Config::set('settings.slider[1]['img']=>'newimg.jpg')
Config::set('settings.slider[1]['link']=>'newWWW')
?
Would be safer to keep in the database for a couple of reasons.
1- If you cache your configuration, it may sometimes behave like a buggy application. I mean after changing an image and coming back, you may see the previous image displaying again. Because what you change at runtime is not persisted. Try to update a config option, e.g:
config(['database.connections.sqlite.driver' => 'fake']);
Then go check the file. tadaaa... the file didn't change.
2- You database is unlimited. YOu can add an infinite number of images (links) with much more options. Of course, you can also pass options to config() but using Eloquent or Query builder is more flexible.

Any way to offset results with AWS SDK for PHP?

I'm currently working on scanning a folder in my S3 bucket and removing files that are no longer in my database. The problem is that I have millions of files, so no way of scanning this in one go.
// get files
$files = $s3->getIterator('ListObjects', array(
"Bucket" => $S3Bucket,
"Prefix" => 'collections/items/',
"Delimiter" => '/'
), array(
'return_prefixes' => true,
'names_only' => true,
'limit' => 10
));
The documentation included something about limiting results, but I can't find anything about offsetting. I want to be able to start from 0, scan 500 items, remove them, stop, save the last scanned index and then run the script again, start from the saved index (501), scan 500 items, and so on.
Does the SDK offer some sort of offset option? Is it called something else? Or can you recommend a different method of scanning such a large folder?
Remember the last key you processed and use it as the Marker parameter.
$files = $s3->getIterator('ListObjects', array(
"Bucket" => "mybucket",
"Marker" => "last/key"
));
BTW, dont set Limit, its slowing down. Limit 10 will cause a request to the API every 10 objects, the API can return up to 1000 objects per request.

Is there a way we can build YII multisite application with one database for multiple domains

We are planned to host a single CMS for the multiple sites.
Is there are way in YII we can do that, The idea is simple we want to share single application and single database for all the domains but we will let them choose the different themes for the different website.
By website I mean totally different Domains.
What other setting will we have to do to point all the domains to single server ?
Edit::
I don't want the different serve directory for each domain. what I want to do it, keep the installation only one.
i.e.
/server/www/master
then all the domains
a.com, b.com, c.com read the same dir "/server/www/master" and same DB. and records get filer on the base of site.
I have done exactly that with Yii so yes it is possible.
In your Apache settings make sure to point all the domain names to the same directory (using ServerAlias - http://httpd.apache.org/docs/2.2/mod/core.html#serveralias).
In my database I created a table with a row for each website, storing the domain name as one of the fields.
In my ApplicationConfigBehavior.php::beginRequest (which is executed for every request), I did something like this:
/**
* Load configuration that cannot be put in config/main
*/
public function beginRequest()
{
if(empty(Yii::app()->session['community'])){
$current_community = Community::model()->with(array(
'communityHosts'=>array(
'joinType'=>'INNER JOIN',
'condition'=>'`communityHosts`.hostname= :hostname',
'params' => array(':hostname' => $_SERVER['SERVER_NAME'])
),
))->find();
Yii::app()->session['community'] = serialize($current_community);
}
else{
$current_community = unserialize(Yii::app()->session['community']);
}
if(!empty($current_community)){
Yii::app()->name = $current_community->name;
Yii::app()->params['currentCommunity'] = $current_community;
Yii::app()->language = $current_community->language;
}
else{
//TODO: Throw error
session_unset();
die('Hostname ' . $_SERVER['SERVER_NAME'] .' not found');
}
}
Which basically says, looks for this server name in my database, get the current "community" (my sites), and store all the settings (theme, site name, etc...) in the session.
The exact query might not be the same for you. It's just to give you the general idea. Adapt it to your database schema or however you store the settings for each website.
In the apache virtual host file, set the site name
SetEnv SITE_NAME "CMSA"
Get site name in the code using
defined('SITE_NAME') || define('SITE_NAME', ( getenv('SITE_NAME') );
Use the constant in the config and filter your records based on the site.
The same way theme can also be declared.

What is the best way to persist PHP application setings?

I have a small application that I'm developing, that I may want to give/sell to others. I want to persist some settings, and create an admin interface to modify them. What would be the best way to store them away? A DB table seems like overkill for the 10-20 settings I'll have, and I want the retrieval of these settings to be as fast as possible. Is a flat file another viable option? What are the pitfalls associated with using a flat file? What would be the fastest/easiest way to interface with a flat file storing multiple keys and values?
I often use PHP's parse_ini_file for this.
So if you write an .ini file with this:
; This is a sample configuration file
; Comments start with ';', as in php.ini
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
[third_section]
phpversion[] = "5.0"
phpversion[] = "5.1"
phpversion[] = "5.2"
phpversion[] = "5.3"
And read it in with this PHP code:
define('BIRD', 'Dodo bird');
$ini_array = parse_ini_file("sample.ini", true);
print_r($ini_array);
You will get this output:
Array
(
[first_section] => Array
(
[one] => 1
[five] => 5
[animal] => Dodo bird
)
[second_section] => Array
(
[path] => /usr/local/bin
[URL] => http://www.example.com/~username
)
[third_section] => Array
(
[phpversion] => Array
(
[0] => 5.0
[1] => 5.1
[2] => 5.2
[3] => 5.3
)
)
)
PHP has functions to read .ini files.
http://is2.php.net/manual/en/function.parse-ini-file.php
It really depends on the type of "settings" you want to store. Are they "bootstrap" settings like DB host, port, and login? Or are they application settings specifically for your application?
The problem with letting an admin interface write a file on the file system is the permissions needed in order to write to the file. Anytime you open up the web server to write files, you increase the possibility that an error in your code could allow severe privilege escalation.
Databases are designed to allow reads and writes without introducing the potential system security risks.
We use "generated" PHP files to store static configuration data in (like database access info). It is generated by a utility script by a user on the command line. After that, all non-static information is stored in a database table. The database table, in turn, is easy to update from an Admin area. It is easy to extend and upgrade as you upgrade your applicecation.
It's also much easier to centralize the "data" that needs backed up in one place.
May I suggest using memcached or something similar to speed it up?
Just a couple thoughts...
I think XML via SimpleXMLElement is very useful for that kind of thing.
The configuration (config.xml):
<config version="1">
<foo>value</foo>
<bar>
<baz>Boo</baz>
</bar>
</config>
The code to read it:
$config = simplexml_load_file('config.xml');
$version = (int) $config['version'];
$foo = (string) $config->foo;
$baz = (string) $config->bar->baz;
Code to write it to a file:
$config = new SimpleXMLElement('<config version="1"/>');
$config->foo = 'value';
$config->bar->baz = 'Boo';
$config->asXML('config.xml');
The main pitfall of using flat files is that it could lead to possible data corruption on script crash or concurrent editing.
Consider a PHP object (or array) serialized to a file. No parsing code to write, fast enough, extensible. The one caveat is to think of a strategy to "upgrade" the settings file as your code grows to support further settings.
I simply use a PHP array for config files.
<?php
return array
(
'user' => 'name',
'pass' => 'word',
'one_day' => 60 * 60 * 24
);
?>
Some of the advantages are that, like morendil mentioned, no parsing required, its as fast as it gets, you can store all kinds of complex variables / equations and you can do the following:
<?php
$config = include 'path/to/file.php';
?>

Drupal - Automate a Content Form Submission

I would like to programatically (using php) fill out an existing drupal form to create a content type that is included in a contributed module.
Details: The module is SimpleFeed and the content type is Feed. I would like to call the module's functions to accomplish this. The method I am interested in is hook_insert which appears to require vid and nid which I am unsure what these are.
Any help is appreciated.
can you provide a bit more information (which modules?). generally, i'd probably suggest calling the modules functions to create the content type, instead of trying to pass it through a form programatically. this way you don't have to worry about implementation, and can trust that if the module works, it'll work for your script too :)
of course this does tie your module to theirs, so any changes in their functions could affect yours. (but then again, you run that risk if they update their database structure too)
ex.
// your file.php
function mymodule_do_stuff() {
cck_create_field('something'); // as an example, i doubt this
// is a real CCK function :)
}
edit: vid and nid are node ID's, vid is the revision id, and nid is the primary key of a particular node. because this is an actual node, you may have to do two operations.
programatically create a node
you'll have to reference the database for all the exact fields (tables node and node_revisions), but this should get you a basic working node:
$node = (object) array(
'nid' => '', // empty nid will force a new node to be created
'vid' => '',
'type' => 'simplefeed'. // or whatever this node is actually called
'title' => 'title of node',
'uid' => 1, // your user id
'status' => 1, // make it active
'body' => 'actual content',
'format' => 1,
// these next 3 fields are the simplefeed ones
'url' => 'simplefeed url',
'expires' => 'whatever value',
'refresh' => 'ditto',
);
node_save($node);
now i think it should automatically call simplefeed's hook_insert() at this point. if not, then go on to 2. but i'd check to see if it worked out already.
call it yourself!
simplefeed_insert($node);
edit2: drupal_execute() isn't a bad idea either, as you can get back some validation, but this way you don't have to deal with the forms API if you're not comfortable with it. i'm pretty sure node_save() invokes all hooks anyhow, so you should really only have to do step 1 under this method.
The drupal api provides drupal_execute() to do exactly this. I would suggest you avoid calling the functions directly to create the node (unless there is a performance reason). By using drupal_execute() all the proper hooks in other modules will be called and your code is far more likely to continue to work through future versions of drupal.
Note that a classic bug in using this method is not first calling something like
module_load_include('inc', 'node', 'node.pages')
which will load the code for your node creation form.
Calling node_save directly is generally considered deprecated and could leave you with broken code in future versions of drupal.
There is a nice example at this lullabot post

Categories