sfFilebasePlugin
1.0.5stable
for sf 1.4sf 1.3sf 1.2 MIT
NEWS
2010/01/02
- Checked for Sf>=1.3 compliency
- Fixed bugs and lost updates in the web frontend modules, so that these should now work with the improved plugin lib-files > V0.9
2009/10/16
- V 1.0.0 released
- Added Doctrine behaviour
- Added more unit tests
- see README ;)
2009/10/14
Image manipulation is now fully supported through the great sfImageTransformPlugin: http://symfony-project.org/plugins/sfImageTransformPlugin
Unit test rewrite to cover core functionalities, more to come until release of v1.0
Bugfixes in core operations (file and directory copying)
chmod(), chown(), chgrp() and improved array access handling.
2009/09/29
Fixed a bug in path detection when accessing a file by giving an absolute pathname under windows.
2009/09/18
Fixed a few minor issues, path handling on windows, utility methods and so on...
Recently worked on cross brower stuff, mainly IE (yes! ;)). So fixed some bug in SWFUploadPlugin and Ext-Tree.
Finally added support for a multi-file uploader based on SWFUpload. I've been re-written the whole queue plugin, so this thing is yet in (cross browser) test state. Please give me a hint if this part of the code runs on lynx, too.
sfFilebasePlugin
sfFilebasePlugin provides an unified api for filesystem related
operations with focus on web based applications (yes, really.)
Additionally, there is a admin module and a simple to use component to render
a drag'n'drop treeview based on ext js for most simply organizing your files
in a directory structure, all maintained through a doctrine driven hierarchical
database. (Still in developement, but at meantime rather stable)
The core plugin consists of a set of classes based on built in SPL classes
(SplFileInfo/ -Object, DirectoryIterator ...) written by Marcus Boerger.
Documentation for these base classes may be found in the
API-docs.
The API Documentation for sfFilebasePlugin can be found in
./plugins/sfFilebasePlugin/doc. The API doc is not included in the pear-
package, so you'll have had to browse the svn-repository
http://svn.symfony-project.com/plugins/sfFilebasePlugin/
or my github-repository
http://github.com/joshiausdemwald/sfFilebasePlugin.
The git repos also contains a sample symfony project which shows a few
features.
Developers
License
Copyright (c) 2007-2009 Johannes Heinen
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
sfFilebasePlugin
sfFilebasePlugin provides an unified api for filesystem related
operations with focus on web based applications (yes, really.)
sfFilebasePlugin provides a wrapper for doing image manipulations very
easily. For that, sfFilebasePlugin uses the great image manipulation capabilities
of sfImageTransformPlugin (http://symfony-project.org/plugins/sfImageTransformPlugin).
There are also helpers that provide easy access to uploaded files, an uploaded
file validator, a SfWebRequest child class for transforming the $__FILES array
into a more accessible structure and a few other features that simplify upload
handling.
sfFilebasePlugin provides as doctrine behaviour to easily connect your systems
files with a database.
Additionally, there is a admin module and a simple to use component to render
a drag'n'drop treeview based on ext js for most simply organizing your files
in a directory structure, all maintained through a doctrine driven hierarchical
database. (Still in developement, but at meantime rather stable)
In connection with sfWidgetFormInputSwfUpload you can perform multi file uploads
within a few quick steps.
The core plugin consists of a set of classes based on built in SPL classes
(SplFileInfo/ -Object, DirectoryIterator ...) written by Marcus Boerger.
The api-documentation for these base classes may be found in
http://www.php.net/helly/php/ext/spl/.
The API Documentation for sfFilebasePlugin can be found in
./plugins/sfFilebasePlugin/doc. The API doc is not included in the pear-
package, so you'll have had to browse the svn-repository
http://svn.symfony-project.com/plugins/sfFilebasePlugin/
or my github-repository
[http://github.com/joshiausdemwald/sfFilebasePlugin](http://github.com/joshiausdemwald/sfFilebasePlugin
which i use to store what i am working on.
The git repos also contains a sample symfony project which shows a few
features. It could also be used as additional documentation material.
SfFilebasePlugin extends the built in SPL-Classes by dissociating more and
different files or types. Resulting in a collection of classes like
sfFilebasePluginDirectory or sfFilebasePluginImage,
sfFilebasePluginThumbnail. I am planning sfFilebasePluginZIP or something
like that - further enrichments that "fit" into sfFilebasePlugin. Additionally,
the plugin provides an extension of SplFileObject named
sfFilebasePluginFileObject.
SfFilebasePlugin can help woman if she wants to
control file uploads,
search and retrieve files from her servers' filesystem,
read/write/execute files,
do (eventually architecture dependent) filesystem operations like chmod, mkdir, touch.
easily convert path names from absolute to relative, web root based or
filebase root based. Each file related plugin method has an overloaded signature, so that it does not matter whether you pass an absolute, relative pathname or an instance of sfFilebasePluginFile or one of its children.
manipulate images or generate thumbnails (based on the great
sfImageTransformPlugin. Included is a hidden cache layer which automatically
stores generated binary data if you want to do so.
Image manipulation capabilities
As of Version >= 0.9, sfFilebasePlugin uses the image transform capabilities of
sfImageTransformPlugin to perform image manipulation. So refer to the plugin
documentation of sfImageTransformPlugin to see what you are able to accomplish.
Installation
(Install instructions taken from README in sfThumbnailPlugin, (c) Fabien Potencier)
To install the plugin for a symfony project, the usual process is to use the
symfony command line.
With symfony 1.0, use:
$ symfony plugin-install http://plugins.symfony-project.com/sfFilebasePlugin
With symfony 1.1/1.2, use:
$ symfony plugin:install sfFilebasePlugin
Alternatively, if you don't have PEAR installed, you can download the latest
package attached to this plugin's wiki page and extract it under your project's
plugins/ directory.
Clear the cache to enable the autoloading to find the new classes:
$ php symfony cc
You're done.
Adminstration area install instructions (optional)
SfFilebasePlugin provides frontend modules for easy adminstration of your files
and directories (in developement progress yet).
The administration area uses the ExtJs (http://extjs.com/) to render
some fancy widgets like a tree view of your directory/file structure. With this
you are able to drag and drop files or whole directory structures within
your filebase with just a click on your mouse button.
This makes organizing your files and assets really easy.
These modules require doctrine >= 1.1 to be installed.
Doctrine 1.1 is not shipped with symfony 1.2, so you will have to download
the appropriate libaries and link it within your config/projectConfiguration.php:
sfConfig::set('sfDoctrinePlugin_doctrine_lib_path', sfConfig::get('sf_plugins_dir') . '/Doctrine/lib/Doctrine.php');
Alternatively you can install doctrine 1.1 with your symfony 1.2 project by
following the instructions behind this link: http://www.symfony-project.org/blog/2009/01/12/call-the-expert-using-a-custom-version-of-doctrine.
Setting up your application
The adminstration modules of sfFilebasePlugin can handle files and directories,
even your database tables dependent of your application and environment settings.
The following part presumes that you have had already setup your database properly.
To init the administration module, first create an empty application:
symfony generate::app frontend
After that, enable the sfFilebasePlugin modules in your /apps/frontend/config/settings.yml:
enabled_modules: [default, sf_filebase_directory, sf_filebase_file, sf_filebase_filedeliverer, sf_filebase_overview]
Now set up the directory the files should be stored (optional, per default the
/web/upload directory is taken).
In /apps/frontend/config/app.yml, write:
all:
sf_filebase_plugin:
filebases:
# THE FILEBASE'S UNIQUE IDENTIFIER
default:
path_name: path/to/your/upload/directory
You can create as much instances of a filebase as you want to, but this will
be your default filebase which is used by the modules and doctrine models to store
uploaded files in. If you don't specify a filebase directory in app.yml, web/uploads
will be used.
Now open a CLI and type:
symfony sfFilebase:create-root frontend
If you want to initially import some files into your sfFilebase, optinally type
the following line:
symfony sfFilebase:import application /path/to/your/files --env="prod"
symfony sfFilebase:import frontend /path/to/your/files --env="your_env"
// Default environment is "dev"
symfony sfFilebase:import frontend /path/to/your/files
That's it. You can now browse to your filebase by typing:
http://yourhost/frontend_dev.php/sf_filebase_file
Have fun ;)
Contents
The plugin contains a set of classes, that are all instanciated by a file
controller called sfFilebasePlugin. Please take a look at the examples, the
sample project available at githup and the phpdocs to see how it works. There is
a static utility class named sfFilebasePluginUtil that provides general worker
methods.
There are also a few classes that integrates sfFilebasePlugin into symfony.
There is a helper file to use the filebase in your views, and there is also
an sfFilebasePluginWebRequest class, that may replace the core symfony
sfWebRequest class, but this is not a "must have". If you want to do so, the
$request variable passed to your actions contains some additional
methods to retrieve uploaded files (there is the original
sfWebRequest::getFiles() which returns a cleaned up file array and - with
sfFilebasePluginWebRequest::getUploadedFiles() a new way to retrieve uploaded
files in an object oriented way as instances of sfFilebasePluginUploadedFile.
Examples
There is a sample project at github:
http://github.com/joshiausdemwald/sfFilebasePlugin
Simply use this project to test sfFilebasePlugin, or create a new project, copy the apps-folder,
thats it (i think).
You'll see some forms, can upload files, create directories and see some image
transformations in action. Perhaps it can be useful.
Short code samples
To use sfFilebasePluginWebRequest as an enhancement of sfWebRequest, write the
following lines in your apps/myapp/factories.yml:
all:
request:
class: sfFilebasePluginWebRequest
If you are done, you can retrieve uploaded files by calling in your action:
public function executeMyAction(sfWebRequest $request)
{
$files = $request->getUploadedFiles();
}
Alternatively and if you don't want to use sfFilebasePluginWebRequest, call
public function executeMyAction(sfWebRequest $request)
{
$filebase = new sfFilebasePlugin();
$files = $filebase->getUploadedFiles();
}
Iterate over sub-directories:
foreach($filebase AS $file)
{
//lets create thumbnails for all images
$thumbnails = array();
if($file instanceof sfFilebasePluginImage)
{
$thumbnails[] = $file->getThumbnail(array('width'=>120));
}
// Make a few stupid things to show up
$file->copy('my_new_filename.ext');
$file->copy('/path/to/folder/in/filebase/filename.ext');
$file->copy($filebase->getFilebaseFile('my_folder/file.ext'));
}
// do something with the thumbnails.
Fetch some Files that exists in file system (the short way):
$file = $filebase['myfile.txt'];
// open the file
$pointer = $file->openFile();
// read some content:
echo $pointer->fileGetContents();
// Retrieve a directory:
$dir = $filebase['path/to/mydir'];
// Retrieve an image from this directory:
$image = $dir['image.jpg'];
// Create a thumbnail:
$tn = $image->getThumbnail($width, $height);
// .... and so on ;)
Deal with "virtual" files, that does not exist in file system:
// Throws an error, so how to achieve this?
$file = $filebase['path/to/nonexistent/file.txt'];
// The correct way:
$file = $filebase->getFilebaseFile('path/to/file');
// Or:
$file = $filebase->getFilebaseFile('/absolute/path.txt');
// Or:
$file = $filebase->getFilebaseFile($another_instance_of_filebase_file);
Note that despite you are awaiting an directory, a file, a link or an image,
the system cant determin it's file type unless the file physicall exists in
file system. So be aware of this!
You can also create new files on the fly, using sfFilebasePlugin methods:
$new_dir = $filebase->mkDir('/path/to/dir');
$absolute_new_dir = $filebase->mkDir('/absolute/path/to/dir');
$new_dir_from_instance = $filebase->mkDir(
$filebase->getFilebaseFile('dirname');
);
File-Uploads:
$destination_directory = "my_uploads";
$files = $filebase->getUploadedFiles();
$filebase->moveUploadedFile($files[0], $destination_directory);
// Or by handling all uploaded files:
$filebase->moveAllUploadedFiles($destination_directory);
Using the sfFilebasePluginValidatorFile is as simple as using the
generic sfValidatorFile class. For example you could do the following:
$form = new myForm()
$this->upload_form->bind($request->getParameter('upload'),
$request->getUploadedFiles('upload'));
if($this->upload_form->isValid())
{
// retrieve all files that have been uploaded
$files = $this->upload_form->getValue('files');
// Loop and save them in a folder that is located in
// /path/to/filebase/my_uploads.
// 'my_uploads' may also be an instance of sfFilebasePluginFile
// or an absolute path.
foreach($files AS $file)
{
$file = $file->moveUploadedFile('my_uploads');
if($file instanceof sfFilebasePluginImage)
{
// DO SOMETHING WITH THE sfImageTransformPlugin-METHODS:
$file->thumbnail(100, 100)->save();
}
}
}
....
Image Manipulation
Every instance of sfFilebasePluginImage implement the same physical methods
as sfFile, the image manipulation base class of sfImageTransformPlugin.
Additionally you can use every virtual method to do transforms, so e.g.
$myImage->thumbnail(200,200) works as expected. For further documentation
refer to the manual of sfImageTransformPlugin
Doctrine behaviour
You may find the behavior class files in the plugins lib directory, under
lib/doctrine/template. Usage is simple:
testerer:
tableName: tester
actAs:
File:
name: path_name
filebaseDirectory: <?php echo dirname(__FILE__)?>/../../test/assets
checkExistence: true
As you can see, woman creates a table named tester and object model "testerer".
The behaviour adds a column named "path_name", and a filebase "root" directory
must also be provided (you may use the one configured within your app.yml, too).
Then fetching a tuple, simply do the following:
// Retrieves the corresponding sfFilebasePluginFile instance
Doctrine::getTable('testerer')->find(1)->getFile();
// And vice-versa
Doctrine::getTable('testerer')->find(1)->setFile('path/to/file');
If checkExistence key isset to true, your doctrine built-in validation checks
if the file really exists in your filesystem before persisting the tuple into
your database.
Error-Handling
The above code is incomplete because it does not show any error handling.
SfFilebasePlugin handles errors by insanely throwing sfFilebasePluginException
that can be caught for merely any operation. Please give me a hint if you think
that there is an exception that makes no sense in the context or if you miss one
in another part of the code or this particular runtime situation.
Developement
SfFilebasePlugin is in developement state. Standard methods to deal with files
are meant to be stable, but there is space for a lot of improvements. Code
contributions and -improvements, error reportings as bugfixes are very welcomed!
Roadmap
I'd love to see some file compression support in the sfFilebasePlugin - but i
think at the moment it'd be better to work on improving stability and testing.
This plugin is ideal if you want to have a solid "virtual filesystem" in a new
project and you are also willing to improve and fix it while coding as well as
optimizing the api for usability. That's what agile devopement is meant to
be ;););).
There are a few concrete features that i have in mind for the near future:
Test
I began to write some unit-tests on it, but they do not fit in every aspect. So
if you want to report a bug, i would appreciate if you'd pass unit or functional
tests that reproduce the issue.
Please note that sfFilebasePlugin was developed on a linux machine running
ubuntu and php5.2.6 and symfony 1.2. It should run on similar platforms, too,
but i did not test it.
Tests should also consider other operating systems like (what was its name?
ahhh, got it:) windows and rich man's MacOS.
Ok, i hope that this plugin is useful, i'd love to receive your comments and
critiques.
Have fun ;)
Credits
Thanks to Marcus Börger for initializing the gread SPL extension.
And to the ext js team for creating the most powerul but simple to use tree view
control.
Thank you, i would not manage to do such things in months.