use following code
query_posts(array(‘orderby’ => ‘rand’));
if (have_posts()) : while (have_posts()) : the_post();
use following code
query_posts(array(‘orderby’ => ‘rand’));
if (have_posts()) : while (have_posts()) : the_post();
reference: http://codex.wordpress.org/Function_Reference/query_posts
query_posts() can be used to control which posts show up in The Loop. It accepts a variety of parameters in the same format as used in your URL (e.g. p=4 to show only post of ID number 4).
Why go through all the trouble of changing the query that was meticulously created from your given URL? You can customize the presentation of your blog entries by combining it with page logic (like the Conditional Tags) — all without changing any of the URLs.
Common uses might be to:
The query_posts function is intended to be used to modify the main page Loop only. It is not intended as a means to create secondary Loops on the page. If you want to create separate Loops outside of the main one, you should use get_posts() instead. Use of query_posts on Loops other than the main one can result in your main Loop becoming incorrect and possibly displaying things that you were not expecting.
The query_posts function overrides and replaces the main query for the page. To save your sanity, do not use it for any other purpose.
<?php
//The Query
query_posts('posts_per_page=5');
//The Loop
if ( have_posts() )Â : while ( have_posts() )Â : the_post();
..
endwhile; else:
..
endif;
//Reset Query
wp_reset_query();
?>
Place a call to query_posts() in one of your Template files before The Loop begins. The wp_query object will generate a new SQL query using your parameters. When you do this, WordPress ignores the other parameters it receives via the URL (such as page number or category). If you want to preserve that information, you can use the $query_string global variable in the call to query_posts().
For example, to set the display order of the posts without affecting the rest of the query string, you could place the following before The Loop:
global $query_string; query_posts($query_string . "&order=ASC");
When using query_posts in this way, the quoted portion of the argument must begin with an ampersand (&).
This is not an exhaustive list yet. It is meant to show some of the more common things possible with setting your own queries.
Show posts only belonging to certain categories.
Show One Category by ID
Display posts from only one category ID (and any children of that category):
query_posts('cat=4');
Show One Category by Name
Display posts from only one category by name:
query_posts('category_name=Staff Home');
Show Several Categories by ID
Display posts from several specific category IDs:
query_posts('cat=2,6,17,38');
Exclude Posts Belonging to Only One Category
Show all posts except those from a category by prefixing its ID with a ‘-’ (minus) sign.
query_posts('cat=-3');
This excludes any post that belongs to category 3.
Multiple Category Handling
Display posts that are in multiple categories. This shows posts that are in both categories 2 and 6:
query_posts(array('category__and' => array(2,6)));
To display posts from either category 2 OR 6, you could use cat as mentioned above, or by using category__in (note this does not show posts from any children of these categories):
query_posts(array('category__in' => array(2,6)));
You can also exclude multiple categories this way:
query_posts(array('category__not_in' => array(2,6)));
Show posts associated with certain tags.
Fetch posts for one tag
query_posts('tag=cooking');
This must use the tag slugs. E.g. query_posts(‘tag=dinner-recipe’); for the tag “dinner recipe”
Fetch posts that have either of these tags
query_posts('tag=bread,baking');
Fetch posts that have all three of these tags:
query_posts('tag=bread+baking+recipe');
Multiple Tag Handling
Display posts that are tagged with both tag id 37 and tag id 47:
query_posts(array('tag__and' => array(37,47)));
To display posts from either tag id 37 or 47, you could use tag as mentioned above, or explicitly specify by using tag__in:
query_posts(array('tag__in' => array(37,47)));
Display posts that do not have any of the two tag ids 37 and 47:
query_posts(array('tag__not_in' => array(37,47)));
The tag_slug__in and tag_slug__and behave much the same, except match against the tag’s slug.
Also see Ryan’s discussion of Tag intersections and unions.
You can also restrict the posts by author.
Note: author_name operates on the user_nicename field, whilst author operates on the author id field.
Display all Pages for author=1, in title order, with no sticky posts tacked to the top:
query_posts('caller_get_posts=1&author=1&post_type=page&post_status=publish&orderby=title&order=ASC');
Retrieve a single post or page.
To return both posts and custom post type movie
query_posts( array( 'post_type' => array('post', 'movie') ) );
Sticky posts first became available with WordPress Version 2.7. Posts that are set as Sticky will be displayed before other posts in a query, unless excluded with the caller_get_posts=1 parameter.
To return just the first sticky post:
$sticky=get_option('sticky_posts')Â ;
query_posts('p=' . $sticky[0]);
or
$args = array(
'posts_per_page' => 1,
'post__in' => get_option('sticky_posts'),
'caller_get_posts' => 1
);
query_posts($args);
Note: the second method returns only the more recent sticky post; if there are not sticky posts, it returns the last post published.
To return just the first sticky post or nothing:
$sticky = get_option('sticky_posts');
$args = array(
'posts_per_page' => 1,
'post__in' => $sticky,
'caller_get_posts' => 1
);
query_posts($args);
if($sticky[0]) {
// insert here your stuff...
}
To exclude all sticky posts from the query:
query_posts(array("post__not_in" =>get_option("sticky_posts")));
Return ALL posts with the category, but don’t show sticky posts at the top. The ‘sticky posts’ will still show in their natural position (e.g. by date):
query_posts('caller_get_posts=1&posts_per_page=3&cat=6');
Return posts with the category, but exclude sticky posts completely, and adhere to paging rules:
<?php
$paged = (get_query_var('paged'))Â ? get_query_var('paged')Â : 1;
$sticky=get_option('sticky_posts');
$args=array(
'cat'=>3,
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'paged'=>$paged,
);
query_posts($args);
?>
Retrieve posts belonging to a certain time period.
Returns posts for just the current date:
$today = getdate();
query_posts('year=' .$today["year"] .'&monthnum=' .$today["mon"] .'&day=' .$today["mday"] );
Returns posts for just the current week:
$week = date('W');
$year = date('Y');
query_posts('year=' . $year .'&w=' .$week );
Returns posts dated December 20:
query_posts( 'monthnum=12&day=20' );
Note: The queries above return posts for a specific date period in history, i.e. “Posts from X year, X month, X day”. They are unable to fetch posts from a timespan relative to the present, so queries like “Posts from the last 30 days” or “Posts from the last year” are not possible with a basic query, and require use of the posts_where filter to be completed. The examples below use the posts_where filter, and should be modifyable for most time-relative queries.
Return posts for posts for March 1 to March 15, 2009:
<?php
//Create a new filtering function that will add our where clause to the query
function filter_where($where = '') {
//posts for March 1 to March 15, 2009
$where .= " AND post_date >= '2009-03-01' AND post_date < '2009-03-16'";
return $where;
}
// Register the filtering function
add_filter('posts_where', 'filter_where');
// Perform the query, the filter will be applied automatically
query_posts($query_string);
?>
Return posts from the last 30 days:
<?php
//Create a new filtering function that will add our where clause to the query
function filter_where($where = '') {
//posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
// Register the filtering function
add_filter('posts_where', 'filter_where');
// Perform the query, the filter will be applied automatically
query_posts($query_string);
?>
Return posts 30 to 60 days old
<?php
//Create a new filtering function that will add our where clause to the query
function filter_where($where = '') {
//posts 30 to 60 days old
$where .= " AND post_date >= '" . date('Y-m-d', strtotime('-60 days')) . "'" . " AND post_date <= '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
// Register the filtering function
add_filter('posts_where', 'filter_where');
// Perform the query, the filter will be applied automatically
query_posts($query_string);
?>
You can displace or pass over one or more initial posts which would normally be collected by your query through the use of the offset parameter.
The following will display the 5 posts which follow the most recent (1):
query_posts('posts_per_page=5&offset=1');
Sort retrieved posts by this field.
Designates the ascending or descending order of the ORDERBY parameter.
Retrieve posts (or Pages) based on a custom field key or value.
Returns posts with custom fields matching both a key of ‘color’ AND a value of ‘blue’:
query_posts('meta_key=color&meta_value=blue');
Returns posts with a custom field key of ‘color’, regardless of the custom field value:
query_posts('meta_key=color');
Returns posts where the custom field value is ‘color’, regardless of the custom field key:
query_posts('meta_value=color');
Returns any Page where the custom field value is ‘green’, regardless of the custom field key:
query_posts('post_type=page&meta_value=green');
Returns both posts and Pages with a custom field key of ‘color’ where the custom field value IS NOT EQUAL TO ‘blue’:
query_posts('post_type=any&meta_key=color&meta_compare=!=&meta_value=blue');
Returns posts with custom field key of ‘miles’ with a custom field value that is LESS THAN OR EQUAL TO 22. Note the value 99 will be considered greater than 100 as the data is stored as strings, not numbers.
query_posts('meta_key=miles&meta_compare=<=&meta_value=22');
You may have noticed from some of the examples above that you combine parameters with an ampersand (&), like so:
query_posts('cat=3&year=2004');
Posts for category 13, for the current month on the main page:
if (is_home()) {
query_posts($query_string . '&cat=13&monthnum=' . date('n',current_time('timestamp')));
}
At 2.3 this combination will return posts belong to both Category 1 AND 3, showing just two (2) posts, in descending order by the title:
query_posts(array('category__and'=>array(1,3),'posts_per_page'=>2,'orderby'=>title,'order'=>DESC));
In 2.3 and 2.5 one would expect the following to return all posts that belong to category 1 and is tagged “apples”
query_posts('cat=1&tag=apples');
A bug prevents this from happening. See Ticket #5433. A workaround is to search for several tags using +
query_posts('cat=1&tag=apples+apples');
This will yield the expected results of the previous query. Note that using ‘cat=1&tag=apples+oranges’ yields expected results.
Placing this code in your index.php file will cause your home page to display posts from all categories except category ID 3.
<?php
if (is_home()) {
query_posts("cat=-3");
}
?>
You can also add some more categories to the exclude-list (tested with WP 2.1.2):
<?php
if (is_home()) {
query_posts("cat=-1,-2,-3");
}
?>
To retrieve a particular post, you could use the following:
<?php
// retrieve one post with an ID of 5
query_posts('p=5');
?>
If you want to use the Read More functionality with this query, you will need to set the global $more variable to 0.
<?php
// retrieve one post with an ID of 5
query_posts('p=5');
global $more;
// set $more to 0 in order to only get the first part of the post
$more = 0;
// the Loop
while (have_posts())Â : the_post();
// the content of the post
the_content('Read the full post »');
endwhile;
?>
To retrieve a particular page, you could use the following:
<?php
query_posts('page_id=7'); //retrieves page 7 only
?>
or
<?php
query_posts('pagename=about'); //retrieves the about page only
?>
For child pages, the slug of the parent and the child is required, separated by a slash. For example:
<?php
query_posts('pagename=parent/child'); // retrieve the child page of a parent
?>
You can pass a variable to the query with two methods, depending on your needs. As with other examples, place these above your Loop:
In this example, we concatenate the query before running it. First assign the variable, then concatenate and then run it. Here we’re pulling in a category variable from elsewhere.
<?php $categoryvariable=$cat; // assign the variable as current category $query= 'cat=' . $categoryvariable. '&orderby=date&order=ASC'; // concatenate the query query_posts($query); // run the query ?>
In this next example, the double quotes tell PHP to treat the enclosed as an expression. For this example, we are getting the current month and the current year, and telling query_posts to bring us the posts for the current month/year, and in this case, listing in ascending order so we get the oldest post at the top of the page.
<?php
$current_month = date('m');
$current_year = date('Y');
query_posts("cat=22&year=$current_year&monthnum=$current_month&order=ASC");
?>
<!-- put your loop here -->
This example explains how to generate a complete list of posts, dealing with pagination. We can use the default $query_string telling query_posts to bring us a full posts listing. We can also modify the posts_per_page query argument from -1 to the number of posts you want to show on each page; in this last case, you’ll probably want to use posts_nav_link() to navigate the generated archive.
<?php
query_posts($query_string.'&posts_per_page=-1');
while(have_posts()) { the_post();
<!-- put your loop here -->
}
?>
If you don’t need to use the $query_string variable, another method exists that is more clear and readable, in some more complex cases. This method puts the parameters into an array. The same query as in Example 2 above could be done like this:
query_posts(array( 'cat' => 22, 'year' => $current_year, 'monthnum' => $current_month, 'order' => 'ASC', ));
As you can see, with this approach, every variable can be put on its own line, for easier reading.
By default running query_posts will completely overwrite all existing query variables on the current page. Pagination, categories dates etc. will be lost and only the variables you pass into query_posts will be used.
If you want to preserve the original query you can merge the original query array into your parameter array:
global $wp_query;
query_posts(
array_merge(
array('cat' => 1),
$wp_query->query
)
);
The “Blog pages show at most” parameter in Settings > Reading can influence your results. To overcome this, add the ‘posts_per_page’ parameter. For example:
query_posts('category_name=The Category Name&posts_per_page=-1'); //returns ALL from the category
This information took from http://www.sitepoint.com/
PHP was released by Rasmus Lerdorf on June 8, 1995. His original usenet post is still available online if you want to examine a computing artefact from the dawn of the web. Many of us owe our careers to the language, so hereâs a brief history of PHPâŠ
PHP originally stood for âPersonal Home Pageâ and Rasmus started the project in 1994. PHP was written in C and was intended to replace several Perl scripts he was using on his homepage. Few people will be ancient enough to remember CGI programming in Perl, but it wasnât much fun. You could not embed code within HTML and development was slow and clunky.
Rasmus added his own Form Interpreter and other C libraries including database connectivity engines. PHP 2.0 was born on this day 15 years ago. PHP had a modest following until the launch of version 3.0 in June 1998. The parser was completely re-written by Andi Gutmans and Zeev Suraski; they also changed the name to the recursive âPHP: Hypertext Preprocessorâ.
Critics argue that PHP 3.0 was insecure, had a messy syntax, and didnât offer standard coding conventions such as object-orientated programming. Some will quote the same arguments today. However, while PHP lacked elegance it made web development significantly easier. Programming novices could add snippets of code to their HTML pages and experts could develop full web applications using an open source technology which became widely installed by web hosts.
PHP 4.0 was released on May 22, 2000. It provided rudimentary object-orientation and addressed several security issues such as disabling register_globals. Scripts broke, but it was relatively easy to adapt applications for the new platform. PHP 4.0 was an instant success and youâll still find it offered by web hosts today. Popular systems such as WordPress and Drupal still run on PHP 4.0 even though platform development has ceased.
Finally, we come to PHP 5.0 which was released on July 13, 2004. The language featured more robust object-orientated programming plus security and performance enhancements. The uptake has been more sedate owing to the success of PHP 4.0 and the introduction of competing frameworks such as ASP.NET, Ruby and Python.
PHP has its inconsistencies and syntactical messiness, but itâs rare youâll encounter a language which can be installed on almost any OS, is provided by the majority of web hosts, and offers a similar level of productivity and community assistance. Whatever your opinion of the language, PHP has provided a solid foundation for server-side programming and web application development for the past 15 years. Long may it continue.
Thanks & Regards
Manoj Ninave
Partial Classes in PHP
One of my favorite features of C# is Partial Classes. For the uninitiated, it is a way of defining a class in two separate locations. Very useful when you have code generation utilities such as LINQ.
Unfortunately, PHP has no such feature (though if anyoneâs listening it would be a great feature to add to the PHP6 feature list), however thanks to the magic of __call($method, $args), __get($key), and __set($key, $value) overload functions as well as passing by reference (aah the good olâ &) we can imitate partial classes.
The idea behind this partial class hack is to instance a copy of the partial class in question and have our magic functions forward any undefined requests to the partial class.
The partial class (probably with the naming convention Partial_CLASSNAME) will contain a reference to the main class and also have magic functions forwarding undefined requests to the main class. The reason why we have our magic functions in the partial class is so that any internal references can still be made (methods in Partial_CLASSNAME must have access to the methods and members in CLASSNAME).
The constructor in the main class will automatically seek out the partial class (and additional coding can be done to seek out more than 1 partial class as well as do some integrity checking) so that the programmer does not have to intervene to form the âfull classâ.
Hereâs some sample code:
class MainClass
{
private $_partial;
public $a = ‘a’;
public function __construct()
{
if( class_exists(“Partial_” . __CLASS__) )
{
$partial = “Partial_” . __CLASS__;
$this->_partial = new $partial($this);
}
}
public function __call($method, $args)
{
return call_user_func_array( array($this->_partial, $method), $args );
}
public function __get($key)
{
return $this->_partial->$key;
}
public function __set($key, $value)
{
$this->_partial->$key = $value;
}
}
class Partial_MainClass
{
private $_parent;
public $b = ‘b’;
public function __construct(&$parent)
{
$this->_parent = $parent;
}
public function foo()
{
$this->a = ‘c’;
return ‘foo called’;
}
public function __call($method, $args)
{
if( function_exists( array($this->_parent, $method) ) )
return call_user_func_array( array($this->_parent, $method), $args );
else
trigger_error(“Call to undefined method ” . get_class($this->_parent) . “::” . $method, E_USER_ERROR);
}
public function __get( $key )
{
if( isset($this->_parent->$key) )
return $this->_parent->$key;
}
public function __set( $key, $value )
{
if( isset($this->_parent->$key) )
$this->_parent->$key = $value;
}
}
$tmp = new MainClass();
echo “$tmp->a: ” . $tmp->a . “”;
echo “$tmp->b: ” . $tmp->b . “”;
echo “$tmp->foo(): ” . $tmp->foo() . “”;
echo “$tmp->a: ” . $tmp->a . “”;
echo “$tmp->b: ” . $tmp->b . “”;
And the output is going to look something like:
$tmp->a: a
$tmp->b: b
$tmp->foo(): foo called
$tmp->a: c
$tmp->b: b
Performing a var_dump() on $tmp gives us:
object(MainClass)[1]
protected ‘_partial’ =>
object(Partial_MainClass)[2]
protected ‘_parent’ =>
&object(MainClass)[1]
public ‘b’ => string ‘b’ (length=1)
public ‘a’ => string ‘c’ (length=1)
If you call a function that doesnât exist in either class, the trigger_error() in the Partial_MainClass will throw an error message. This is, of course, to prevent having an infinite loop of having each class call each other to find the non-existant function.
The big limitation is accessing private and protected members and methods, however with a small amount of time, the PHP5 Reflection API should replace the call_user_func_array() and provide access to the private and protected members and methods.
Ignoring the limitations, the sample code above achieves what it sets out to accomplish: combines two classes so that the rest of the code sees it as a unified object.
Reference/ original post : http://www.toosweettobesour.com/2008/05/01/partial-classes-in-php
by Kevin Waterson from http://www.phpro.org/tutorials/Model-View-Controller-MVC.html
Abstract
Model View Controller.
This tutorial will take you from the beginning to the end of building a MVC framework. The object is not soley to produce the finished MVC framework, although that will happen, but to demonstrate how MVC works and some of the concepts that lay behind it..
What is MVC?
MVC is a design pattern. A Design pattern is a code structure that allows for common coding frameworks to be replicated quickly. You might think of a design pattern as a skeleton or framework on which your application will be built.
In the MVC framework that is created in this tutorial, several key points will be raised. The first is the frameworks needs a single point of entry, ie: index.php. This is where all access to the site must be controlled from. To ensure that a single point of entry is maintained, htaccess can be utilized to ensure no other file may be accessed, and that we hide the index.php file in the url. Thus creating SEO and user friendly URL’s.
It is beyond the scope of this tutorial to show how to set up htaccess and mod_rewrite and more information on these can be gained from the Apache manual. The .htaccess file itself looks like this.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rt=$1 [L,QSA]
The .htaccess file will permit access to the site via urls such as
http://www.example.com/news/show
If you do not have mod_rewrite available, the entry to the site will be the same, except that the URL will contain the values needed such as:
http://www.example.com/index.php?rt=news/show
The Site Structure
In this tutorial several directories are required to hold the various components that make up the MVC framework. The index.php and the .htaccess files will, of course, reside at the top level. We will need a directory to hold the application code, and directories for the model view and controllers. The site structure should look like this:
html
application
controller
includes
model
views
.htaccess
index.php
The Index File
As previously mentioned, the index.php file is our single point of access. As such, it provides the ideal space for declaring variables and site wide configurations. It is in this file that we will also call a helper file to initialize a few values. This file will be called init.php and it will be placed in includes directory as shown in the direcory structure. The index file therefore, will begin like this:
/*** error reporting on ***/
error_reporting(E_ALL);
/*** define the site path constant ***/
$site_path = realpath(dirname(__FILE__));
define (‘__SITE_PATH’, $site_path);
/*** include the init.php file ***/
include ‘includes/init.php’;
?>
The index.php file so far only sets the error reporting, includes the init file, and defines the site path constant. With this file in place, and the .htaccess file we can begin to build the registry. In this MVC framework, the registry object is passed to other objects and contains site wide variables without the the use globals. To create a new registry object, we use the init.php file in the includes directory.
Of course, to create new object we need to include the registry class definition file. During the building of the MVC framework we will be including the application class files directly. Any PHP class definition files which are used by the model will be autoloaded as they can become quite cumbersome with larger applications. To alleviate some of this PHP has the __autoload function to help us out. After the application includes, the __autoload function will immediately follow to load class definition files automatically when they are required by the system. That is, when the new keyword is used. The class definitions will be stored in a directory called model. The includes/init.php file should now look like this.
/*** include the controller class ***/
include __SITE_PATH . ‘/application/’ . ‘controller_base.class.php’;
/*** include the registry class ***/
include __SITE_PATH . ‘/application/’ . ‘registry.class.php’;
/*** include the router class ***/
include __SITE_PATH . ‘/application/’ . ‘router.class.php’;
/*** include the template class ***/
include __SITE_PATH . ‘/application/’ . ‘template.class.php’;
/*** auto load model classes ***/
function __autoload($class_name) {
$filename = strtolower($class_name) . ‘.class.php’;
$file = __SITE_PATH . ‘/model/’ . $filename;
if (file_exists($file) == false)
{
return false;
}
include ($file);
}
/*** a new registry object ***/
$registry = new registry;
?>
Here is should be noted that the autoload function uses a naming convention for the class definition files to be included. They must all follow the convention of ending in .class.php and the class name must be that of the .class.php file name. So that to create a new “news” object the class definition file name must be news.class.php and the class must be named “news”. With these files in place we are well on the way, however our MVC does not do anything yet. In fact, if you tried to access the index.php file now, you would get many errors about missing files. Mostly from the files in the application directory. So, lets begin by creating those files each can be blank or simply contain
?>
The files to create in the application directory are:
* controller_base.class.php
* registry.class.php
* router.class.php
* template.class.php
Note that although these files are not autoloaded, we have still maintained the same naming convention by calling the files .class.php
The Registry
The registry is an object where site wide variables can be stored without the use of globals. By passing the registry object to the controllers that need them, we avoid pollution of the global namespace and render our variables safe. We need to be able to set registry variables and to get them. The php magic functions __set() and __get() are ideal for this purpose. So, open up the registry.class.php in the applications directory and put the following code in it:
Class Registry {
/*
* @the vars array
* @access private
*/
private $vars = array();
/**
*
* @set undefined vars
*
* @param string $index
*
* @param mixed $value
*
* @return void
*
*/
public function __set($index, $value)
{
$this->vars[$index] = $value;
}
/**
*
* @get variables
*
* @param mixed $index
*
* @return mixed
*
*/
public function __get($index)
{
return $this->vars[$index];
}
}
?>
With the registry in place, our system is working. It does not do anything or display anything, but we have a functional system. The __set() and __get() magic function now allow us to set variables within the registry and store them there. Now to add the Model and router classes.
The Model
The Model is the “M” in MVC. The model is where business logic is stored. Business logic is loosely defined as database connections or connections to data sources, and provides the data to the controller. As I am a fan of CAV (Controller Action View) we will blur the line between the Model and Controller. This is not strictly how MVC should work, but this is PHP baby. Our database connection is a simple singleton design pattern and resides in the classes directory and can be called statically from the controller and set in the registry. Add this code to the init.php file we created earlier.
/*** create the database registry object ***/
$registry->db = db::getInstance();
?>
Like all registry members, the database is now globally availabe to our scripts. As the class is a singleton we always get the same instance back. Now that registry objects can be created a method of controlling what is loaded is needed.
The Router
The router class is responsible for loading up the correct controller. It does nothing else. The value of the controller comes from the URL. The url will look a like this:
http://www.example.com/index.php?rt=news
or if you have htaccess amd mod_rewrite working like this:
http://www.example.com/news
As you can see, the route is the rt variable with the value of news. To begin the router class a few things need to be set. Now add this code to the router.class.php file in the application directory.
class router {
/*
* @the registry
*/
private $registry;
/*
* @the controller path
*/
private $path;
private $args = array();
public $file;
public $controller;
public $action;
function __construct($registry) {
$this->registry = $registry;
}
So it does not look like much yet but is enough to get us started. We can load the router into the registry also. Add this code to the index.php file.
/*** load the router ***/
$registry->router = new router($registry);
Now that the router class can be loaded, we can continue with the router class by adding a method to set the controller directory path. Add this block of code to the router.class.php file.
/**
*
* @set controller directory path
*
* @param string $path
*
* @return void
*
*/
function setPath($path) {
/*** check if path i sa directory ***/
if (is_dir($path) == false)
{
throw new Exception (‘Invalid controller path: `’ . $path . ‘`’);
}
/*** set the path ***/
$this->path = $path;
}
And to set the controller path in the registry is a simple matter of adding this line to the index.php file
/*** set the path to the controllers directory ***/
$router->setPath (__SITE_PATH . ‘controller’);
With the controller path set we can load the controller. We will create a method to called loader() to get the controller and load it. This method will call a getController() method that will decide which controller to load. If a controller is not found then it will default back to the index. The loader method looks like this.
/**
*
* @load the controller
*
* @access public
*
* @return void
*
*/
public function loader()
{
/*** check the route ***/
$this->getController();
/*** if the file is not there diaf ***/
if (is_readable($this->file) == false)
{
echo $this->file;
die (’404 Not Found’);
}
/*** include the controller ***/
include $this->file;
/*** a new controller class instance ***/
$class = $this->controller . ‘Controller_’;
$controller = new $class($this->registry);
/*** check if the action is callable ***/
if (is_callable(array($controller, $this->action)) == false)
{
$action = ‘index’;
}
else
{
$action = $this->action;
}
/*** run the action ***/
$controller->$action();
}
The getController method that the loader() method calls does the work. By taking the route variables from the url via $_GET['rt'] it is able to check if a contoller was loaded, and if not default to index. It also checks if an action was loaded. An action is a method within the specified controller. If no action has been declared, it defaults to index. Add the getController method to the router.class.php file.
/**
*
* @get the controller
*
* @access private
*
* @return void
*
*/
private function getController() {
/*** get the route from the url ***/
$route = (empty($_GET['rt'])) ? ” : $_GET['rt'];
if (empty($route))
{
$route = ‘index’;
}
else
{
/*** get the parts of the route ***/
$parts = explode(‘/’, $route);
$this->controller = $parts[0];
if(isset( $parts[1]))
{
$this->action = $parts[1];
}
}
if (empty($this->controller))
{
$this->controller = ‘index’;
}
/*** Get action ***/
if (empty($this->action))
{
$this->action = ‘index’;
}
/*** set the file path ***/
$this->file = $this->path .’/’. $this->controller . ‘.php’;
}
?>
The Controller
The Contoller is the C in MVC. The base controller is a simple abstract class that defines the structure of all controllers. By including the registry here, the registry is available to all class that extend from the base controller. An index() method has also been included in the base controller which means all controller classes that extend from it must have an index() method themselves. Add this code to the controller.class.php file in the application directory.
Abstract Class baseController {
/*
* @registry object
*/
protected $registry;
function __construct($registry) {
$this->registry = $registry;
}
/**
* @all controllers must contain an index method
*/
abstract function index();
}
?>
Whilst we are in the controller creating mood, we can create an index controller and a blog controller. The index controller is the sytem default and it is from here that the first page is loaded. The blog controller is for an imaginary blog module. When the blog module is specified in the URL
http://www.example.com/blog
then the index method in the blog controller is called. A view method will also be created in the blog controller and when specified in the URL
http://www.example.com/blog/view
then the view method in the blog controller will be loaded. First lets see the index controller. This will reside in the controller directory.
class indexController extends baseController {
public function index() {
/*** set a template variable ***/
$this->registry->template->welcome = ‘Welcome to PHPRO MVC’;
/*** load the index template ***/
$this->registry->template->show(‘index’);
}
}
?>
The indexController class above shows that the indexController extends the baseController class, thereby making the registry available to it without the need for global variables. The indexController class also contains the mandatory index() method that ll controllers must have. Within itn index() method a variable named “welcome” is set in the registry. This variable is available to the template when it is loaded via the template->show() method.
The blogController class follows the same format but has has one small addition, a view() method. The view() method is an example of how a method other than the index() method may be called. The view method is loaded via the URL
http://www.example.com/blog/view
Class blogController Extends baseController {
public function index() {
$this->registry->template->blog_heading = ‘This is the blog Index’;
$this->registry->template->show(‘blog_index’);
}
public function view(){
/*** should not have to call this here…. FIX ME ***/
$this->registry->template->blog_heading = ‘This is the blog heading’;
$this->registry->template->blog_content = ‘This is the blog content’;
$this->registry->template->show(‘blog_view’);
}
}
?>
The View
The View, as you might have guessed, is the V in MVC. The View contains code that relates to presentation and presentation logic such as templating and caching. In the controller above we saw the show() method. This is the method that calls the view. The major component in the PHPRO MVC is the template class. The template.class.php file contains the class definition. Like the other classes, it has the registry available to it and also contains a __set() method in which template variables may be set and stored.
The show method is the engine room of the view. This is the method that loads up the template itself, and makes the template variables available. Some larger MVC’s will implement a template language that adds a further layer of abstraction from PHP. Added layers mean added overhead. Here we stick with the speed of PHP within the template, yet all the logic stays outside. This makes it easy for HTML monkies to create websites without any need to learn PHP or a template language. The template.class.php file looks like this:
Class Template {
/*
* @the registry
* @access private
*/
private $registry;
/*
* @Variables array
* @access private
*/
private $vars = array();
/**
*
* @constructor
*
* @access public
*
* @return void
*
*/
function __construct($registry) {
$this->registry = $registry;
}
/**
*
* @set undefined vars
*
* @param string $index
*
* @param mixed $value
*
* @return void
*
*/
public function __set($index, $value)
{
$this->vars[$index] = $value;
}
function show($name) {
$path = __SITE_PATH . ‘/views’ . ‘/’ . $name . ‘.php’;
if (file_exists($path) == false)
{
throw new Exception(‘Template not found in ‘. $path);
return false;
}
// Load variables
foreach ($this->vars as $key => $value)
{
$$key = $value;
}
include ($path);
}
}
?>
Templates
The templates themselves are basically HTML files with a little PHP embedded. Do not let the separation Nazi’s try to tell you that you need to have full seperation of HTML and PHP. Remember, PHP is an embeddable scripting language. This is the sort of task it is designed for and makes an efficient templating language. The template files belong in the views directory. Here is the index.php file.
Well, that was pretty amazing.. Now for the blog_index.php file.
And finally the blog_view.php file..
In the above template files note that the variable names in the templates, match the template variables created in the controller.
Download Source
The full source code for this MVC Framework is available for download here.
http://www.phpro.org/downloads/mvc-0.0.4.tar.gz
Update
Due to the populariity of this tutorial and the framework, a small side project has been spawned that builds on this tutorial and adds some practical functionality. Users are recommended to get the basics in this tutorial and move on to the next level. See more at http://sevenkevins.com and see how simple and easy MVC and application development can be.
Conclusion
It is hoped that you have found some insight into how MVC works whilst reading this tutorial. The MVC Framework you have build here should be used as a guide only, although it is a fully functional implementation, it is left to the user to build on it and take it to new hights. If you are using this MVC in any way, or have corrections or improvements, simply contact us.
Credits
Thanks to Bill Hernandez of Plano, Texas for errata.
here code is to import images into magento databse without using any core files.
this is for product’s images. you can modify it for gallery images also.
here all the images took from media/import and copied to that perticular directory.
you can find here,how images created there directory structure.
if images name is example.gif,then will create directory structure like e/x/example.gif.
that is means this images will copy to media/catalog/product/e/x/example.gif
and the value /e/x/example.gif will insert into table catalog_product_entity_varchar.you can see this image at fronend to that perticular product.Actaully i did script to imaport product with catagory,attribute,images,description…. etc
it is nothing but a cron job.i took only import images part from my script.
$LargeProductImageURL=$LargeImageURL!=”"?basename($allData[$key]->LargeImageURL):”";
$first_2_letter = substr(“$LargeProductImageURL”, 0,2);
$first_letter = substr(“$first_2_letter”, 0,1);
$second_letter = substr(“$first_2_letter”, -1);
$product_image =”/”.$first_letter.”/”.$second_letter.”/”.$LargeProductImageURL;
$product_path=$media_path.”".$slash.”catalog\product”;
$import_images=$media_path.”".$slash.”import”.$slash.”".$LargeProductImageURL;
$mypath1=$product_path.”".$slash.”".$first_letter;
if(!is_dir($mypath1))
{
mkdir($mypath1,0777,TRUE);
}
$mypath2=$product_path.”".$slash.”".$first_letter.”".$slash.”".$second_letter;
if(!is_dir($mypath2))
{
mkdir($mypath2,0777,TRUE);
}
//copy ( string $source , string $dest [, resource $context ] )
$Image_dest=$mypath2.”".$slash.”".$LargeProductImageURL;
@copy($import_images,$Image_dest);
#####check Is images are ready for copy or not
if (file_exists($import_images)) {
$product_image = $product_image;
}
else {
$product_image=”no_selection”;
}
#######
$UrlKey = strtolower(str_replace(” “,”-”,$PName));
$URL_path= $PName.”.html”;
/*if(empty($LargeProductImageURL))
{$product_image=”no_selection”;}*/
$db_obj->query(“INSERT INTO catalog_product_entity_varchar(entity_type_id, attribute_id,store_id,entity_id,value) VALUES
(‘”.$catalog_product.”‘,’56′,’0′,’”.$entity_id.”‘,’”.$PName.”‘),
(‘”.$catalog_product.”‘,’82′,’0′,’”.$entity_id.”‘,’”.$UrlKey.”‘),
(‘”.$catalog_product.”‘,’469′,’0′,’”.$entity_id.”‘,’2′),
(‘”.$catalog_product.”‘,’67′,’0′,’”.$entity_id.”‘,’”.$PName.”‘),
(‘”.$catalog_product.”‘,’69′,’0′,’”.$entity_id.”‘,’”.$PName.”‘),
(‘”.$catalog_product.”‘,’70′,’0′,’”.$entity_id.”‘,’”.$product_image.”‘),
(‘”.$catalog_product.”‘,’71′,’0′,’”.$entity_id.”‘,’”.$product_image.”‘),
(‘”.$catalog_product.”‘,’72′,’0′,’”.$entity_id.”‘,’”.$product_image.”‘),
(‘”.$catalog_product.”‘,’86′,’0′,’”.$entity_id.”‘,”),
(‘”.$catalog_product.”‘,’90′,’0′,’”.$entity_id.”‘,”),
(‘”.$catalog_product.”‘,’92′,’0′,’”.$entity_id.”‘,’container2′),
(‘”.$catalog_product.”‘,’95′,’0′,’”.$entity_id.”‘,”),
(‘”.$catalog_product.”‘,’96′,’0′,’”.$entity_id.”‘,”),
(‘”.$catalog_product.”‘,’97′,’0′,’”.$entity_id.”‘,”),
(‘”.$catalog_product.”‘,’83′,’0′,’”.$entity_id.”‘,’”.$URL_path.”‘)”, $db_conect);
regard
Manoj Ninave
Data inserted in following tables while importing products.
1)adminnotification_inbox
2)catalogindex_eav
3)catalogindex_price
4)cataloginventory_stock_item
5)cataloginventory_stock_status
6)catalogsearch_fulltext
7)catalog_category_product
8)catalog_category_product_index
9)catalog_product_enabled_index
10)catalog_product_entity
11)catalog_product_entity_datetime
12)catalog_product_entity_decimal
13)catalog_product_entity_int
14)catalog_product_entity_media_gallery
15)catalog_product_entity_media_gallery_value
16)catalog_product_entity_text
17)catalog_product_entity_varchar
18)catalog_product_link
19)catalog_product_link_attribute_int
20)catalog_product_website
21)core_url_rewrite
Regard
Manoj Ninave
Software Engineer,
COG IT Solutions Pvt. Ltd.
www.cogitsolutions.com
n.manoj@cogitsolutions.com
if you are not managing stock, cross-sells will not show.
edit the cross-sell products that are not showing up. Go to the inventory tab on the edit product page and change these options:
Manage Stock: Yes
– Qty: > 0
âIn Stock: Yes
you may want to change following setting also but not suggested if you want to manage stock on sale
in System > Configuration > Inventory
Decrease Stock When Order is Placed: No
Above settings will stop showing product in cross sell on check out when in stock status changes to out stock for cross sell product.
If you want to show product in cross sell even if it is out of stock without changing above settings you need to make a small change in coding as below
go to app\code\core\Mage\Checkout\Block\Cart and open Crosssell.php
search for Mage::getSingleton(‘cataloginventory/stock’)->addInStockFilterToCollection($collection);
comment this line
When html and php code mixing is required in php development, at that time writing html code as it is is faster than printing html code using echo or print function. Reason is PHP interprets and compiles each php code statement and ignore any thing writting outside php tag. Hence php echo for html is slower compared to direct writing php.
Question is how to separate php and html for readability in php development. Better solution is write down html code in separate file and include that file in php. This way readability will increase while PHP web development and also speed will be achived.
I faced problem to load some web page in Firefox and Crome browser
so i passed some code in .htaccess files.
code is given as follow:
php_value output_handler ob_gzhandler
simply copy and paste it to .htaccess file.
Also see that following lines are passed are not:
php_flag allow_call_time_pass_reference on
php_flag magic_quotes_runtime off
php_flag register_globals off
php_flag magic_quotes_gpc On
php_flag register_argc_argv on
php_value register_long_arrays on
php_value display_errors on
php_value allow_url_include on
to compress your files for faster loading
“php_value output_handler ob_gzhandler” is very useful.
Regard
Manoj Ninave
Software Engineer,
COG IT Solutions Pvt. Ltd.
www.cogitsolutions.com
n.manoj@cogitsolutions.com