support unicode in Magento product url key

Magento is one of the best E-Commerce platforms currently on the internet. However, it doesn’t seem to take into account one of the most important SEO rules which states that the URL key which is used to create the product’s URL should be SEO-friendly. We can still write the url key in english for our arabic products but this won’t exactly match this rule to have the arabic keywords of the product’s title in the product url as well.

I rolled up my sleeves and got to work. What i did was a 2 stage tracing / debugging session. I will also be writing this in a magento module to group this functionality all together into a reusable component.

Let’s start preparing for the module we’re going to create. All you have to do, assuming you name your company “XYZ” is the following:

1) Create a folder called “XYZ” in your app/code/local directory.

2) Inside XYZ, create a folder called “etc” and another folder called “Model”.

3) Inside XYZ/etc create a file called config.xml and add the following:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <XYZ_UnicodeUrls>
            <version>0.0.1</version>
        </XYZ_UnicodeUrls>
    </modules>
</config>

Now… here’s what i’ve done.

1) The first problem was that when entering the product key in arabic, the product got saved with an empty url key. Using Zend Studio and xdebug’s remote debugging, i found out that product entity attributes were being filtered. One of the filters passed on the url_key field was “Mage_Catalog_Model_Product_Url”. The method being called in that filter is “formatUrlKey” which takes the URL key as a string:

public function formatUrlKey($str)
{
    $urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str));
    $urlKey = strtolower($urlKey);
    $urlKey = trim($urlKey, '-');
 
    return $urlKey;
}

As you can see from the regex in the first line of the function’s body. All characters are being removed apart from 0 to 9 and a – z (small case). All we had to do here is override the function to become:

public function formatUrlKey($str)
{
    $urlKey = Mage::helper('catalog/product_url')->format($str);
    $urlKey = strtolower($urlKey);
    $urlKey = trim($urlKey, '-');
 
    return $urlKey;
}

So the final model code should become:

<?php
class XYZ_UnicodeUrls_Model_Product_Url extends Mage_Catalog_Model_Product_Url
{
    public function formatUrlKey($str)
    {
        $urlKey = Mage::helper('catalog/product_url')->format($str);
        $urlKey = strtolower($urlKey);
        $urlKey = trim($urlKey, '-');
 
        return $urlKey;
    }
}

Make sure you add the following to your config.xml so that magento can rewrite the original model with your one.

<global>
    <models>
    ....
        <catalog>
            <rewrite>
                <product_url>N2Vlabs_UnicodeUrls_Model_Product_Url</product_url>
            </rewrite>
        </catalog>
    .....
    </models>
</global>

2) Even if you’ve solved the problem of adding a unicode url key. Now we have to make sure magento was finding a record for this URL inside table “core_url_rewrite” when looking for it.

After digging a bit deep into what is going on, i also found out that “Mage_Core_Model_Resource_Url_Rewrite” was looking up the database for this URI in a method:

public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)

When having an arabic URI, the URI is captured url encoded inside this method’s loop that looks as follows:

foreach ($path as $key => $url) {
    $pathBind['path' . $key] = $url;
}

All we had to do here is to make sure we url decode $url to become:

foreach ($path as $key => $url) {
    $pathBind['path' . $key] = urldecode($url);
}

The whole code looks as follows:

<?php
class XYZ_UnicodeUrls_Model_Resource_Url_Rewrite extends Mage_Core_Model_Resource_Url_Rewrite
{
    public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
    {
        if (!is_array($path)) {
            $path = array($path);
        }
 
        $pathBind = array();
        foreach ($path as $key => $url) {
            $pathBind['path' . $key] = urldecode($url);
        }
        // Form select
        $adapter = $this->_getReadAdapter();
 
        $select = $adapter->select('*')
            ->from($this->getMainTable())
            ->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')')
            ->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId()));
 
        $items = $adapter->fetchAll($select, $pathBind);
 
        // Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
        $mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
        $currentPenalty = null;
        $foundItem = null;
        foreach ($items as $item) {
            $penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
            if (!$foundItem || $currentPenalty > $penalty) {
                $foundItem = $item;
                $currentPenalty = $penalty;
                if (!$currentPenalty) {
                    break; // Found best matching item with zero penalty, no reason to continue
                }
            }
        }
 
        // Set data and finish loading
        if ($foundItem) {
            $object->setData($foundItem);
        }
 
        // Finish
        $this->unserializeFields($object);
        $this->_afterLoad($object);
 
        return $this;
    }
}

And you have to add the following to your config.xml to override the original model.

<global>
    <models>
        ....
        <core_resource>
            <rewrite>
                <url_rewrite>XYZ_UnicodeUrls_Model_Resource_Url_Rewrite</url_rewrite>
            </rewrite>
        </core_resource>
        ....
    </models>
</global>

If you’d like to get the whole extension code from github… here’s the link

That’s all folks… see ya next time.

Tagged , , , ,

PHP getting difference between two arrays

Is it me? or is array_diff and array_diff_assoc don’t really cover the requirements of getting the actual difference between two arrays ?

I am currently working on a project using Yii Framework. What i am trying to do, is get the list of fields that have changed after saving data within my model (CActiveRecord).

According to the documentation of array_diff, it Returns an array containing all the entries from array1 that are not present in any of the other arrays. Which is not what i needed. What i really needed is a function that checks the difference between two arrays and returns all entries from array1 which are not in array2 and all entries from array2 which don’t exist in array1 in addition to checking if the actual values have changed.

 

Here’s my attempt at solving this problem:

protected function getChangesBetweenArrrays($oldArr, $newArr) {
    $changedFields = array();
 
    foreach($oldArr as $key => $value) {
        if(!isset($newArr[$key])) {
            $newArr[$key] = '';
        }
    }
 
    foreach($newArr as $key => $value) {
        if($key == 'id') continue;
 
        $item = false;
        if(!isset($oldArr[$key]) && isset($newArr[$key])) {
            $item = array('field'=>$key, 'value'=>$newArr[$key]);
        }
        elseif(isset($oldArr[$key]) && $newArr[$key]=='') {
            $item = array('field'=>$key, 'value'=>'removed');
        }
        elseif($oldArr[$key] != $newArr[$key]) {
            $item = array('field'=>$key, 'value'=>$newArr[$key]);
        }
        if($item) {
            $changedFields[] = $item;
        }
    }
 
    return $changedFields;
}

I would love to hear your feedback on this solution and if you’ve been facing such a case, what was your implementation?

What is swipe200?

Hello Again,

I am sure you all want to know about what swipe200 is all about?

swipe200 (Swipe 2 Infinity) brings you the experience of watching-TV-on-a-couch to the web. Usually, when sitting on a TV, you lay back on your couch, holding the remote control and you keep flipping between channels till you find something you like one one of those channels. Chances are that you might land on a channel that you keep watching or keep flipping channels till you do.

In swipe200, you keep swiping left and right between channels as if you’re pressing on the CH+ or CH- on your TV’s remote control. But this time you are adding channels that you really like to your wall. Your own wall is the place where fresh new content of the channels you are subscribed to will show. Its like owning a TV and your own broadcasting channel at the same time.

So what are you waiting for? Throw out your TV’s remote .. grab your connected-to-the-internet computer and start swiping .. discover content you like through swipe to infinity!

Swipe content categories:

 

Feel free to go there right now and check it out. Remember, don’t forget to create an account. If you’re a facebook user… there’s always an option for you to login using your facebook account. Don’t worry, we will not be stealing any of your private info :)

Visit swipe200.com now!

And don’t forget to head over to our facebook page:

swipe200 on facebook, like our sub pages and enjoy the ride :)

 

Rakan

Tagged , , , , , , , , ,

If This Then That (ifttt)

A very nice service which can let you trigger certain actions when updates are found from a certain channel. For this example, i am writing this blog post and telling ifttt that when i post a new blog, share it on my facebook account!

The Lean Startup, What it is and What it is NOT

At least of what my conception of the methodology of Lean Startups.

The Lean Startup methodology suggests that you go about building your startup in simple steps:

  1. Problem / Solution Fit, this is where you suggest the problem your product (startup) solves for your customer segment. You end up by answering ONE simple question. Do i have a problem WORTH solving?
  2. Product / Market Fit, It is after you prove that your product solves an actual problem that you go about on validating whether your product users are willing-to-pay customers.
  3. Scale, when you’ve figured out that you’re doing a decent job at building, measuring and learning about your customers you know that when you scale, you’re acquired customers will be engaged into using, buying.. etc your product.

 

In all of the above steps, you simply follow a simple three-steps formula: Build, Measure, Learn.

  1. Build: Develop an minimal-viable-product (MVP) of your suggested solution. Your MVP should provide the core solution.
  2. Measure: Specifying what metrics you want to consider when you’re analyzing customer behavior when using the product.
  3. Learn: You build conclusions and optimize your product based on your analysis in the measuring step.

 

This day, Jan 12th 2012, CEO of N2V Labs Rami Alkarmi gave a session Lean Startup 101 which was a great brief introduction on how to follow the methodology. The session was a great one and i suggest you click on the link to check the slides available at Rami’s blog.

Having that i’ve attended the session as part of N2V Labs and being an Entrepreneur-in-Residence at the Labs and also with a hands-on experience on following the lean startup methodology; i found that there was a small misconception by the crowd that Lean Startup is THE secret sauce to a successful startup and nothing else.

Uhhm,  NO!

Lean startup is NOT a super mathematic formula that if you follow your startup is going to be the next big thing. Lean Startup is basically a major player in the game and is also a factor of the success of any startup.

So what is all about?

Well, my conception is that it is all about the Entrepreneur! Simply put, each one of us has his/her own way of logical thinking. His/her way of understanding and implementing. The Lean Startup is only successful if the entrepreneur following the methodology is a good one.

They say that you can never succeed if you don’t fail. Good Entrepreneurs fail fast, learn from failures, adapt and pivot based on those experiences.

 

Correct me if i am wrong :) , feel free to drop a comment if you’re in the mood to discuss.

Links:

1) Rami Alkarmi’s blog

2) The Lean Startup

Rakan

 

N2V meets with Google VP of product management on GJordan day

The N2V team had an exclusive meeting with Nelson Mattos the Google vice-president of product management and engineering for Europe, the Middle East and Africa. The meeting took place during the first day of G.Jordan (Google day in Jordan) event in Amman, on the 23rd of October at the Grand Hyatt.

The two parties exchanged valuable insights and information especially concerning the region. Rami Al-Karmi, the N2V investment director and head of Labs, spoke briefly about the N2V projects and investments. Nelson When asked, shared information about how Google manages its big number of projects around the world. He answered by explaining how Google tries to strike the balance between the freedom of innovation and the structure of discipline. Nelson said ” As i always like to say, Google is an organized chaos”.

When Google looks at a product in a region, it sees whether the product succeeds or not from many angles. The product might succeed, however not in the region. “Thus we either keep the team in that region, but keep it small, or we choose to relocate this team to another area. However if the project succeeds, then Google invests in a bigger team in that area.”

Nelson was asked many questions of which he displayed Google’s expertise.

The questions were as follows:

Question: What is the perfect size of a successful production team?

Answer: “A Google production team ranges from 6-10 members, doesn’t exceed a dozen. However that isn’t the real measure of success. Google runs by a system of OKRs (objectives and key results). These goals are how a team measures whether its going in the right direction or not. Google isn’t afraid to kill big projects, that are not achieving their expected results.

 

Question: When it comes to fitting the projects with the Google strategy. Is it a top-downward decision where structure is imposed. Or is it a down-upward decision where the engineers have to fit their product to the Google strategy?

Answer: Its a bit of both. We have a system called 80% – 20%. Where our engineers work 80% of their time on their main assigned project. However in the left 20% they work on whatever small project they choose to work on that they seem passionate about. however those small projects are a result of ideas that come from individuals within Google, they are not funded by the company. The main projects that take 80% of the time, are already structured according to the Google strategy. However the 20% percent projects that the engineers are passionate about, they one day would like to have them as main projects. If so then they will need to prove the project’s success by making the project fit with the company’s strategy. So they can convince the board to fund their project and thus become a main Google successful project. Google Maps was a project that started as a 20% project. Just like the “commenting on youtube video” project, and the Google Doodle project.

 

Question: Some Google products failed in the Middle East, example “Google Buzz”. What did the google marketing do in efforts to fix situations like that in the future?

Answer: if you mean understanding the market, we have 2 organizations that focus on understanding the regions. Our marketing team has a division that does marketing analysis. they do all kinds of research; Quantitative, and Qualitative like focus groups, and experimenting with users, which has a major input in our products. 5 years ago when we launched a product we launched the same product everywhere in the world, with only the translation of languages. However that cannot be the case today. for example there are internet companies in China or Russia since they are not Americans they don’t think the american way, and thus our products that are targeted to them have more features added that are appealing to those markets.

 

Question: How do you organize that no 2 or more teams are working on the same project?

Answer: In the small scale this isn’t considered a problem that we would want to fix. because if three teams are working on the same idea, tackled in different approaches. This increases the stakes of the right approach of the idea to succeed. However because we have a database that has all the projects listen on it, through this kind of transparency everybody in the company knows the projects that are being worked on. We are a very down-upwards company when it comes to innovation of ideas, however that doesn’t mean we lack the discipline and structure of the up-downwards decisions. Nelson was asked a question about what they do when they have a product but not enough market research. And he replied that sometimes when they have the product they launch it before the market research is complete. because sometimes they learn through throwing the product in the market.

 

Question: Assuming that the Google team finished the project implementation. How do they market for the Product? do they tackle different acquisition channels, or do they do the easy way by using their own channels?

Answer: Our marketing department has its own budget. In case of it using the Google marketing methods, it does pay google for whatever methods it chooses to use. However it was a surprise to me, that in Google some products can be launched without marketing. the product is launched and by chance users discover it, and boom it takes off. However for products that are a little more complicated and need explanation to the user, we launch a campaign that explains how these can be used. we have recently done a television ad.

 

Question: If you look at the Google chrome speed test, that was a great way to market the idea. Do the engineers come up with these marketing ideas?

Answer: We have marketing teams focused on each project, and we have a team called the creative team, who came up with great ideas like the “paris love” campaign. their idea was getting the attention of a non-technical person, and because our marketing people are in between the technicals and the publics they are capable of coming up with such ideas.

 

question from a user came as follows: I use Facebook and Google ads. However i turn to Facebook ads when i want to target a specific audience. How much does Google understand the person using their search engine, and his needs?

Answer: To begin with, we know the person’s region from their IP address. And we can make a very close guess of this person’s needs, through his browsing habits.

 

Question: Google acquisitions, some turn to be very successful companies, and some are small however doing very well. How does Google see the potential in them and decide on the acquisition?

Answer: What matters to us isn’t always the idea, or the product. However what matters to Google is the people behind the idea. And that is our first type of acquisitions. the second type of acquisitions is feature acquisitions. The third type of acquisitions is are the ones we tackle because they are in areas we want to go into.

 

Then Nelson was interested to know, the feedback of Google users in the region. With which many of the participants had of insights to give him.

Of those insights were,

1- Hiring Google Ambassadors in the region that would physically go around collecting data, of local shops to be added in the search engine or Google maps..etc.

2- Simplifying the technical side of Google ads. make it simpler for the region to use.

3-Improving Google Ads form of payment. Not everybody in the Middle East deals with credit cards.

 

3inapp public beta was launched!

What is 3inapp?

3inapp (Pronounced innap or عناب in Arabic) is the first arabic marketplace for mobile-friendly web applications. 3inapp contains a huge collection of international mobile-friendly applications which you can install and use including facebook, twitter, gmail, yahoo and many more.

Every decent well-known website displays a mobile version for visitors browsing the website from a smart phone device. 3inapp uses this key feature to bring web apps to your smart phone homescreen. By installing any application on your homescreen from 3inapp, you can use this application just like you use any other app installed from Android’s marketplace or Apple Appstore.

So what updates does 3inapp bring to the average user?

This is simple… by using 3inapp powered apps, these apps are not ACTUALLY installed on your mobile phone… they are simply run on the cloud and the result is displayed back to you on your smartphone… while native apps from android’s marketplace or Apple Appstore will be downloaded as a package into your smartphone taking up phone disk space which will definitely run out in the near future. 3inapp simply downloads a single tiny file which is added onto your homescreen which doesn’t consume even 10% of native apps consumed space which enables you to have as many apps installed on your phone as possible.

 

Whats next?

3inapp has many more surprises… navigate now to http://3inapp.com for instructions on how to download 3inapp and check it out… we would love your feedback if any at support@3inapp.com

(Or use this QR code to quickly access 3inapp)

3inapp QR code

3inapp QR code

 

 

The weakness of PHP frameworks

A programming language framework is meant to decrease the development time and increase the productivity of software developers. However, i still find the frameworks built for the PHP language still concentrate on building the lower-level features of the frameworks while disregarding the importance of higher level ones.

Example, Zend framework provides the set of class chains which provide the functionality to implement the login mechanism. This includes authentication (Zend_Auth) and Authorization (Zend_Acl). But in reality, these components still require me to write integration codes to be able to have this whole membership feature.

My point is, having a framework that provides plug-and-play components just like Django’s middleware which you can just drop into your framework-based application and have the feature working with almost zero efforts.

Is lacking this plug-and-play feature because framework developers prefer implementing the low-level code patterns such as MVC, or is implementing customizable functional out of the box components really hard?

http://www.phpframeworks.com/top-10-php-frameworks/

Exception handling isn’t a must!

As a long-time PHP developer, i find exception handling to be an option that PHP supports just because other languages do or because OOP in PHP started to emerge in the 5.x series of the language.

I’ve developed many systems in the past and present days… from small simple to high scalability applications and to be honest, i found that i can easily write code with no exception handling whatsoever and that application will do just fine. I know i know, “will do just fine” is the normal behavior of any well-written application, but book and tutorials writers always tend to emphasize on the importance of using exception handling in code to make sure the application does not crash in case some exception is thrown. But this is the point, PHP rarely throws exceptions, it mainly triggers errors which can be handled by set_error_handler.

The only thing that ever forced me to use exception handling was when i used well designed OOP 3rd party libraries which throw exceptions instead of triggering errors… which is exactly what PHP is supposed to be doing as far as am concerned.

 

Have YOU ever used exception handling in any other case than the one i just mentioned? please enlighten me :)

 

Rakan

Whats new in PHP 5.4

According to PHP.net, php 5.4 alpha1 has been released.  So whats new about it? alright here we go:

1) Array dereferencing support (finally!):

We all know that we can do the following with objects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass1
{
    public function get()
    {
        return new MyClass2();
    }
}
 
class MyClass2
{
    public function test()
    {
        return "Hello world";
    }
}
 
$a = new MyClass1();
echo $a->get()->test(); // Will output Hello world

But if MyClass1 “get” method was to return an array we would do this in a different way:

1
2
3
4
5
6
7
8
9
10
11
class MyClass1
{
    public function get()
    {
        return array('text'=>'Hello world');
    }
}
 
$a = new MyClass1();
$arr = $a->get();
echo $arr['text']; // Will output Hello world

But now using PHP 5.4 we can do this:

1
2
3
4
5
6
7
8
9
10
class MyClass1
{
    public function get()
    {
        return array('text'=>'Hello world');
    }
}
 
$a = new MyClass1();
$arr = $a->get()['text'];

2) Added indirect method call through array
Now an array(‘class’, ‘method’) can be used to call a function. is_callable will return true.

That means we can do:

1
2
3
4
5
6
7
8
class MyClass1 {
   public function test($name) {
      echo "Hello, $name";
   }
}
 
$f = array('MyClass1','test');
echo $f('World'); // Hi, World

3) Added closure $this support back
When using closures in PHP 5.3, using this inside the closure itself a hack was needed in the form of a callback context. However, in PHP 5.4 we can do the following with no hacks whatsoever:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyClass1 {
  private $value = 1;
  function get($name) {
    return function() use ($name) {
      return $this->$name;
    };
  }
}
class MyClass2 {
  private $value = 2;
  function test() {
    $mc1 = new MyClass1();
    $getter = $mc1->get('value');
    print $getter();
  }
}  
 
$b = new MyClass2();
$b->test();

4) Traits support
The topic about traits is quite long. I suggest you google php traits or have a look at the following link: RFC Horizontal reuse

Conclusion:
Its great to see these features coming to PHP even though it took longer than expected. I seriously hope they start breaking backward compatibility and implementing everything as an object just like Ruby & Python.

Tagged , ,