Skip navigation

Tag Archives: php

opencart has built in seo friendly url but that’s for products only as far as i can tell. and you have to actually type out the terms. so i took it upon myself to make it friendlier and more automagic.

this is for opencart v1.4.8b

the format of url we are trying to achieve is:

/product/:product_id/:product_title

so it would look something like /product/1/girls-gone-wild

change catalog/model/tool/seo_url.php

UPDATED: includes all urls now and added file for download (Catalog.rar (601))

  1. public function rewrite($link)
  2. {
  3. if ($this->config->get(‘config_seo_url’))
  4. {
  5. $url_data = parse_url(str_replace(‘&’, ‘&’, $link));
  6.  
  7. $url = ;
  8.  
  9. $data = array();
  10.  
  11. parse_str($url_data[‘query’], $data);
  12.  
  13. switch($data[‘route’])
  14. {
  15. case ‘product/product’:
  16. $this->load->model(‘catalog/product’);
  17. $product = $this->model_catalog_product->getProduct($data[‘product_id’]);
  18. //get product categories
  19. $path = ;
  20. if(!isset($this->request->get[‘path’]) || empty($this->request->get[‘path’]))
  21. {
  22. $categories = $this->model_catalog_product->getCategories($product[‘product_id’]);
  23. if(!empty($categories))
  24. {
  25. $path = $this->model_catalog_product->getPath($categories[’0′][‘category_id’]);
  26. $path = substr($path,-1,1)==‘_’?substr($path,0,strlen($path)-1):$path;
  27. }
  28. }
  29. else
  30. {
  31. $path = $this->request->get[‘path’];
  32. }
  33. $url = $this->config->get(‘config_url’).‘product/’.$data[‘product_id’].‘/’.(!empty($path)?$path.‘/’:).$this->toSlug($product[‘name’]);
  34. break;
  35. case ‘product/category’:
  36. $this->load->model(‘catalog/category’);
  37. $this->load->model(‘catalog/product’);
  38. $categoryId = explode(‘_’,$data[‘path’]);
  39. $path = ;
  40. if(count($categoryId) == 1)
  41. {
  42. $path = $this->model_catalog_product->getPathUp($categoryId[’0′]);
  43. $path = substr($path,-1,1)==‘_’?substr($path,0,strlen($path)-1):$path;
  44. }
  45.  
  46. $categoryId = $categoryId[(count($categoryId)-1)];
  47. $category = $this->model_catalog_category->getCategory($categoryId);
  48. $url = $this->config->get(‘config_url’).‘category/’.($path?$path:$data[‘path’]).‘/’.$this->toSlug($category[‘name’]);
  49. break;
  50. case ‘information/information’:
  51. $this->load->model(‘catalog/information’);
  52. $info = $this->model_catalog_information->getInformation($data[‘information_id’]);
  53. $url = $this->config->get(‘config_url’).‘information/’.$data[‘information_id’].‘/’.$this->toSlug($info[‘title’]);
  54. break;
  55. default:
  56. $route = explode(‘/’,$data[‘route’]);
  57. $url = $this->config->get(‘config_url’).$data[‘route’];
  58.  
  59. break;
  60. }
  61. if(!empty($url))
  62. {
  63.  
  64. unset($data[‘route’],$data[‘path’],$data[‘product_id’],$data[‘information_id’]);
  65. $query = ;
  66.  
  67. if ($data)
  68. {
  69. foreach ($data as $key => $value)
  70. {
  71. $query .= ‘&’ . $key . ‘=’ . $value;
  72. }
  73.  
  74. if ($query)
  75. {
  76. $query = ‘?’ . trim($query, ‘&’);
  77. }
  78. }
  79. return $url.$query;
  80. }
  81. return $link;
  82.  
  83. } else
  84. {
  85. return $link;
  86. }
  87. }
  88.  
  89. public function toSlug($name)
  90. {
  91. $name = str_replace("’", "", $name);
  92. $name = str_replace(‘"’, "", $name);
  93. $name = strtolower($name);
  94. $name = preg_replace("/&#?[a-z0-9]+;/i","",$name);
  95. $name = preg_replace(‘/[^a-zA-Z0-9-]/’, ‘-’, $name);
  96. $name = preg_replace(‘/-+/’, "-", $name);
  97. return $name;
  98. }

then change catalog/controller/common/seo_url.php

  1. public function index()
  2. {
  3. if (isset($this->request->get[‘_route_’]))
  4. {
  5. $parts = explode(‘/’, $this->request->get[‘_route_’]);
  6. $routes = array(‘category’,‘product’,‘information’,‘account’,‘common’,‘checkout’);
  7.  
  8. if(in_array($parts[0], $routes))
  9. {
  10. switch($parts[0])
  11. {
  12. case ‘category’:
  13. $this->request->get[‘path’] = $parts[1];
  14. break;
  15. case ‘product’:
  16. $this->request->get[‘product_id’] = $parts[1];
  17. $this->request->get[‘path’] = $parts[2];
  18. break;
  19. case ‘information’:
  20. $this->request->get[‘information_id’] = $parts[1];
  21. break;
  22. default:
  23. $this->request->get[‘route’] = $this->request->get[‘_route_’];
  24. break;
  25. }
  26. }
  27. else
  28. {
  29. foreach ($parts as $part)
  30. {
  31. $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = ‘" . $this->db->escape($part) . "’");
  32.  
  33. if ($query->num_rows)
  34. {
  35. $url = explode(‘=’, $query->row[‘query’]);
  36.  
  37. if ($url[0] == ‘product_id’)
  38. {
  39. $this->request->get[‘product_id’] = $url[1];
  40. }
  41.  
  42. if ($url[0] == ‘category_id’)
  43. {
  44. if (!isset($this->request->get[‘path’]))
  45. {
  46. $this->request->get[‘path’] = $url[1];
  47. } else
  48. {
  49. $this->request->get[‘path’] .= ‘_’ . $url[1];
  50. }
  51. }
  52.  
  53. if ($url[0] == ‘manufacturer_id’)
  54. {
  55. $this->request->get[‘manufacturer_id’] = $url[1];
  56. }
  57.  
  58. if ($url[0] == ‘information_id’)
  59. {
  60. $this->request->get[‘information_id’] = $url[1];
  61. }
  62. } else
  63. {
  64. $this->request->get[‘route’] = ‘error/not_found’;
  65. }
  66. }
  67. }
  68.  
  69. if (isset($this->request->get[‘product_id’]))
  70. {
  71. $this->request->get[‘route’] = ‘product/product’;
  72. } elseif (isset($this->request->get[‘path’]))
  73. {
  74. $this->request->get[‘route’] = ‘product/category’;
  75. } elseif (isset($this->request->get[‘manufacturer_id’]))
  76. {
  77. $this->request->get[‘route’] = ‘product/manufacturer’;
  78. } elseif (isset($this->request->get[‘information_id’]))
  79. {
  80. $this->request->get[‘route’] = ‘information/information’;
  81. }
  82.  
  83. if (isset($this->request->get[‘route’]))
  84. {
  85. return $this->forward($this->request->get[‘route’]);
  86. }
  87. }
  88. }

If you need to sum up or average a column on a table via bindModel. this is what you are looking for.
The table looks like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//each report is connected to same session report via session_id

CREATE TABLE IF NOT EXISTS `gather_reports` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `session_id` varchar(64) NOT NULL DEFAULT '',
  `type` enum('Category','Store') NOT NULL DEFAULT 'Category',
  `name` varchar(128) NOT NULL DEFAULT '',
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `importedId` text NOT NULL,
  `total` int(11) NOT NULL DEFAULT '0',
  `imported` int(11) NOT NULL DEFAULT '0',
  `duration` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
)

in your controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$this->GatherReport->bindModel(
    array('hasOne'=>array(
	'GatherTotal'=>array(
        	'className'=>'GatherReport',
		'foreignKey'=>'id',
		'fields'=>'SUM(GatherTotal.total) as total'
	),
	'GatherImported'=>array(
		'className'=>'GatherReport',
		'foreignKey'=>'id',
		'fields'=>'SUM(GatherImported.imported) as imported'
	),
	'GatherTime'=>array(
		'className'=>'GatherReport',
		'foreignKey'=>'id',
		'fields'=>'SUM(GatherTime.duration) as duration'
	)
)),false);
$this->paginate['GatherReport']['group'] = 'GatherReport.session_id';
$data = $this->paginate('GatherReport');

So how do you combine your favorite blogging app with your favorite framework so that user can signin from your cakephp app and maintain his/her session in wordpress, assuming user can only sign up and log in from your cakephp site.

The idea is to create a wordpress user when a user signs up on your cakephp site.

1. We need wordpress password hash function to do this properly. You need to create a new component that would contain wp password hashing functions. The file that contains everything you need is at wp-include/class-phpass.php. Just turn this class into a cakephp component, so you can include it in your user controller.

2. In your user controller, include your recently created wp hash function component. And after the user is saved into your cakephp user table. You want to add it to your wp user table as well. And it would look something like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
if($this->User->save($this->data))
{
//create blog user for this user

$wp_hash = new $this->Wphash;
$wp_hash->PasswordHash(8,1);
$blog_user['ID'] = $this->User->id;
$blog_user['user_login'] = $this->sanitize_user($email);
$blog_user['user_pass'] = $wp_hash->HashPassword($this->data['User']['password']);
$blog_user['user_email'] = trim($email);
$blog_user['user_url'] = 'http://';
$blog_user['user_nicename'] = $this->data['User']['firstname'].' '.substr($this->data['User']['lastname'],0,1);
$blog_user['display_name'] = $this->data['User']['firstname'].' '.substr($this->data['User']['lastname'],0,1);
$blog_user['user_registered'] = date(configure::read('dateformat'));
$blogdata['Blog_user'] = $blog_user;
$this->Blog_user->save($blogdata);

//create user meta

$bid = $this->Blog_user->id;
$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'first_name';
$user_meta['meta_value'] = $this->data['User']['firstname'];
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'last_name';
$user_meta['meta_value'] = $this->data['User']['lastname'];
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'nickname';
$user_meta['meta_value'] = $email;
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'rich_editing';
$user_meta['meta_value'] = 'true';
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'comment_shortcuts';
$user_meta['meta_value'] = 'false';
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'admin_color';
$user_meta['meta_value'] = 'fresh';
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

$user_meta['user_id'] = $bid;
$user_meta['meta_key'] = 'blog_capabilities';
$user_meta['meta_value'] = 'a:1:{s:10:"subscriber";b:1;}';
$blogdata['BlogUserMeta']= $user_meta;
$this->BlogUserMeta->save($blogdata);

3. In your wordpress index.php file

1
2
3
4
5
//change the session name of your wordpress site to match that of your cakephp site.

//so session data can be shared.

session_name("mysite");

4. in your theme header.php(might not be the best place if you change your theme a lot)

1
2
3
4
5
6
7
8
9
10
11
12
13
//you read the user id

$user = $_SESSION['Auth']['User'];
if(!empty($user))
{
//you change the current user manually

wp_set_current_user($user['id']);
}

And there you have it.

One of my bigger project requires me to setup personal sites on the main site’s subdomains. So i did what everyone would do and googled that.

It turned out to be quite simple. You just have to set session.cookie_domain to the domain of your site without www.

Like this session.cookie_domain = .mysite.com

Of course, you can set it with php using

1
ini_set("session.cookie_domain", ".localhost/mysite");

AND
You probably need to set cakephp security setting to medium or low. You can do that in core.php
Some people say medium is enough, but i needed to change minie to low in order for it to work.

Here’s a cool function i found today while i was working on a project.

it prints the first n sentence.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<span style="color: #000000;"><span style="color: #007700;">function </span><span style="color: #0000bb;">getLeadingSentences</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$data</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$max</span><span style="color: #007700;">)
{
</span><span style="color: #ff8000;">//given string $data, will return the first $max sentences in that string</span></span>

//in: $data = the string to parse, $max = maximum # of sentences to return
//returns: string containing the first $max sentences
//(If the # of sentences in the string is less than $max,
//then entire string will be returned.)

//a sentence is any charactors except ., !, and ?
//any number of times,  plus one or more .s, ?s, or !s
//and any leading or trailing whitespace:
<span style="color: #0000bb;">$re </span><span style="color: #007700;">= </span><span style="color: #dd0000;">"^s*[^.?!]+[.?!]+s*"</span><span style="color: #007700;">;
</span><span style="color: #0000bb;">$out </span><span style="color: #007700;">= </span><span style="color: #dd0000;">""</span><span style="color: #007700;">;
for(</span><span style="color: #0000bb;">$i </span><span style="color: #007700;">= </span><span style="color: #0000bb;">0</span><span style="color: #007700;">; </span><span style="color: #0000bb;">$i </span><span style="color: #007700;">< </span><span style="color: #0000bb;">$max</span><span style="color: #007700;">; </span><span style="color: #0000bb;">$i</span><span style="color: #007700;">++) {
if(</span><span style="color: #0000bb;">ereg</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$re</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$data</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$match</span><span style="color: #007700;">)) {
</span><span style="color: #ff8000;">//if a sentence is found, take it out of $data and add it to $out
</span><span style="color: #0000bb;">$out </span><span style="color: #007700;">.= </span><span style="color: #0000bb;">$match</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">];
</span><span style="color: #0000bb;">$data </span><span style="color: #007700;">= </span><span style="color: #0000bb;">ereg_replace</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$re</span><span style="color: #007700;">, </span><span style="color: #dd0000;">""</span><span style="color: #007700;">, </span><span style="color: #0000bb;">$data</span><span style="color: #007700;">);
}
else {
</span><span style="color: #0000bb;">$i </span><span style="color: #007700;">= </span><span style="color: #0000bb;">$max</span><span style="color: #007700;">;
}
}
return </span><span style="color: #0000bb;">$out</span><span style="color: #007700;">;
}</span>

<span style="color: #ff8000;">//EXAMPLE:
</span><span style="color: #0000bb;">$start </span><span style="color: #007700;">= </span><span style="color: #dd0000;">"Sentence one...  Sentence two?  Sentence three!  Sentence four."</span><span style="color: #007700;">;
</span><span style="color: #0000bb;">$end </span><span style="color: #007700;">= </span><span style="color: #0000bb;">getLeadingSentences</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$start</span><span style="color: #007700;">, </span><span style="color: #0000bb;">3</span><span style="color: #007700;">);
echo(</span><span style="color: #dd0000;">"result: $end"</span><span style="color: #007700;">); </span>

[source]