DOWNLOAD
Released Saturday, November 12, 2011 - most recent version
Datapod for PHP - Version 0.10.00
"Smooth-Site-Creation Version"
The process of creating ItemTypes has become very streamlined so you basically just have to dump in your schema and item text and you can immediately search, click, view, and set to the page on which they are displayed public or viewable only to certain groups. You then can alter the two methods displaySummaryWithLink() and displaySingle() in the singular class for that ItemType and your items are fully customized. Since the querying and sorting is far enough along for most basic needs, creating Datapod sites is just a matter of defining your ItemTypes, creating pages, selecting items and displaying them where you need them. 
Latest Beta Version:
This version has many bug fixes since the November 2011 release, plus easy-to-create jQuery/AJAX actions, the ability to create PDF files, and the ability to create images with the ImageMagick library (see showcase).
New Features in Version 0.10.00:
    FEATURE:
    Items Now Viewable and Searchable Immediately After Creation
    When you create an ItemType now, all functionality is created for you by default: full-text AJAX search on all fields, and data is shown semantically based on data types, so if a field is of type "isbn", then it automatically has a link to its Amazon page, and if a field is of type "stars", then it automatically shows itself represented as graphic stars. In addition, there is a displaySummaryWithLink view for each record which leads to its displaySingle view, with links to each individual record. This means that immediately after you create an ItemType with records, they are viewable and searchable in a convenient fashion.
    TRY IT:
    1. in the developer menu, click on Create Item Type
    2. copy the "books" Item Type example text
    3. paste it into the box
    4. click the Create Item Type Now button
    WATCH IT:
    How to Create an ItemType
    FEATURE:
    Embed YouTube Videos in SmartNotes
    In any text that is parse with SmartNotes, you can now put at the end of the line @@theyoutubeid and the video will appear embedded below that line in the text.
    TRY IT:
    1. create the example "Books" ItemType
    2. in the "Head First Design Patterns" record, add the line Here is an video of design patterns in Python:@@0vJJlVBVTFg
    3. view the record and the video will appear
    FEATURE:
    Export and Import ItemTypes Between Datapod Sites
    It is now possible to share ItemTypes between datapod sites by using "Export ItemType" and "Import ItemType" on the developer menu.
    TRY IT:
    1. click on Export ItemType
    2. choose ItemType to export
    3. a zip file will be created
    4. move zip file to import directory of another datapod site
    5. in that site, click "Import ItemTypes"
    6. item type will be recreated from ItemType schema, custom methods will be copied back in into singular and plural ItemType classes, any images belonging to item types will also be copied
    FEATURE:
    Simplified Item Selection and Display
    After you have created an ItemType with items, you have a simplified way to select and display them simply using the select and display methods available in the DatapodItem and DatapodItems classes.
    FEATURE:
    New Item Initialization
    After you add new items to their data file, clicking on the title of your Datapod Site will initialize those items, giving them a unique ID-Code, a WhenCreated field, and each field will be labeled so that the rest of the data is easier to add.
    FEATURE:
    Dynamic Properties
    You can now define any value you want in the Extras field and then access it with a getter. This means that if you need to quickly keep track of some kind of information on records, you don't have to recreate the item and add the field, you just add the data to the items you need, and the value for all the other items which don't have this field is an empty string.
New Methods Added in Version 0.10.00:
    $datapodItem->getSmartImagePathAndFileName() Allows you to save an image with a file name the same name as the ID-Code of the item, either in .jgp, .gif, or .png, in either the ItemTypes folder or the specific folder for that ItemType. This allows you to use a screen capture program (e.g. SnagIt) on which you have defined a hotkey which saves screenshots from various types of items all in one directory. When an ItemType is exported, it takes all the pictures out of this general directory as well.
    EXAMPLE:
    $book dpod::select('book;selectWithIdCode(jqueryAction)');
    /* @var $book Book */
    $iconPathAndFileName $book->getSmartImagePathAndFileName();
    echo 
    '<p>'.$book->getTitle().'</p>';
    echo 
    '<img src ="'.$iconPathAndFileName.'"/>';

    //IMAGE CAN BE ANY OF THESE:
    //customImages\itemTypes\jqueryAction.jpg
    //customImages\itemTypes\jqueryAction.gif
    //customImages\itemTypes\jqueryAction.png 
    //customImages\itemTypes\books\jqueryAction.jpg
    //customImages\itemTypes\books\jqueryAction.gif
    //customImages\itemTypes\books\jqueryAction.png
    RESULT:
    qfil::createZipFileFromDirectory() Allows you to zip any directory into a zip file. Use a relative path and file name (directly under your website directory). It zips recursively so any sub-directories will also be zipped. Note that directories that are empty will not be copied into the zip file.
    EXAMPLE:
    qfil::createZipFileFromDirectory('export/parseFiles.zip''export/parseFiles');
    RESULT:
    qfil::unpackZipFile() Simply unzips a zip file into a target directory.
    EXAMPLE:
    qfil::unpackZipFile('export/parseFiles.zip''export/parseFiles');
    RESULT:
    qdat::getTimeStamp() Returns the current date/time for use in displaying a generic time something happened.
    EXAMPLE:
    $timeStamp qdat::getTimeStamp();
    echo 
    '<p>Report was printed at '.$timeStamp.'.</p>';
    RESULT:
    Report was printed at 2011-11-12 07:18:16.
    qsys::getIncomingVariable() Gets the POST variable, if not available, then gets the GET variable.
    EXAMPLE:
    $status qsys::getIncomingVariable('status');
    echo 
    '<p>status is "'.$status.'".</p>';
    RESULT:
    qpre::displayIconWithContentArea() Easy way to display anything (e.g. an item) on the screen with an icon to the left and the content (e.g. title first) on the right, all top justified, etc. You can also override CSS with parameters.
    EXAMPLE:
    $iconArea '<div ><img src="systemImages/general/iconPaper.png"/></div>';
    $iconArea .= '<div style="font-size:10pt">public</div>';
    $contentArea '<h3>Complex number</h3>';
    $contentArea .= 'A complex number is a number consisting of a real part and an imaginary part. Complex numbers extend
    the idea of the one-dimensional number line to the two-dimensional complex plane by using the number line for the real
    part and adding a vertical axis to plot the imaginary part. In this way the complex numbers contain the ordinary real 
    numbers while extending them in 
    order to solve problems that would be impossible with only real numbers.'
    ;

    echo 
    qpre::displayIconWithContentArea($iconArea$contentArea);
    RESULT:
    qstr::getTranslation() Allows a simple way to implement multiple-lingual websites. Currently you need to handle the language code manually (keep in a session, etc.).
    EXAMPLE:
    $message 'Please wait.@@LANG_DE:Bitte warten Sie.@@LANG_FR:Veuillez patienter s\'il vous plaĆ®t.';
    echo 
    '<p>'.qstr::getTranslation($message'fr').'</p>';
    echo 
    '<p>'.qstr::getTranslation($message'en').'</p>';
    echo 
    '<p>'.qstr::getTranslation($message'de').'</p>';
    echo 
    '<p>'.qstr::getTranslation($message'ru').'</p>';
    RESULT:
    qdat::getTimeStampForFileName() Returns a timestamp string to be used e.g. at the end of a filename. E.g. when exporting ItemTypes we stamp the .zip file with a timestamp as an easy way to show versioning.
    EXAMPLE:
    $fileName 'backup_'.qdat::getTimeStampForFileName().'.zip';
    echo 
    '<p>'.$fileName.'</p>';
    RESULT:
    backup_2011-11-11-04-01-43.zip
    qpre::displaySmartImage() Returns an HTML IMG element which has the full URL to the site as a path, important for external linking applications, e.g. Facebook to grab thumbnail for a post.
    EXAMPLE:
    echo qpre::displaySmartImage('customImages/notice.png');
    RESULT:
    $datapodItem->isMostRecent() Returns whether or not the current item is the most recent items in the set of plural items sent.
    EXAMPLE:
    $books dpod::select('books');
    if (
    count($books->getItems()) > 0) {
        foreach (
    $books->getItems() as $book) {
            
    /* @var $book Book */
            
    $niceDateTime qdat::getNiceShortAmericanDayAndDateWithoutYearAndTime($book->getWhenCreated());
            if (
    $book->isMostRecent($books)) {
                echo 
    '<p style="font-weight:bold">' $marker $book->getTitle() . ' added at ' $niceDateTime '</p>';
            } else {
                echo 
    '<p>' $marker $book->getTitle() . ' added at ' $niceDateTime '</p>';
            }
        }
    }
    RESULT:
    qstr::chopLeftLines() Removes a string from the left of a group of strings.
    EXAMPLE:
    $fileNames[] = 'test1.txt';
    $fileNames[] = 'test2.txt';
    $fileNames[] = 'test3.txt';
    $fileNames[] = 'test4.txt';
    $simpleFileNames qstr::SchopLeftLines($fileNames'test');
    if (
    count($simpleFileNames) > 0) {
        foreach (
    $simpleFileNames as $simpleFileName) {
            echo 
    '<p>'.$simpleFileName.'</p>';
        }
    }
    RESULT:
    qstr::chopRightLines() Removes a string from the right of a group of strings.
    EXAMPLE:
    $fileNames[] = 'test1.txt';
    $fileNames[] = 'test2.txt';
    $fileNames[] = 'test3.txt';
    $fileNames[] = 'test4.txt';
    $fileNameIdCodes qstr::SchopRightLines($fileNames'.txt');
    if (
    count($fileNameIdCodes) > 0) {
        foreach (
    $fileNameIdCodes as $fileNameIdCode) {
            echo 
    '<p>'.$fileNameIdCode.'</p>';
        }
    }
    RESULT:
    qsys::getSiteIsOnline() Returns whether or not site is online (uploaded to web hoster and live) or not. This allows you to, for example, make a backup when someone logs in, but only when the site is live on the server, but not when locally (and hence not being used productively).
    EXAMPLE:
    if(qsys::getSiteIsOnline()) {
        
    qfil::createZipFileFromDirectory('backups/backup'.qdat::getTimeStampForFileName().'.zip''userData');
    }
    RESULT:
    (this would zip the directory "userData" into the zip file, but only be executed when the site is being accessed on the web hosting provider)
    qstr::getLinesThatEndWith() Given an array of lines (strings), returns lines which end with a certain suffix. E.g. to get all path-and-file-names that end with a certain extension.
    EXAMPLE:
    $lines[] = 'How to you upload a document in Google Docs?';
    $lines[] = 'MySQL Databases';
    $lines[] = 'How can you make an easy menu with jQuery?';
    $linse[] = 'JavaScript: The Good Parts';

    $questions qstr::getLinesThatEndWith($lines'?');
    if (
    count($questions) > 0) {
        foreach (
    $questions as $question) {
            echo 
    '<p>'.$question.'</p>';
        }
    }
    RESULT:
    How to you upload a document in Google Docs?
    How can you make an easy menu with jQuery?
    qsys::getCallingPageItemIdCode() Gets the idcode of the page on which the user clicked to get to the current page. You can get then use this ID-Code to get the PageItem object as shown in the example.
    EXAMPLE:
    $callingPageIdCode qsys::getCallingPageItemIdCode();
    $pageItem dpod::select('pageItem;selectWithIdCode('.$callingPageIdCode.')');
    echo 
    '<p>'.$callingPageIdCode.'</p>';
    echo 
    '<p>You came from page "'.$pageItem->getTitle().'".</p>';
    RESULT:
    switchLayout
    You came from page "Switch Layout".
    qstr::getDuplicates() Returns the strings in an array that are the same.
    EXAMPLE:
    $lines[] = 'How to you upload a document in Google Docs?';
    $lines[] = 'MySQL Databases';
    $lines[] = 'How can you make an easy menu with jQuery?';
    $lines[] = 'MySQL Databases';
    $lines[] = 'JavaScript: The Good Parts';
    $lines[] = 'How can you make an easy menu with jQuery?';

    echo 
    '<h3>In this list:</h3>';
    if (
    count($lines) > 0) {
        foreach (
    $lines as $line) {
            echo 
    '<p>'.$line.'</p>';
        }
    }

    echo 
    '<h3>These are duplicates:</h3>';
    $duplicates qstr::getDuplicates($lines);
    if (
    count($duplicates) > 0) {
        foreach (
    $duplicates as $duplicate) {
            echo 
    '<p>'.$duplicate.'</p>';
        }
    }
    RESULT:
    qfil::copyDirectoryContents() Copies the contents of one directory into the contents of another, if second directory does not exist, it will be created.
    EXAMPLE:
    qfil::copyDirectoryContents('import/import_files''import/import_files_parsed');
    RESULT:
    $smartUrl->getQueryVariableValue() The SmartUrl class now has a method to get the value of a URL variable.
    EXAMPLE:
    $smartUrl SmartUrl::createWithUrl('https://www.google.com/search?q=kahn+math&ie=utf-8');
    /* @var $smartUrl SmartUrl */
    $searchWordList $smartUrl->getQueryVariableValue('q');
    echo 
    '<p>'.$searchWordList.'</p>';
    RESULT:
    kahn+math
    qstr::getFileNameFromUrl() Returns the file name from a URL.
    EXAMPLE:
    $fileName qstr::getFileNameFromUrl('http://www.tanguay.info/dpphp/index.php?pageItem=switchLayout');
    echo 
    '<p>'.$fileName.'</p>';
    RESULT:
    index.php
    qfil::getFileNameFromRelativePathAndFileName() Gets the file name from the path-and-file-name string. You often use this after you get an array of path-and-file-names from a directory and then e.g. want to display only the files names in some way.
    EXAMPLE:
    $pathAndFileNames qfil::getRelativePathAndFileNamesInDirectoryRecursive('import/import_files');
    if (
    count($pathAndFileNames) > 0) {
        foreach (
    $pathAndFileNames as $pathAndFileName) {
            
    $fileName qfil::getFileNameFromRelativePathAndFileName($pathAndFileName);
            echo 
    '<p>'.$pathAndFileName.' (<b>'.$fileName.'</b>)</p>';
        }
    }
    RESULT:
    qfil::getIdCodeFromFilePathAndName() Returns the "non-extension" part of the file name in a path-and-file-name. The ID-Code is used a lot to e.g. load a like-named image from another directory by convention.
    EXAMPLE:
    $pathAndFileNames qfil::getRelativePathAndFileNamesInDirectoryRecursive('import/import_files');
    if (
    count($pathAndFileNames) > 0) {
        foreach (
    $pathAndFileNames as $pathAndFileName) {
            
    $fileIdCode qfil::getIdCodeFromFilePathAndName($pathAndFileName);
            
    $imagePathAndFileName 'customImages/importImages/'.$fileIdCode.'.png';
            
    $fileName qfil::getFileNameFromRelativePathAndFileName($pathAndFileName);
            echo 
    '<p>for <b>'.$fileName.'</b> we will display this image: <b>'.$imagePathAndFileName.'</b></p>';
        }
    }
    RESULT:
    qfil::getFileNamesInDirectoryRecursive() Gets the names of files only (e.g. "first.png") from a particular directory. E.g. if you want to check to make sure there are no duplicate files in a complex directory structure.
    EXAMPLE:
    $imageFileNames qfil::getFileNamesInDirectoryRecursive('customImages/layouts/datapodForPhp''png,gif');
    if (
    count($imageFileNames) > 0) {
        foreach (
    $imageFileNames as $imageFileName) {
            echo 
    '<p>'.$imageFileName.'</p>';
        }
    }
    RESULT:
New Code Conventions in Version 0.10.00:
  • Name object variables after classes: all object variables should be named the camelcase equivalent of their classes, e.g. $smartUrl = new SmartUrl() except for $item can be of type DatapodItem and $items can be of type DatapodItems.
  • $record/$itemRecord: $record = associative array (e.g. $record['firstName'] = "Jim", $record['lastName'] = "Smith"), although an $itemRecord is the same as a $record but matches its fields one-to-one to an ItemType
  • $sql/$sqlStatement: $sql = an SQL string, e.g. "INSERT INTO dpod_site_...", but an $sqlStatement is an SqlStatement object which e.g. builds SQL strings ($sql)
  • Name of object on end: always put the name of the object on the end, e.g. $processedPathAndFileNames (not $pathAndFileNamesToBeProcessed) e.g. for for/next loops
  • Convention: build...() and get...(): when naming methods, use the prefix "get" if you are returning a value and the prefix "build" or "define" if you are setting the value of an internal variable, "build" indicates a more involved process than "define"
  • Use the word "ItemType": when referring to an ItemType, use the word "ItemType" in text, not "itemtype" or "item type".
New FAQs Added in Version 0.10.00:
  • What is the purpose of qtools? Why do you make so many static functions that do simple tasks such as qstr::isEmpty() and qstr::getAreEqual() etc.? Because eventually all qtools (Quick Tools) will be available in the interface via a simplified script language. In addition, Datapod implementations in other languages (Javascript, ASP.NET MVC, etc.) will use the same qtools, so that it will be easier to switch between Datapod frameworks no matter what base technology they use.
  • How to make added records unique? When I add records to a text file they don't have an ID-Code like the other records in the file. How can I get datapod to automatically add this? When logged in as developer, if you click on the site name, it will execute the file update.php which will go through all text files and assign an ID-Code and "whenCreated" time stamp for each new record.
Documentation Added in Version 0.10.00:
  • Difference between an "interface developer" and a "code developer": An interface developer is someone who creates a site with Datapod but would never write an "if statement" or open up a code editor such as NetBeans or Eclipse. The current version of Datapod only has the beginnings of functionality for interface developesr, e.g. you can create a page but in order to edit the content of the page, or change the rights of who sees the page, you need to open at least a text editor and change certain files. You can also create ItemTypes through the Datapod Interface (on the developer menu), but to edit how they look, you need to modify the code. As Datapod advances, more and more functionality will be moved from that of a code developer to that of an interface developer. Note that I have begun to label class methods with metadata which identify them as a method for a code developer or an interface developer (mostly select and display methods).
  • "Select Methods" and "Display Methods": A select method is used to query an ItemType for certain items. You can think of them as stored procedures. A display method returns HTML. The basic approach to creating content on a Datapod site is to (1) use a select method to get a certain number (and order) of items, then (2) use a display method to display these in HTML.
New Terminology in Version 0.10.00:
  • list: a "list" is a comma-separated list of ID-Code values, e.g. "jpg,gif,png"
  • part: a "part" is a "part of a string", e.g. very often in Datapod you are breaking up a "list" of values such as "jpg,gif,png" into an array, the common line for this is $parts = qstr::breakIntoParts($extensionList, ',')