Updates from June, 2011 Toggle Comment Threads | Keyboard Shortcuts

  • webscriptz 22:37 on 23/06/2011 Permalink | Reply
    Tags: , data, , , , , , , ,   

    Using Our Models To Do Basic Queries On The DB 

    The application has an auto-generated model, Gii kindly provides the model once the database is created.

    01
    <?php
    02
    class Product extends CActiveRecord
    03
    {
    04
        /**
    05
         * The followings are the available columns in table 'Product':
    06
         * @var integer $id
    07
         * @var integer $brandId
    08
         * @var string $name
    09
         * @var string $price
    10
         */
    11
     
    12
        /**
    13
         * Returns the static model of the specified AR class.
    14
         * @return CActiveRecord the static model class
    15
         */
    16
        public static function model($className=__CLASS__)
    17
        {
    18
            return parent::model($className);
    19
        }
    20
     
    21
        /**
    22
         * @return string the associated database table name
    23
         */
    24
        public function tableName()
    25
        {
    26
            return 'Product';
    27
        }
    28
     
    29
        /**
    30
         * @return array validation rules for model attributes.
    31
         */
    32
        public function rules()
    33
        {
    34
            return array(
    35
                array('name','length','max'=>255),
    36
                array('price','length','max'=>8),
    37
                array('name, price', 'required'),
    38
            );
    39
        }
    40
     
    41
        /**
    42
         * @return array relational rules.
    43
         */
    44
        public function relations()
    45
        {
    46
            // NOTE: you may need to adjust the relation name and the related
    47
            // class name for the relations automatically generated below.
    48
            return array(
    49
                'brand' => array(self::BELONGS_TO, 'Brand', 'brandId'),
    50
                'categories' => array(self::MANY_MANY, 'Category', 'ProductCategory(productId, categoryId)'),
    51
            );
    52
        }
    53
     
    54
        /**
    55
         * @return array customized attribute labels (name=>label)
    56
         */
    57
        public function attributeLabels()
    58
        {
    59
            return array(
    60
                'id'=>'Id',
    61
                'brandId'=>'Brand',
    62
                'name'=>'Name',
    63
                'price'=>'Price',
    64
            );
    65
        }
    66
    }

    Enable your weblogger: this you will find in: /yourProject/protected/config/main.php

    By default your log array looks something like this: (Tip: IF you haven’t done this, and you find it hard to find you way in the file, comment everything you deem meaningful, use spaces and limit blocks of codes with comment of your choice)

    1
            'log'=>array(
    2
                'class'=>'CLogRouter',
    3
                'routes'=>array(
    4
                    array(
    5
                        'class'=>'CFileLogRoute',
    6
                        'levels'=>'error, warning',
    7
                    ),
    8
                ),
    9
            ),

    Let’s add in the CWebLogRoute so it looks like this.

    01
      'log'=>array(
    02
                'class'=>'CLogRouter',
    03
                'routes'=>array(
    04
                    array(
    05
                        'class'=>'CFileLogRoute',
    06
                        'levels'=>'error, warning',
    07
                    ),
    08
                    array(
    09
                        'class'=>'CWebLogRoute',
    10
                        'levels'=>'trace,info, error, warning',
    11
                    ),
    12
                ),
    13
            ),

    Visit the application and notice that at the bottom of the screen a table is shown displaying everything Yii does to make it possible for the website to be shown correctly. This is especially useful when you’re new to the Yii DB stuff.

    Let’s start by getting all of our products. If you are trying this tutorial, then please create a simple new installation, config the database settings in /protected/config/main.php and create your database with the proposed columns from the model seen earlier.

    You can test this in any controller, because the system already has a default SiteController in: /protected/controllers/siteController.php, this tutorial will use siteController.php with the view-file in: /protected/views/site/index.php

    So we’ll first modify our SiteController::actionIndex method.

    1
        public function actionIndex()
    2
        {
    3
            $this->render('index', array(
    4
                'Products' => Product::model()->findAll(),
    5
            ));
    6
        }

    Open the view-file related to the actionIndex() The system has an array that will be passed to our index view. This array contains ‘Products’ which will be usable as ‘$Products’ in our view: /protected/views/site/index.php

    01
    <?php $this->pageTitle=Yii::app()->name; ?>
    02
     
    03
    <h1>
    04
        Welcome, <?php echo Yii::app()->user->name; ?>!
    05
    </h1>
    06
    <table>
    07
    <?php foreach($Products AS $Product):?>
    08
        <tr>
    09
            <td><?php echo $Product->name;?></td>
    10
            <td><?php echo $Product->price;?></td>
    11
        </tr>
    12
    <?php endforeach;?>
    13
    </table>

    The system (Yii) writes the SQL statements for us thanks to the AR and everything behind that, but we got back an array of product objects.

    Now let’s use the ‘brand’ relation that is set in our Product model.

    Without changing the controller, we can simply change the view and add the line to output the brand name.

    1
    <td><?php echo $Product->brand->name;?></td>

    Now how did Yii do that? Look at the screen logger. You will see that it used the ‘lazy-loading’ technique to query the Brand table at that point.

    1
    Querying SQL: SELECT * FROM `Product`
    2
     
    3
    Querying SQL: SELECT `Product`.`id` AS `t0_c0`, t1.`id` AS `t1_c0`,
    4
    t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product` LEFT OUTER
    5
    JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`) WHERE (`Product`.`id`=3)
    6
     
    7
    Querying SQL: SELECT `Product`.`id` AS `t0_c0`, t1.`id` AS `t1_c0`,
    8
    t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product` LEFT OUTER
    9
    JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`) WHERE (`Product`.`id`=4)

    This is not the best way to go so let’s change the actionIndex in siteController.php

    1
        public function actionIndex()
    2
        {
    3
            // renders the view file 'protected/views/site/index.php'
    4
            // using the default layout 'protected/views/layouts/main.php'
    5
            $this->render('index', array(
    6
                'Products' => Product::model()->with(array('brand'))->findAll(),
    7
            ));
    8
        }

    One query is all that is needed for all the data to be collected.

    1
    Querying SQL: SELECT `Product`.`id` AS `t0_c0`, `Product`.`brandId` AS
    2
    `t0_c1`, `Product`.`name` AS `t0_c2`, `Product`.`price` AS `t0_c3`, t1.`id`
    3
    AS `t1_c0`, t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product` 
    4
    LEFT OUTER JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`)

    The view file does not have to change for this. This technique is called eager-loading and has advantages over lazyloading sometimes.

    This tutorial is a modified tutorial from another website/blog that unfortunantly isn’t online anymore, domain is being sold by godaddy.com, so I search my archives to retrieve this on, and post him here, hence a few additions, deletes and rewrites from me.

     
  • webscriptz 22:16 on 23/06/2011 Permalink | Reply
    Tags: , , , , , , , , , , ,   

    YiiFramework adding functions to your models 

    MVC has some principals to it, like the fat model principal that I’ll show in this tutorial and which is used in a lot of frameworks. I’m going to show how to add and use functions that can be added to a model.

    There are a few ways to add to a models that increase code re-usability. One way is to just add methods to the models, methods which can execute complex queries and make your controller thinner.

    The first example, a query that will get all products within a price range, it will need a limit and an offset for pagination, so in the Products model, the following function can be added:

    1
    public function findAllByPrice($min=0, $max=1000000, $offset = 0, $limit = 30) {
    2
        $Criteria = new CDbCriteria();
    3
        $Criteria->condition = "price >= :min AND price <=:max";
    4
        $Criteria->limit = $limit;
    5
        $Criteria->offset = $offset;
    6
        $Criteria->params = array ( ':min' => $min, ':max' => $max );
    7
        return $this->with(array('brand'))->findAll($Criteria);
    8
    }

    Now in any of the controlller files this method can be easily accessed and returns all of the ‘Product’ objects with a single line command:

    1
    $Products = Product::model()->findAllByPrice(100, 700, 0, 30);

    Another way to do the same is to:

    1
    public function getProducts($category){
    2
        return $this->findAll('categoryIdFk=:category', array(':category'=>$category));
    3
    }

    Let’s implement the first query using two named scope methods that I’ll create.

    1
    // Price Between - Named Scope ---------------------------------//
    2
    public function scopePriceBetween($min, $max) {
    3
        $Criteria = new CDbCriteria();
    4
        $Criteria->condition = "$this->tableName().price BETWEEN :min AND :max";
    5
        $Criteria->params = array(':min' => $min,   ':max' => $max);
    6
        $this->getDbCriteria()->mergeWith($Criteria);
    7
        return $this;
    8
    }

    Now an additional named scope for the limit element

    1
    //  Limit - Named Scope --------------------------------------//
    2
    public function scopeLimit($limit = 30, $offset = 0) {
    3
        $Criteria = new CDbCriteria();
    4
        $Criteria->limit = $limit;
    5
        $Criteria->offset = $offset;
    6
        $this->getDbCriteria()->mergeWith($Criteria);
    7
        return $this;
    8
    }

    Now we can simply use our named scopes to get our data back, and then we could continue to pile on named scopes to return our data.

    1
    $Products = Product::model()->scopePriceBetween(0, 5000) ->scopeLimit(30, 1)->findAll();

    The query that actually gets executed is simple and looks like this:

    1
    SELECT * FROM `Product` WHERE Product.price BETWEEN :MIN AND :MAX LIMIT 30 OFFSET 1

    This tutorial is a modified tutorial from another website/blog that unfortunantly isn’t online anymore, domain is being sold by godaddy.com, so I search my archives to retrieve this on, and post him here, hence a few additions, deletes and rewrites from me.

     
  • webscriptz 19:03 on 23/06/2011 Permalink | Reply
    Tags: , , , myssql, , sql view, , , ,   

    mySQL view and YiiFramework 

    The sql standard gives the possibility to create a view, a view is or can be a mask of one column for a special user that only has access to some of the data and thus not all the data stored in the column? The view can also be used to regroup data from multiple column into one, this can be handy if you need to display that selection a lot.

    Limitations
    It might be wise to, first, learn what you can do with it as it is not a all-in-one solutions for al your troubles and ideas. You can use a view to DISPLAY data, but unless you display all the data from the column or columns, which most of the time doesn’t make sense, you can NEVER use it to insert data IF any other columns are required to be filled out.

    How to create a view in mySQL
    The syntax, normally, can be used in other databases to but I’m focussing on mySQL.

    1
    <code lang="sql[lines]">CREATE VIEW [name of the view] AS [ your query];

    Best is that you make a clear distinction between the original tables and the view by for instance writing "_view" after it, this will help later when reviewing the database or using the view element with the YiiFramework.

    You can in fact put everything you want in the [your query] section as long as it is valid SQL. You also need to be careful when using this that whatever query you make, you don't ask the Cartesian product, this however you need to do with every single query you ever make where joints and where clauses are involved.

    YiiFramework and Views
    This is the fastest part, you create your model with Gii, and you do the rest of your magic to write your application.

     
  • webscriptz 00:06 on 25/03/2011 Permalink | Reply
    Tags: 127.0.0.1, apache, apache2, bind9, , console, , dns, fedora, hosts, httpd, , local domain name, name-based virtual host, nano, virtual hosts   

    Fedora Core – virtual hosts httpd 

    I’ve reinstalled my pc with Fedora Core recently, because of the extended SELinux and more tools that are at my disposal. A problem I always had with ubuntu was the configuration of Apache virtual hosts. Once they where installed I needed to put them into the host file and each time I reconnected to a network the NetworkManager rewrote the hosts file annoying me and the fact that if one was configured localhost would also begin pointing to it, a rather nasty thing.

    First you need to open the console and login with your root user, type su and fedora will already know what to do.

    You need to shutdown the httpd servic deamon with the command :

    1
    /etc/init.d/httpd stop

    You will have to open /etc/httpd/conf/httpd.conf, once opened you will have to locate the section on virtual hosts and you should see an example that is already commented out., I edited the files with nano in the console.

    1
    ### Section 3: Virtual Hosts

    Instead of telling you which lines to uncomment, I’m going to show you below, the stanzas to add to the Virtual Host section to get companyABC.com and companyDEF.com websites running:

    001
    #
    002
    # Virtual hosts
    003
    #
    004
     
    005
    # Virtual host Default Virtual Host
    006
    <VirtualHost *>
    007
    DocumentRoot /var/www/html/
    008
    ErrorLog logs/error_log
    009
    ServerAdmin root@localhost
    010
     
    011
     
    012
     
    013
    ServerSignature email
    014
    TransferLog logs/access_log
    015
    DirectoryIndex index.php index.html index.htm index.shtml
    016
     
    017
     
    018
    SSLEngine off
    019
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    020
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    021
     
    022
    SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
    023
     
    024
    SSLOptions
    025
    LogFormat "None"
    026
    TransferLog logs/access_log
    027
    ErrorLog logs/error_log
    028
    LogLevel debug
    029
    HostNameLookups off
    030
     
    031
     
    032
     
    033
     
    034
    </VirtualHost>
    035
     
    036
    # Virtual host resume.loc
    037
    <VirtualHost 127.0.0.1>
    038
    DocumentRoot /var/www/html/mdw/resume
    039
    ErrorLog logs/error_log
    040
    ServerAdmin root@localhost
    041
    ServerName resume.loc
    042
     
    043
     
    044
    ServerSignature email
    045
    TransferLog logs/access_log
    046
    DirectoryIndex index.html index.php index.shtml
    047
     
    048
    <Directory "/var/www/html/mdw/resume/">
    049
    Options all
    050
     
    051
    AllowOverride all
    052
     
    053
     
    054
     
    055
    </Directory>
    056
     
    057
     
    058
    SSLEngine off
    059
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    060
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    061
     
    062
    SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
    063
     
    064
    SSLOptions
    065
    LogFormat "None"
    066
    TransferLog logs/access_log
    067
    ErrorLog logs/error_log
    068
    LogLevel error
    069
    HostNameLookups on
    070
     
    071
     
    072
     
    073
     
    074
    </VirtualHost>
    075
     
    076
    # Virtual host linker
    077
    <VirtualHost 127.0.0.1>
    078
    DocumentRoot /var/www/html/mdw/linkerv2/
    079
    ErrorLog logs/error_log
    080
    ServerAdmin root@localhost
    081
    ServerName linker.loc
    082
     
    083
     
    084
    ServerSignature email
    085
    TransferLog logs/access_log
    086
    DirectoryIndex index.html index.php index.shtml
    087
     
    088
     
    089
    SSLEngine off
    090
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    091
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    092
     
    093
    SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
    094
     
    095
    SSLOptions
    096
    LogFormat "None"
    097
    TransferLog logs/access_log
    098
    ErrorLog logs/error_log
    099
    LogLevel error
    100
    HostNameLookups on
    101
     
    102
     
    103
     
    104
     
    105
    </VirtualHost>
    106
     
    107
    # Virtual host Virtual Host 1
    108
    <VirtualHost 127.0.0.1>
    109
    DocumentRoot /var/www/html/mdw/site
    110
    ErrorLog logs/error_log
    111
    ServerAdmin root@localhost
    112
    ServerName mdw.loc
    113
     
    114
     
    115
    ServerSignature email
    116
    TransferLog logs/access_log
    117
    DirectoryIndex index.html index.php index.shtml
    118
     
    119
     
    120
    SSLEngine off
    121
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    122
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    123
     
    124
    SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
    125
     
    126
    SSLOptions
    127
     
    128
    TransferLog logs/access_log
    129
    ErrorLog logs/error_log
    130
    LogLevel error
    131
    HostNameLookups on
    132
     
    133
     
    134
     
    135
     
    136
    </VirtualHost>
    137
     
    138
     

    After you have added the host(s), save the file. At this point, you will need to add the appropriate records to your DNS server to make these domains reachable by anyone on the network. If you have no access to a DNS server (BIND9), or you just want to test the configuration, just edit your /etc/hosts file. Here is what my file looks like:

    1
    # Do not remove the following line, or various programs
    2
    # that require network functionality will fail.
    3
    127.0.0.1               localhost.localdomain localhost
    4
    127.0.0.1               host1.loc
    5
    127.0.0.1               host2.loc
    6

    Once hosts is saved you just restart your server and everything should work without a problem

     
    • webscriptz 11:47 on 30/03/2011 Permalink | Reply

      This is if you have a server distribution installed on a laptop like I do for development purposes.

      Note that this works best with a server distribution because,if you take, for instance the Ubuntu desktop edition an make a webserver for development purposes you will have disable NetworkManager
      or each time you connect to a different network rewrite the /etc/hosts to be able to access your websites via the link specified by you.

      Fedora, RHEL and centOS use /etc/resolv.conf for the IP-address currently used by the PC where Ubuntu for instance use /etc/hosts and thus rewrites it as soon as you change from network.

    • webscriptz 23:09 on 30/03/2011 Permalink | Reply

      A friend pointed out that When in production you should patch the server, here’s a good article describing howto: http://mitka.us/articles/mpm-itk/

  • webscriptz 00:39 on 22/02/2010 Permalink | Reply
    Tags: annoyed, , , , , ,   

    Annoyed…with coding 

    I’ve been coding away all week, that is between my other jobs at home :P

    In all my ‘wisdom’ and persistence i made a small app with Yii which stores data in an array and serializes it into a db, and a basic CRUD, a proof of concept to see if the framework was capable of doing this and in the fastest way possible.

    No problem so far, getting it is simple, but apparently you Yii doesn’t permit everything. So you need a $temp variable to store the model data in, suffice to say that it isn’t really the shortest route to take nor in my opinion the fastest bus alas I have to do with it. This little app of not more then a 60 lines of code took me four days, four damn days to figure out the error,  honestly if we have methods to ‘save space’ in your coding why not permit them?

    I’m not going to bother everybody with my nagging so, I’ll stop here.

    For those who want to see the topic on the yii forums.

     
  • webscriptz 23:47 on 20/12/2009 Permalink | Reply
    Tags: , , , , , , , ,   

    YII framework configuration 

    I’m toying with the Yii Framework for some time now and even if i cost me a lot of anger and frustration in the beginning I’m starting to like it more and more, alas I do have to say that the documentation isn’t always that clear and for someone who begins or who’ll write some large applications the configuration file can be a hassle so here’s my solution:

    Brake down the configuration file in multiple files, this will give you some speed disadvantage and some will  saying that I’m raping Yii framework purpose for speed but at least to me it seems more clear

    This is the protected.config/main.php

    dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
    'name'=>'WEBSITENAME',
    'modules'=>array(
    'users'=>array(
    //sub modules in the module users
    'modules'=>array(
    'messaging',
    'profile',
    'dashboard',
    )
    ),
    'about',
    'forums',
    ),
    // preloading 'log' component active loading
    'preload'=>array('log'),
    
    // autoloading model and component classes lazy loading
    // I make the difference between CformModel and CActiveRecord
    'import'=>array(
    'application.models.*',
    'application.models.forms.*',
    'application.models.database.*',
    ),
    
    // application components
    'components'=>array(
    // enable cookie-based authentication
    'user'=>array('allowAutoLogin'=>true),
    
    // data relinquished to database.php
    // for easy access and usability as also for the future
    // installation procedure, it's less to write to a file
    'db'=>include(dirname(__FILE__).'/database.php'),
    
    // for a better overview we exculded url routes to a seperate file
    'urlManager'=>include(dirname(__FILE__).'/routes.php'),
    
    //authentication component needs data from db for CdbConnection
    'authManager'=>array(
    'class'=>'CDbAuthManager',
    'connectionID'=>'db',
    'defaultRoles'=>array('authenticated', 'guest'),
    ),
    
    //security measures
    'request'=>array(
    'enableCsrfValidation'=>true,
    'enableCookieValidation'=>true,
    ),
    ),
    
    // application-level parameters that can be accessed
    // using Yii::app()->params['paramName']
    // uncomment the following if you want static params in the application
    //'params'=>array(include(dirname(__FILE__).'/params.php'))
    );

    database.php

    'CDbConnection',
    'connectionString'=>'mysql:host=localhost;dbname=mysql',
    //'connectionString'=>'pgsql:host=localhost;port=5432;dbname=mysql',
    'username' => 'root',
    'password' => '',
    );
    ?>
    

    routes.php

    'path', // path or get
    'urlSuffix' => '', //.html .whateverextentionyouwant
    'showScriptName' => true,
    'rules'=>array(
    'users/recovery/perimeterSecurity/'=>'users/recovery/perimeterSecurity',
    ),
    );
    ?>
    

    param.php

    //nothing in it at the moment

     
    • Cherry 10:58 on 30/12/2009 Permalink | Reply

      Hi,I’m trying Yii now.Almost everything could be done with Yii.But all the components,those how I configure ,will run.Something ,like,DB session…
      well,my english is so poor!

    • webscriptz 03:32 on 01/01/2010 Permalink | Reply

      I’m a bit torn between speed and programming luxury and because sometimes Yii is poorly documented, nice example code but not all the options are given actually sometimes very few.

      I’m currently doing models and testing them in Yii and i can’t get my head really around it, Codeigniter was really easy to use in the model logic but now what’s the logic, Model driven or controller driven because of the AR layer and the model sql query which seems implemented in the controllers. I thought controllers were just a gateway between view and model because it’s the model that usually contains all the logic not the controller.

  • webscriptz 20:45 on 30/06/2009 Permalink | Reply
    Tags: CI function, codeigniter, , redirect   

    Codeigniter Redirect 

    redirect()

    Does a “header redirect” to the local URI specified. Just like other functions in this helper, this one is designed to redirect to a local URL within your site. You will not specify the full site URL, but rather simply the URI segments to the controller you want to direct to. The function will build the URL based on your config file values.

    The optional second parameter allows you to choose between the “location” method (default) or the “refresh” method. Location is faster, but on Windows servers it can sometimes be a problem. The optional third parameter allows you to send a specific HTTP Response Code – this could be used for example to create 301 redirects for search engine purposes. The default Response Code is 302. The third parameter is only available with ‘location’ redirects, and not ‘refresh’. Examples:

    if ($logged_in == FALSE)
    {
    redirect('/login/form/', 'refresh');
    }

    // with 301 redirect
    redirect('/article/13', 'location', 301);

    This was the excerpt from the codeigniter userguide but what they don’t really tell is the essential:

    redirect(‘controller/function/param’, ‘refresh’);

     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel