Archive

Archive for the ‘Programming’ Category

Split a file by a set number of lines

March 4, 2012 Leave a comment
I had large files that I had to split into smaller files, 
all the examples I found ran out of memory when running. 
I created this class which can split 100 MB files easily and quickly. 
Let me know if you find it useful.
class SplitFile {

    /*
     * @var Full path or relative path to where the output file will be created
     */
    private $_dest_path;

    /*
     * __construct
     */
    public function __construct($dest_path = '.')
    {
        $this->_dest_path = $dest_path;
    }

    /*
     * Split the input (text) file into smaller files by number of lines
     *
     * @param string $source_file File path of the source text file
     * @param string $output_prefix File prefix for the output files
     * @param int $split_count Number of lines per split file
     */
    public function split($source_file, $output_prefix = '', $split_count = '500000')
    {
        // File is less then split count so return file
        if($this->_getFileLineCount($source_file) <= $split_count) {
            return $this->_dest_path . '/' . $source_file;
        }

        $fileExtension = pathinfo($source_file,PATHINFO_EXTENSION);

        if($output_prefix == '') {
            $output_prefix = basename($source_file,'.'.$fileExtension);
        }

        $fileExtension = pathinfo($source_file,PATHINFO_EXTENSION);

        // Open the file for reading
        $handle = fopen($source_file, "r");

        $lineCount = 0;
        $split = 1;

        // Loop through the file until you reach the last line
        while(!feof($handle)) {
            if ($lineCount == 0) {
                $outfile = $this->_dest_path . '/' . $output_prefix . '-' . $split . ".$fileExtension";
                $outHandle = fopen($outfile,'w+');
            }

            fwrite($outHandle, fgets($handle));

            if($lineCount < $split_count) {
                // Increment the counter
                $lineCount++;
            } else {
                $split++;
                $lineCount = 0;
            }
        }

        // Release the file for access
        fclose($handle);
        unlink($source_file);
    }

    /**
    * Get the line count of a file
    *
    * @param string $file The file name
    * @return int The number of lines in a file
    */
    private function _getFileLineCount($file)
    {
        // Open the file for reading
        $handle = fopen($file, "r");
        $lineCount = 0;

        // Loop through the file until you reach the last line
        while (fgets($handle) !== false) {
            // Increment the counter
            $lineCount++;
        }

        // Release the file for access
        fclose($handle);
        return $lineCount;
    }
}
Categories: PHP, Programming

Adding items to a Sharepoint list using PHP

July 5, 2011 2 comments

At work I was asked to populate a sharepoint list from a database report. I did a lot of searching on the web for how to’s, they all seemed a little old, but they did head me in the right direction. This is my adventure.

First thing is to get the log into the sharepoint using soap, I used my own class which extends the Zend_Soap_Client class. The most important thing to remember is that after successfully logging in you have to save the cookie to send on subsequent requests. Also remember to set the WSDL to the sharepoint list URL. Below is the code:

/**
 * Log into the sharepoint site
 * @param int $count How many times the function has been called
 * @return Cisc\Web\Soapclient
 */
function webserviceLogin($count=0)
{
    // Create soap client
    $wsdl = 'https://path/to/sharepoint/list/_vti_bin/Authentication.asmx?WSDL';
    $ws = new Cisc\Web\Soapclient($wsdl);
    $login = array('username'=>'user',
                   'password'=>'pass');
    try {
        $rs = $ws->Login($login);
        if($rs->LoginResult->ErrorCode != 'NoError'){
            throw new Exception($rs->LoginResult->ErrorCode);
        }
        $ws->setSoapCookieInfo($rs->LoginResult->CookieName, getCookieValue($ws->getLastResponseHeaders()));
        return $ws;
    } catch (SoapFault $ex) {
        $log = Zend_Registry::get('log');
        $log->err($ex->getMessage());
        sleep(20); // Sleep for 10 seconds and try again
        $count++;
        if ($count < 10) {
            return webserviceLogin($count);
        }
        scriptExit('Unable to process soap call!');
    }
}

Notice the getCookieValue function, this is used to extract the cookie value since sharepoint sends the name on success but not the value. The function parses the HTTP header and extracts the cookie value. The code is below:

/**
 * Get the cookie value from the http header
 *
 * @param string $header
 * @return string
 */
function getCookieValue($header)
{
    $header_array = explode("\r\n",$header);
    foreach($header_array as $header) {
        $loop = explode(":",$header);
        if($loop[0] == 'Set-Cookie') {
            $value = explode(".ASPXAUTH=",$loop[1]);
        }
    }
    return $value[1];
}

The next bit of oddity is creating the XML file to upload. The variable used to hold the new items is called any. Gotta love Microsoft.

/**
 * Generate the xml to populate the lists
 *
 * @param array $data
 * @return string
 */
function generateXml($data)
{
    $id = 1;
    foreach($data as $rowData) {
        $xml_batch .= "<Method Cmd='New' ID='$id'>
                        <Field Name='Title'>{$row['title']}</Field>
                     </Method>";
        $id++;// Increase id number
    }

    $listname = 'list';
    $xml_add = "<Batch ListVersion='1' OnError='Continue'>$xml_batch</Batch>";
    $xml = array(
            'listName' => $listname,
            'updates' => array('any' => $xml_add)
          );
    return $xml;
}

The next thing to do is update the list with the new items.

/**
 * Update the list with the data
 *
 * @param object $ws
 * @param array $params
 */
function updateList($ws,$params)
{
    $wsdl_list = 'https://paht/to/sharepoint/list/_vti_bin/Lists.asmx?WSDL';
    // Change wsdl file
    $ws->setWsdl($wsdl_list);
    try {
        // Need to send cookie for each request
        $ws->sendCookie();
        $rs = $ws->UpdateListItems($params);
    } catch (Exception $ex) {
        $log = Zend_Registry::get('log');
        $log->err($ex->getMessage());
        scriptExit('Unable to update the list: ' . $ex->getMessage());
    }
    return $rs->UpdateListItemsResult->any;
}

And that’s pretty much it. It’s simple once you figure out the oddities but maddening until you do.

Please leave any questions, comments or criticisms.

Categories: PHP, Zend Framework

Netbeans 6.9

July 20, 2010 Leave a comment

My new favorite PHP IDE is Netbeans 6.9 . Netbeans is great for what I do, but your mileage may vary. First of all it uses a loss less ram then Eclipse which is great because I don’t have a lot. At work I have to use a very old Windows XP desktop, with only 1.5 gigs of ram so anytime I use Eclipse it really slows down the machine.

Netbeans has great Zend Framework integration and making it extremely easy to use Zend Tool. The only feature it lacks for me is jQuery integration. A nice add-on I found is called Path Tools, it makes it easy to copy a project path, open a window with the project directory selected or open a terminal window in the project. The requirements do not state 6.9 compatibility but I have not had any problems. BTW, there is a version of Path Tools for Eclipse.

Categories: PHP, Zend Framework

Hide borders for an input box

November 6, 2009 Leave a comment

I wanted to have a form with read only input boxes that were populated by Ajax calls. The problem is there was a border around the box in IE7 and FF 3.5. In IE6 border=0 solved the issue but not in the other browsers. Thanks to this site for the inspiration I was able to remove the borders using this css style:

.hiddenlabel[type="text"] 
{
border:none;
display:inline;
vertical-align:middle;
}

The key is the [type="text"], this applies the style to the input box. Just in case your wondering why I need to do this it is because I need the information in the form to be submitted and need to update the information using Ajax. This was easier than using hidden fields.

Categories: CSS Tags:

Save an email attachment using Zend Mail

June 10, 2009 8 comments

To do some automated billing I needed to grab an email attachment off the exchange server. The Zend framework made it very easy to connect to the mail server and navigate files, and that part of the code came directly from the Zend Framework documentation. The issue that took the longest was saving the attachment. I could not figure out how to decode the attachment using the Zend framework. Let me know if you have a better way or if it helps you out.
NOTE: If you getting the mail from the INBOX you do not have to use the getFolders() function.

// Connecting with Imap
$mail = new Zend_Mail_Storage_Imap(
        array('host'     => 'SERVER',
              'user'     => 'USERNAME',
              'password' => 'PASSWORD'));

// Navigate to desired folder
$folder = $mail->getFolders()->INBOX->Info;

// Change to folder
$mail->selectFolder($folder);

// Loop through messages
foreach ($mail as $message)
{
 // Find desired message subject
 if($message->subject == 'SUBJECT')
 {
 // Check for attachment
 if($message->isMultipart())
 {
    $part = $message->getPart(2);
 }

 // Get the attacment file name
 $fileName = $part->getHeader('content-description');

 // Get the attachement and decode
 $attachment = base64_decode($part->getContent());

 // Save the attachment
 $fh = fopen($fileName, 'w');

 fwrite($fh, $attachment);

 fclose($fh);
 }
}

Categories: PHP, Zend Framework

Getting the root node from an XML string

June 3, 2009 Leave a comment

PHPs SimpleXML is great for parsing xml files. The downside is that it does not return the root node name. I wrote this function that gets the name.


/**
 * function getXMLRootNode
 * @param string An xml string
 * @return string Return XML root node name
 */

function getXMLRootNode($xmlstr)
{
 // Create DOM model
 $doc = new DOMDocument();

 // Load the XML string
 if(!$doc->loadXML($xmlstr))
 {
 throw new Exception('Unable to parse XML string');
 }

 // Find the root tag name
 $root = $doc->documentElement;

 if(!isset($root))
 {
 throw new Exception('Unable to find XML root node');
 }

 if(!isset($root->nodeName))
 {
 throw new Exception('Unable to find XML root node name');
 }

 return $root->nodeName;
}

Categories: PHP, Programming

New autoloading with Zend Framework 1.8

May 15, 2009 2 comments

I love the fact that you can autoload classes using the ZF. I was a little shocked at the depreciation errors when I updated to ZF 1.8. Apparently, there is a new way to use the autoload class. It took a little reading but I came up with this solution. Let me know what you think!

/*
 * Set up Zend loader
 */
require_once 'Zend/Loader/Autoloader.php';

$autoloader = Zend_Loader_Autoloader::getInstance();

/*
 * Register Cisc Classes
 */
$autoloader->registerNamespace('Cisc_');

The registerNamespace function registers my own classes.

Categories: PHP Tags:

Creating a Soap Server using the Zend Framework

May 15, 2009 Leave a comment

I decide to try my hand at creating a soap server using the Zend Framework. This was an exersice in getting me more familiar with ZF and web services. Hopefully this will help others. I think the code is pretty self explanitory but feel free to ask questions or provide comments.

Basically the WSDL is auto generated by php if the URL ends in ?wsdl, if not then the soap server is created and the request handled.


/*
* Check to see if soap call is to be handled
* or if the WSDL should be displayed
*/
if(isset($_GET['wsdl']))
{
    createWSDL();
}
else
{
   /*
    * Soap Server WSDL document
    */
    $wsdl = 'http://' . $_SERVER["SERVER_NAME"] .
    $_SERVER['PHP_SELF'] . '?wsdl';

   /*
    * Create a new soap server
    */
    $server = new Zend_Soap_Server($wsdl,
        array('soap_version' => SOAP_1_2)
    );

   /*
    * Set the server to cache the wsdl file
    */
    $server->setWsdlCache(1);

   /*
    * Set the class for the web service
    */
    $server->setClass('Cisc_Ws_Cs3webservice');

   /*
    * Set soap server persistance (For use with login feature)
    */
    $server->setPersistence(SOAP_PERSISTENCE_SESSION);

   /*
    * Register exceptions
    */
    $server->registerFaultException('Exception');
   /*
    * Handle the soap call
    */
    $server->handle();
}

/**
* Create the WSDL file for display
*
* @param none
* @return string The wsdl xml
*/
function createWSDL()
{
    $wsdl = new Zend_Soap_AutoDiscover();

    $wsdl->setClass('Cisc_Ws_Cs3webservice');

    $wsdl->handle();
}

The WSDL is created from the class file, so make sure you use proper documentation blocks for you code. The only issue I have seen so far is that if a function input in the class is a integer,
no matter what is inputted, an integer will be pass to the function. This makes it difficult to verify data, say that your getting an integer and not a float. The workaround is to pass an array
and check the values of the array.

Categories: PHP Tags:

Zend Server Community Edition Install

March 4, 2009 3 comments

So  I decided I would try out Zend Server CE. I have tried the installation on a server running Windows 2003 and XP Professional with PHP already installed using ISAPI. The install goes fine, but when I try to access the web page I get an FastCGI Access Denied error.

I have tried everything I can think of, including the suggestions on the web for changing permissions on several directories, but I still cannot resolve this issue. I am going to try and get it working but if anybody has any suggestions please let me know.

UPDATE: I was finally able to get Zend Sever installed. I had to remove IIS using add/remove programs, re-install it, then install Zend Server. I like it a lot.

Categories: PHP, Programming

Cross Domain Ajax

September 29, 2008 Leave a comment

I found a nice simple way to do cross domain ajax calls reliably. I found this Yahoo page that gives a nice little tutorial on how to use php and curl to access other domains using a simple proxy. Simple and effective. The code that I tweeked for my own use is found here. Let me know if you have any comments or suggestions.

Categories: PHP, Programming
Follow

Get every new post delivered to your Inbox.

Join 43 other followers