1. Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.

PlumPHP

Discussion in 'Programming & Webmastering' started by Aquinus, Mar 29, 2012.

  1. Aquinus

    Aquinus Resident Wat-man

    Joined:
    Jan 28, 2012
    Messages:
    6,896 (6.47/day)
    Thanks Received:
    2,480
    Location:
    Concord, NH
    Hi everyone. Depending on how many web developers there are that browse through this thread, I was looking to see if anyone had any input on a project I've been working on. Like the title of the post, it is called PlumPHP. It is similar to CodeIgniter, FuelPHP, and CakePHP in the sense that it is a framework. It uses PHP >=5.3. It requires a little bit of Apache rewrite magic to make the url provide arguments rather than named get variables and currently only supports PostgreSQL for database access (but is designed to support multiple.)

    Please keep in mind that this isn't a finished product and I'm the only person working on it in my free time and when I feel like it (since I write code most of the day at work). :cool:

    Code:
    http://plum.somewebsite.com/forum/view/5
    or without rewrite magic
    Code:
    http://plum.somewebsite.com/index.php/forum/view/5
    The directory that Apache accesses is completely segregated from the application and the code. The root of Plum looking something like this:
    Code:
    app
    config.dist
    ext
    plum
    public
    README
    Where the application lives in app, static configurations go in config (.dist prepended to indicate sample config files), ext for extensions to plum, and public which contains a single index.php file which is where all traffic comes into as well as any static javascript, images, or anything that isn't going to be provided by the application itself, and plum which contains all of the core plum libraries.

    I've tried to maintain an MVC-like design for application development, but honestly usage of views is optional and I've opted for the end-user to chose how they want to manage their libraries, so the controllers are really the only required part of plum for any web application.

    Since I'm a one man army, I've only implemented bits and pieces of what I needed to get the system to work for a basic web application and I'm planning on adding more. I've been building a small portal-like application to go alongside PlumPHP so I can have an application to help me determine what does and doesn't work well, the branch is included in the github repository, but an example of a controller and a view look like this.

    Controller:
    Code:
    class Welcome extends \Plum\Controller {
        public function before() {
            if(!\Plum\Auth::is_logged_in()) {
                \Plum\Http::redirect(\Plum\Uri::href('login'));
            }
        }
    
        public function index() {
            $page = new stdClass;
            $page->breadcrumbs = array();
            \Plum\View::load('page', array('page' => $page));
        }
    }
    View:
    Code:
    <?= \Plum\Html::doctype() ?>
    
    <?php
    if(empty($page)) {
        throw new \Plum\Exception('No page object passed to page view.');
    }
    
    require_once(dirname(dirname(__FILE__)) . '/libs/lib.php');
    
    $html = new \Plum\HtmlBuilder();
    
    // TODO: Re-add this when we actually need it.
    $html->head();
    $html->title();
    if(empty($page->styles)) {
        $page->styles = array('basic');
    }
    if(!empty($page->styles) & is_string($page->styles)) {
        $page->styles = array($page->styles);
    }
    if(!empty($page->styles) & is_array($page->styles)) {
        foreach($page->styles as $style) {
            $html->link_style(\Plum\Uri::href("style/get/$style"));
        }
    }
    
    // TinyMCE time!
    // Here goes nothing!
    if(!empty($page->rtf)) {
        $html->merge_builders(\Plum\View::load('tinymce'));
    }
    $html->step_out('html');
    
    // Enter the html body and create a new drive using the header attributes.
    $div_header = array(
        'id' => 'tpl_header'
    );
    
    $div_body = array(
        'id' => 'tpl_body'
    );
    
    $div_footer = array(
        'id' => 'tpl_footer'
    );
    
    $html->body()->div($div_header);
    
    // Put header contents here.
    $bread_list = array (
        'id' => 'breadcrumbs'
    );
    $html->h(3, \Plum\Config::get('site_name', 'web'), array('id' => 'pagetitle'));
    
    // Check to see if a user is logged in.
    
    // This should take two forms. Not logged in, and logged in.
    if(\Plum\Auth::is_logged_in()) {
        $user = \Plum\Auth::get_current_user();
        $loginstr = \Plum\Lang::get('youareloggedinas') . ' '. fullname($user);
        $loginstr .= ' (' . \Plum\Xml::tag('a', 
            array('href' => \Plum\Uri::href('login/logout')),
            \Plum\Lang::get('logout')
        ) . ')';
    } else {
        $loginstr = \Plum\Lang::get('youarenotloggedin');
    }
    
    $html->raw('p', array('id' => 'loginstring'), $loginstr);
    $html->ul($bread_list);
    
    // Lets say where we are and provide it as a link for starters.
    $html->li(false, array('class' => 'breadcrumb', 'id' => 'firstbreadcrumb'))
        ->a(\Plum\Config::get('site_name_short', 'web'), \Plum\Uri::href())
        ->step_out('ul');
    
    if(!empty($page->breadcrumbs)) {
        $total = count($page->breadcrumbs);
        $c = 0;
        foreach($page->breadcrumbs as $crumb) {
            $c++;
            if(is_array($crumb)) {
                $crumb = (object)$crumb;
            }
            if(is_string($crumb)) {
                $crumb = (object)array(
                    'text' => $crumb
                );
            }
            $html->li(false, array('class' => 'breadcrumb'))
                ->span('>');
            if(!empty($crumb->url) and $c != $total) {
                $html->a($crumb->text, $crumb->url);
            } else {
                $html->span($crumb->text);
            }
            $html->step_out('ul');
        }
    }
    
    // End header contents
    $html->step_out('body');
    
    if(!empty($page->body)) {
        $html->div($div_body);
        if(is_object($page->body)) {
            if(\Plum\HtmlBuilder::is_builder($page->body)) {
                $html->merge_builders($page->body);
            } else {
                // TODO: Handle it.
            }
        }
        $html->step_out('body');
    }
    
    $html->hr('footer_hr');
    if(empty($page->footer)) {
        $page->footer = new \Plum\HtmlBuilder('div', $div_footer);
    }
    if(is_string($page->footer)) {
        $html->div($div_footer, $page->footer);
    }
    if(\Plum\HtmlBuilder::is_builder($page->footer)) {
        if(\Plum\Auth::is_privileged('site:admin')) {
            $page->footer->a(\Plum\Lang::get('adminpanel'), \Plum\Uri::href('admin'));
        }
        $html->merge_builders($page->footer, true);
    }
    $html->step_out('html');
    ?>
    
    <?= $html->get_string() ?>
    All the HTML/XML classes helps manage the HTML so it validates and so it becomes well formed. The following code produces the following page if the user is logged in. Also notice the method chaining on the HTMLBuilder (which extends the XMLBuilder.)

    HTML:
    <!DOCTYPE HTML>
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <html>
      <head>
        <title>PlumPortal</title>
        <link href="http://plum.somewebsite.com/style/get/basic" rel="stylesheet" type="text/css" media="screen" />
      </head>
      <body>
        <div id="tpl_header">
          <h3 id="pagetitle">PlumPortal 1.0</h3>
          <p id="loginstring">You are logged in as Username (<a href="http://plum.somewebsite.com/login/logout">Logout</a>)</p>
          <ul id="breadcrumbs">
            <li class="breadcrumb" id="firstbreadcrumb">
              <a href="http://plum.somewebsite.com/">PlumPortal</a>
            </li>
          </ul>
        </div>
        <hr id="footer_hr" />
        <div id="tpl_footer">
          <a href="http://plum.somewebsite.com/admin">Admin Panel</a>
        </div>
      </body>
    </html>
    
    I also apologize for not using the PHP bbcode tags for the PHP, it didn't want to render the backslashes which are kind of important in Plum since it uses namespacing.

    So my question to any of you web developers is, what do you like, what do you dislike, and what would be nice if you were to need to use a framework for something?

    Finally, all of this code is licensed GPL v3, please treat it as such if you decide to use or change it.
     
    Last edited: Mar 29, 2012
  2. W1zzard

    W1zzard Administrator Staff Member

    Joined:
    May 14, 2004
    Messages:
    15,051 (3.88/day)
    Thanks Received:
    11,954
    why do we need another php framework ?
    (i don't mean this offensive in any way)
     
    Last edited: Mar 29, 2012
  3. Aquinus

    Aquinus Resident Wat-man

    Joined:
    Jan 28, 2012
    Messages:
    6,896 (6.47/day)
    Thanks Received:
    2,480
    Location:
    Concord, NH
    Because practically none of them use the features of PHP 5.3 or have support for PostgreSQL? I liked FuelPHP but I disagreed with how they were developing it and I wasn't happy with the reception I got when I started adding postgres support to it.

    No offense taken, there are plenty of frameworks in the world, I've used a couple of them. I guess this is less about what Plum is and more about how it works.
     
    Last edited: Mar 29, 2012

Currently Active Users Viewing This Thread: 1 (0 members and 1 guest)

Share This Page