PHP::String permutation — recursive way

/**
 * Class StringPermutation 
 * 
 * @category   Algorithms
 * @package    MyAlgorithmsPackage
 * @author     Guru from Princeton
 * @author     J Wolfe (Minion)
 */
class StringPermutation {
    /**
     * permutation init function
     * @param string $str
     * @return none
     */
    public function permutationWithOne($str) { 
        $this->permutationWithTwo("", $str);
    }

    /**
     * permutation lookup function for recursion
     * @param string prefix collects permutation
     * @param string string for each letter except the main one
     * @return none
     */
    public function permutationWithTwo($prefix, $str) {
        $length = strlen($str);
        if ($length == 0) echo $prefix;
        else {
            for ($i = 0; $i < $length; $i++) {
                $this->permutationWithTwo($prefix . $str[$i], substr($str, 0, $i) . substr($str, $i+1, $length));
            }
        }
    }

    public function __call($name, $args) {
        switch ($name) {
        case 'permutation':
            switch (count($args)) {
            case 1:
                call_user_func_array(array($this, 'permutationWithOne'), $args);
            case 2:
                call_user_func_array(array($this, 'permutationWithTwo'), $args);
             }
        }
    }
}

$str = "ABC";
$perm = new StringPermutation();
$perm->permutation($str);

Source: http://introcs.cs.princeton.edu/java/23recursion/Permutations.java.html

PHP::FileUploader in Symfony

When I tried to use a Symfony uploading function, I realized there is very few “stock” class for uploading in Symfony. What I found was not well written and renaming routine kind of got convoluted. I decided to write my own by cleaning up unnecessary or badly written codes.

Here’s the results:

/*
 * File uploader class
 * Author: J Wolfe
 */
class FileUploader
{
    /**
     * file handle
     * @var Symfony\Component\HttpFoundation\File\File
     */
    private $file;

    /**
     * file extension
     * @var string
     */
    private $fileExt;

    /**
     * file path
     * @var string
     */
    private $filePath;

    /**
     * file name
     * @var string
     */
    private $fileName;

    /**
     * relative file path
     * @var string
     */
    private $filePersistencePath;
    
    public function __construct($dir = '') {
        $this->setFilePath($dir);
    }

    // getters & setters
    public function setFilePath($dir) {
        $this->filePath = $dir;
    }  
    public function getFilePath() {
        return $this->filePath;
    }    
    public function setFileExt($fileExt) {
        $this->fileExt = $fileExt;
    }
    public function getFileExt() {
        return $this->fileExt;
    }
    public function setFileName($fileName) {
        $this->fileName = $fileName;
    }
    public function getFileName() {
        return $this->fileName;
    }    
    //

    /**
      * Uploads a file
      *
      * @param File Symfony File object - Symfony\Component\HttpFoundation\File\File
      * @return none
      */
    public function setFile(File $file) {
        $this->file = $file;
        $origName = $this->getOriginalFileName();
        $arrName = explode('.', $origName);
        $fileExt = $arrName[sizeof($arrName) - 1];
        if ( (1 < count($arrName)) && (3 <= strlen($fileExt) && 4 >= strlen($fileExt)) ) {
            $this->setFileExt($fileExt);
            array_pop($arrName);
            $origName = implode('.', $arrName);
            $this->setFileName($origName);
        }
    }
    
    /**
      * Read file from the direct
      * @param none
      * $return Symfony\Component\HttpFoundation\File\File
      */
    public function getFile() {
        return new File($this->getFilePath() . DIRECTORY_SEPARATOR . $this->filePersistencePath);
    }

    /**
      * get original file path
      * @param none
      * $return string
      */    
    public function getOriginalFileName() {
        return $this->file->getClientOriginalName();
    }

    /**
      * get relative file path
      * @param none
      * $return string
      */       
    public function getFilePersistencePath() {
        return $this->filePersistencePath;
    }

    /**
      * process command container
      * @param none
      * $return none
      */     
    public function processFile() {
        if (! ($this->file instanceof UploadedFile) ) {
            return false;
        }
        $this->filePersistencePath = $this->moveUploadedFile();
    }

    /**
      * move file location after handling duplicated file names
      * @param none
      * $return string full file path and name
      */  
    public function moveUploadedFile() {
        $origName = $this->file->getClientOriginalName();
        
        // use filemtime() to have a more determenistic way to determine the subpath, otherwise its hard to test.
        // $relativePath = date('Y-m', filemtime($file->getPath()));
        // $newFileName = $relativePath . DIRECTORY_SEPARATOR . $origName;
        $newFilePath = $this->getFilePath() . DIRECTORY_SEPARATOR . $origName;

        $fileName = $this->getFileName();
        $fileExt  = $this->getFileExt();
        $idx = 1;
        while (file_exists($newFilePath) && md5_file($this->file->getPath()) != md5_file($newFilePath)) {
            $tmpfileName = $fileName . '_' . (string)$idx;
            $newFilePath = $this->getFilePath() . DIRECTORY_SEPARATOR . $tmpfileName . '.' . $fileExt;
            $this->setFileName($tmpfileName);
            $idx++;
        }
        $targetDir = $this->getFilePath() . DIRECTORY_SEPARATOR;

       if (!is_dir($targetDir)) {
            $ret = @mkdir($targetDir, umask(), true);
            if (!$ret) {
                throw new \RuntimeException("Could not create target directory to move temporary file into.");
            }
        }
        $this->file->move($targetDir, basename($newFilePath));
        return str_replace($this->getFilePath() . DIRECTORY_SEPARATOR, "", $newFilePath);
    }    
}

PHP::PHPExcel, Read spreadsheet partially

PHPExcel is very usual library when read or write a spreadsheet. Its main focus is to provide a set of classes for the PHP programming language, which allow you to write to and read from different spreadsheet file formats, like Excel (BIFF) .xls, Excel 2007 (OfficeOpenXML) .xlsx, CSV, Libre/OpenOffice Calc .ods, Gnumeric, PDF and HTML. The volume of library is pretty big which was why I was a bit reluctant to use it in the beginning but it contains a lot of general functionality without too much necessities.

While I write a PHPExcel, I faced a memory issue. I didn’t know this is a kind of general issues in reading spreadsheet files. Among the recommendations, I think the most useful one is to filter spreadsheet data and divide up into a chunk. It helps to limit the size of spreadsheet load, but I am not so sure if using disconnectWorksheets(), followed by unset() function actually releases the memory space properly once occupied by load() process. Maybe I should look into the function.

Anyway, here is a stock class for dividing up the file:

class ExcelReadFilter implements PHPExcel_Reader_IReadFilter
{
    private $worksheetName;
    private $startRow;
    private $endRow;
    private $columns;
    private $isChunkRead;
    private $chunkSize;

    public function __construct($startRow = 1, $endRow = 200, $columns = array('A', 'Z'), $isChunkRead = true, $chunkSize = 25) {
        $this->worksheetName = 'Worksheet';
        $this->startRow      = $startRow;
        $this->endRow        = $endRow;
        $this->columns       = $columns;
        $this->isChunkRead   = $isChunkRead;
        $this->chunkSize     = $chunkSize;
    }

    public function setWorksheetName($worksheetName) {
        $this->worksheetName = (!empty($worksheetName)) ? $worksheetName : 'Worksheet';
    }

    public function setStartRow($startRow) {
        if ( ($startRow >= 0) && ($startRow <= $this->endRow) ) {
            $this->startRow = $startRow;
            $this->endRow   = $startRow + $this->chunkSize;
        }
    }

    public function setEndRow($endRow) {
        $this->endRow = $endRow;
    }

    public function setColumns($columns) {
        $this->columns = (is_array($columns)) ? $columns  : array('A', 'Z');
    }

    public function setChunkSize($chunkSize = null) {
        if (!is_null($chunkSize)) {
            $this->chunkSize = $chunkSize;
        }
        $this->isChunkRead = true;
    }

    public function getChunkSize() {
        return $this->chunkSize;
    }

    public function readCell($column, $row, $worksheetName = '') {
        if ( ($row >= $this->startRow)
            && ($row < ($this->startRow + $this->chunkSize)) 
            && ($row <= $this->endRow) ) {
            return true;
        }
        return false;    
    }
}

This is an example of how to read through filter

protected function readRangeCells($readFilter, $docObj, $startRow) {
	$sheetData = array();
	$inputFile = $this->getInputFile();
	if ($readFilter && $this->docObj) {
		$readFilter->setStartRow($startRow);
		$docObj->setReadFilter($this->readFilter);
		$tempObj   = $docObj->load($inputFile);
		$sheetData = $tempObj->getActiveSheet()->toArray(null, true, true, true);

		// to free up the memory
		$tempObj->disconnectWorksheets(); 
		unset($tempObj);
	}
	return $sheetData;
} 

PHP::Symfony Dependency Injection

If you open a new Symfony2 structure, the first thing that hits you in the face is Dependency Injection. Most of us understand how Dependency Injection works and utilize it in their projects. But I didn’t know Symfony2 uses various ways.

  • Constructor Injection
  • Setter Injection
  • Property Injection

As the documents reads, “Making a class’s dependencies explicit and requiring that they be injected into it is a good way of making a class more reusable, testable and decoupled from others.
There are several ways that the dependencies can be injected. Each injection point has advantages and disadvantages to consider, as well as different ways of working with them when using the service container.”

Constructor Injection

The most common way to inject dependencies is via a class’s constructor. To do this you need to add an argument to the constructor signature to accept the dependency:

class NewsletterManager
{
    protected $mailer;

    public function __construct(\Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    // ...
}

here are several advantages to using constructor injection:
If the dependency is a requirement and the class cannot work without it then injecting it via the constructor ensures it is present when the class is used as the class cannot be constructed without it.

The constructor is only ever called once when the object is created, so you can be sure that the dependency will not change during the object’s lifetime.
These advantages do mean that constructor injection is not suitable for working with optional dependencies. It is also more difficult to use in combination with class hierarchies: if a class uses constructor injection then extending it and overriding the constructor becomes problematic.

You can specify what service you would like to inject into this in the service container configuration:
YAML

services:
     my_mailer:
         # ...
     newsletter_manager:
         class:     NewsletterManager
         arguments: ["@my_mailer"]

Setter Injection

Another possible injection point into a class is by adding a setter method that accepts the dependency:

class NewsletterManager
{
    protected $mailer;

    public function setMailer(\Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    // ...
}

YAML

services:
     my_mailer:
         # ...
     newsletter_manager:
         class:     NewsletterManager
         calls:
             - [setMailer, ["@my_mailer"]]

This time the advantages are:
Setter injection works well with optional dependencies. If you do not need the dependency, then just do not call the setter.
You can call the setter multiple times. This is particularly useful if the method adds the dependency to a collection. You can then have a variable number of dependencies.
The disadvantages of setter injection are:
The setter can be called more than just at the time of construction so you cannot be sure the dependency is not replaced during the lifetime of the object (except by explicitly writing the setter method to check if has already been called).
You cannot be sure the setter will be called and so you need to add checks that any required dependencies are injected.

Property Injection

Another possibility is just setting public fields of the class directly:

class NewsletterManager
{
    public $mailer;

    // ...
}

YAML

services:
     my_mailer:
         # ...
     newsletter_manager:
         class: NewsletterManager
         properties:
             mailer: "@my_mailer"

There are mainly only disadvantages to using property injection, it is similar to setter injection but with these additional important problems:
You cannot control when the dependency is set at all, it can be changed at any point in the object’s lifetime.
You cannot use type hinting so you cannot be sure what dependency is injected except by writing into the class code to explicitly test the class instance before using it.
But, it is useful to know that this can be done with the service container, especially if you are working with code that is out of your control, such as in a third party library, which uses public properties for its dependencies.

Source: http://symfony.com/doc/current/components/dependency_injection/types.html