Category Archives: PHP

So you want PayPal Express Checkout on Magento 1.3?

And you get some weird errors…
open your app/code/core/Mage/Paypal/Model/Api/Nvp.php file and search for SOLUTIONTYPE, change its value to “mark”.

Edit your PayPal preferences from Magento backend and use this PayPal Url:
https://www.paypal.com/au/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=

You should be done.
Good luck.

P4A’s tools changes

In the last months we had problems with the past infrastructure, our mediawiki was heavily attacked and become useless and SourceForge’s bugtracker was completely destroyed by spam. So I took the suggestion of one of our followers to rethink about everything and give it a spin:

The forum system is still on SourceForge, I didn’t find a way to migrate it somewhere else but it didn’t have any bad troubles in the past so it should be ok to keep it on SourceForge at the moment, what do you think?

That should be all for now, thank you everyone and I hope we’ll see much more movement around P4A in the future!

Magento 2.0

News are coming out about our new loved/hated Magento major (and it’s gonna be really major) release: Magento2.

First of all a technical overview video, not too recent actually:

One amazing thing is that the development moved to github:
https://github.com/magento/magento2
with all the benefits we know.

Another nice improvement is that we have public tests for the test addicted:
https://github.com/magento/taf

A couple of nice articles about Magento 2.0:

Magento 2.0 is scheduled for Q4.2012, let’s see what is going to happen! :)

cygwin lighttpd php mysql, the perfect dev setup for windows

Since a few months, after more than 10 years on Linux, I switched my main OS to win7 (I’ll write something about this switch in a different post) and I’m quite happy with it, if there’s a thing I wasn’t happy about (’till today) was my development servers environment, I had Zend Server + MySQL, both as windows services, eating my pc’s resources also if I was not using it to work. Another thing was that I only work on Linux production servers and having those “c:\” paths just felt wrong.

I already used the great cygwin for a bunch of things, most of all rsync backups, so I decided to try removing Zend Server + MySQL for windows and move those services inside the cygwin environment, so I can start them with a bash script whenever I need them and I’m finally free from the “c:\” paths.

The problem was that there’s no documentation at all about this kind of installation, so:

  • no problems with MySQL, just install the packages, run “mysql_install_db” just the first time, and then call “mysqld_safe &” to start it when you need it
  • I couldn’t make apache2 work so I decided to use lighttpd
  • Configure and install all PHP packages you need using the cygwin ports project cause the main cygwin repository doesn’t have them

I ran into a few troubles configuring PHP for lighttpd, so here you have my /etc/lighttpd/lighttpd.conf:


# lighttpd configuration file
#
# use it as a base for lighttpd 1.0.0 and above
#
# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $

############ Options you really have to take care of ####################

## modules to load
# at least mod_access and mod_accesslog should be loaded
# all other module should only be loaded if really neccesary
# - saves some time
# - saves memory
server.modules = (
 "mod_rewrite",
# "mod_redirect",
# "mod_alias",
 "mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
# "mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
 "mod_cgi",
# "mod_compress",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
 "mod_accesslog" )

## a static document-root, for virtual-hosting take look at the
## server.virtual-* options
server.document-root = "/srv/www/htdocs/"

## where to send error-messages to
server.errorlog = "/var/log/lighttpd/error.log"

# files to check for if .../ is requested
index-file.names = ( "index.php", "index.html",
 "index.htm", "default.htm" )

## set the event-handler (read the performance section in the manual)
# server.event-handler = "freebsd-kqueue" # needed on OS X

# mimetype mapping
mimetype.assign = (
 ".pdf" => "application/pdf",
 ".sig" => "application/pgp-signature",
 ".spl" => "application/futuresplash",
 ".class" => "application/octet-stream",
 ".ps" => "application/postscript",
 ".torrent" => "application/x-bittorrent",
 ".dvi" => "application/x-dvi",
 ".gz" => "application/x-gzip",
 ".pac" => "application/x-ns-proxy-autoconfig",
 ".swf" => "application/x-shockwave-flash",
 ".tar.gz" => "application/x-tgz",
 ".tgz" => "application/x-tgz",
 ".tar" => "application/x-tar",
 ".zip" => "application/zip",
 ".mp3" => "audio/mpeg",
 ".m3u" => "audio/x-mpegurl",
 ".wma" => "audio/x-ms-wma",
 ".wax" => "audio/x-ms-wax",
 ".ogg" => "application/ogg",
 ".wav" => "audio/x-wav",
 ".gif" => "image/gif",
 ".jar" => "application/x-java-archive",
 ".jpg" => "image/jpeg",
 ".jpeg" => "image/jpeg",
 ".png" => "image/png",
 ".xbm" => "image/x-xbitmap",
 ".xpm" => "image/x-xpixmap",
 ".xwd" => "image/x-xwindowdump",
 ".css" => "text/css",
 ".html" => "text/html",
 ".htm" => "text/html",
 ".js" => "text/javascript",
 ".asc" => "text/plain",
 ".c" => "text/plain",
 ".cpp" => "text/plain",
 ".log" => "text/plain",
 ".conf" => "text/plain",
 ".text" => "text/plain",
 ".txt" => "text/plain",
 ".dtd" => "text/xml",
 ".xml" => "text/xml",
 ".mpeg" => "video/mpeg",
 ".mpg" => "video/mpeg",
 ".mov" => "video/quicktime",
 ".qt" => "video/quicktime",
 ".avi" => "video/x-msvideo",
 ".asf" => "video/x-ms-asf",
 ".asx" => "video/x-ms-asf",
 ".wmv" => "video/x-ms-wmv",
 ".bz2" => "application/x-bzip",
 ".tbz" => "application/x-bzip-compressed-tar",
 ".tar.bz2" => "application/x-bzip-compressed-tar",
 # default mime type
 "" => "application/octet-stream",
 )

# Use the "Content-Type" extended attribute to obtain mime type if possible
#mimetype.use-xattr = "enable"
## send a different Server: header
## be nice and keep it at lighttpd
# server.tag = "lighttpd"

#### accesslog module
accesslog.filename = "/var/log/lighttpd/access.log"

## deny access the file-extensions
#
# ~ is for backupfiles from vi, emacs, joe, ...
# .inc is often used for code includes which should in general not be part
# of the document-root
url.access-deny = ( "~", ".inc" )

$HTTP["url"] =~ "\.pdf$" {
 server.range-requests = "disable"
}

##
# which extensions should not be handle via static-file transfer
#
# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

###### virtual hosts

##
## If you want name-based virtual hosting add the next three settings and load
## mod_simple_vhost
##
## document-root =
## virtual-server-root + virtual-server-default-host + virtual-server-docroot
## or
## virtual-server-root + http-host + virtual-server-docroot
##
#simple-vhost.server-root = "/srv/www/vhosts/"
#simple-vhost.default-host = "www.example.org"
#simple-vhost.document-root = "/htdocs/"

## virtual directory listings

dir-listing.activate = "enable"
## select encoding for directory listings
dir-listing.encoding = "utf-8"

#

# chroot() to directory (default: no chroot() )
#server.chroot = "/"

## change uid to <uid> (default: don't care)
#server.username = "wwwrun"

## change uid to <uid> (default: don't care)
#server.groupname = "wwwrun"

cgi.assign = (".php"=>"/usr/bin/php-cgi")

Now that you’ve the right lighttpd config file, just start lighttpd with “/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf &” and you’re done, the perfect PHP dev environment on windows is yours.

Magento reindexer issue and very bad fix

On a big website, while Magento (this was a Professional 1.10.something) is reindexing (work done by a cron job) every page (viewed from the browser) seems to try to reindex the products it shows, that ends in a duplicate key error on an index temporary table (catalog_product_index_price_tmp), I needed a rough and quickfix I opened app\code\core\Mage\Index\Model\Resource\Helper\Abstract.php and added a try/catch to the insertFromSelect method, making it become:

public function insertFromSelect($select, $destTable, array $columns, $readToIndex = true)
    {
		try {
        if ($readToIndex) {
            $from   = $this->_getWriteAdapter();
            $to     = $this->_getIndexAdapter();
        } else {
            $from   = $this->_getIndexAdapter();
            $to     = $this->_getWriteAdapter();
        }

        if ($this->useDisableKeys()) {
            $to->disableTableKeys($destTable);
        }
        if ($from === $to) {
            $query = $select->insertFromSelect($destTable, $columns);
            $to->query($query);
        } else {
            $stmt = $from->query($select);
            $data = array();
            $counter = 0;
            while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
                $data[] = $row;
                $counter++;
                if ($counter>2000) {
                    $to->insertArray($destTable, $columns, $data);
                    $data = array();
                    $counter = 0;
                }
            }
            if (!empty($data)) {
                $to->insertArray($destTable, $columns, $data);
            }
        }
        if ($this->useDisableKeys()) {
            $to->enableTableKeys($destTable);
        }
		} catch (Exception $e) {}
        return $this;
    }

It is bad but now it’s working, oh god.