SociallyNotable: Amazon.com Affiliate Site

 No comments     jwage

March 19th, 2011 

A little side project of mine, SociallyNotable.com, that I built using Symfony2 and the Doctrine MongoDB ODM is starting to get a pretty regular stream of traffic each day. It is not a lot, but I can see it steadily increase as Google slowly indexes all the content. It was an interesting project and a fun one because of the amount of data you gather searching Twitter for tweets with links to Amazon.com products. It is also interesting watching the trends and seeing what products are the most popular each day. The site is pretty simple, you can see past daily deal, watch a live stream of the products that people are tweeting right now, browse all products, or register for daily e-mail notifications of the most popular products at the end of each day. You can even use the site to generate random popular gifts to give to your friends for birthdays, holidays, etc.

The site was built as an experimental playground for myself and uses the following technologies:

  • Ubuntu
  • nginx
  • supervisor
  • PHP
  • MongoDB
  • Symfony2
  • Doctrine MongoDB ODM

Posted in: Doctrine, MongoDB, Open Source, PHP, Symfony2

Tags: affiliate, amazon, mongodb, odm, php

Keep your Kitchen Sink Clean

 No comments     jwage

March 18th, 2011 

When programming in any language, you must remember to keep your kitchen sink clean and do the dishes regularly!

* Image courtesy of Jeremy Mikola

Posted in: PHP

Tags: php, programming, technical debt, testing

Getting married and buying a new house

 No comments     jwage

March 17th, 2011 

Yep, it’s true! I am getting married to the love of my life, Megan Byrd! and we are currently shopping for a new house for us to start our lives in together. I bought my first house when I was 19 and I can’t believe I’ve been living here for almost 7 years now! It is time to move on to a new place and rent out our current house.

Buying a new house is an exciting ride. It has been up and down so far and we have already put in an offer on a house we really liked. Unfortunately, another offer was made and we did not get the house. So, we’ve started looking again and I think this time we’ll find something that we like even better!

Posted in: Life

Tags: house, marriage

MongoDB Tailable Cursors

 5 comments     jwage

March 16th, 2011 

Tailable cursors are a cool feature of MongoDB. It allows you to setup scripts that run forever and are constantly processing new data that gets inserted to the collection. You need a capped collection in order to tail a cursor so just create a new collection and make sure it is capped to a size you can specify:

> db.createCollection("my_collection", {capped:true, size:100000})

Now you can tail a cursor in your favorite language. I have a few examples of the same script in PHP, Ruby, Python and Perl!

PHP

<?php

$mongo = new Mongo();
$db = $mongo->selectDB('my_db')
$coll = $db->selectCollection('my_collection');
$cursor = $coll->find()->tailable(true);
while (true) {
    if ($cursor->hasNext()) {
        $doc = $cursor->getNext();
        print_r($doc);
    } else {
        sleep(1);
    }
}

Ruby

db   = Mongo::Connection.new().db('my_db')
coll = db.collection('my_collection')
cursor = Mongo::Cursor.new(coll, :tailable => true)
loop do
  if doc = cursor.next_document
    puts doc
  else
    sleep 1
  end
end

Python

By Robert Stewart:

from pymongo import Connection
import time

db = Connection().my_db
coll = db.my_collection
cursor = coll.find(tailable=True)
while cursor.alive:
    try:
        doc = cursor.next()
        print doc
    except StopIteration:
        time.sleep(1)

Perl

By Max

use 5.010;

use strict;
use warnings;
use MongoDB;

my $db = MongoDB::Connection->new;
my $coll = $db->my_db->my_collection;
my $cursor = $coll->find->tailable(1);
for (;;)
{
    if (defined(my $doc = $cursor->next))
    {
        say $doc;
    }
    else
    {
        sleep 1;
    }
}

If you want to provide the same example in another language please add it in the comments and I’d be glad to include it here!

Posted in: MongoDB, PHP

Tags: mongodb, php, ruby

MongoDB Hosting by ServerGrove

 2 comments     jwage

March 15th, 2011 

Recently I partnered with ServerGrove to help bring a new product to the market for MongoDB hosting. The service aims to be a highly scaleable, fast and easy solution for MongoDB hosting. The service features a pay for usage billing structure and a fully featured user interface for managing everything related to your shared and dedicated MongoDB instances. Below are a few highlights of the features the service will provide.

Features

  • Free, Shared and Dedicated Options
  • UI for managing databases, collections, documents, backups and much more.
  • Easy to get started with free option and connect to your MongoDB servers remotely. Great for development!
  • Pay for usage only.
  • Tight integration with the existing ServerGrove shared and VPS web hosting options.

We are currently under heavy development integrating the MongoDB hosting with the ServerGrove infrastructure and the awesome already existing control panel. You can sign up for a beta invite at mongodbhosting.com and we’ll let you know when the service is live and ready for you to test with the FREE option!

Posted in: MongoDB, ServerGrove

Tags: hosting, mongodb, servergrove

Tips on Being Successful in Open Source

 5 comments     jwage

February 28th, 2011 

This morning I got an e-mail from someone asking for some pointers on how to build a successul open source project. It’s a difficult question to answer. In the end I think it comes down to a lot of things, but mainly it is being consistent and active. I responded to him with some of my thoughts and when I was done I practically had a blog post so I decided flesh it out a little more and post it here.

Identity

First, it is extremely important for your project to have a name and an identity. Just pick a word, anything, something is better than nothing. Then pick some colors and slice up a logo in Photoshop.

Source Control

You must use some kind of source control. I recommend using GitHub as it will help to build the community around your project and generate contributions.

Mailing Lists & IRC

Next, setup a mailing list using Google Groups and create an IRC channel on the irc.freenode.net network. Now you have a way to communicate with your users and contributors!

Setup a Website

Once you have your identity, your code publicly available and a way to communicate with your users you need a website to organize all the information about your project. I recommend a blog, documentation, information about your community, how to contribute, how to download your code, release/download information, etc.

Social Networking

I think leveraging social networking is also a big part of connecting with your users. Create a Twitter account for your project and announce updates there. When you are developing and working on your project, be sure to let your users know what you are up to. Be active and passionate about what you do and your users will more likely connect with you and help contribute to building a great open source project.

Release Early and Release Often

In the early days of an open source project you need to release early and release often. The project is new, and the users know that so the project needs to show that it is active and moving fast in order for developers to consider using your project. As your project matures, and you have stable versions users can rely on, then you can consider throttling down the frequency of releases. Get your users new stuff fast!

Maintenance

After you have your project ground work done, you need to maintain your project and stay active. If you do not maintain your project, then it will die a slow death. Frequently write blog posts about new developments, new versions, updates to documentation, use cases and example tutorials, etc. This will get your users coming back to your site and seeing the new stuff you are working on and will be more likely to use and or contribute to your library.

I hope this helps someone with getting a new open source project off the ground or sparks someones interest to open source something today!

Posted in: Open Source, PHP

Tags: oss, php, software

Changing Jobs

 7 comments     jwage

October 28th, 2010 

For the last two years I have worked full-time for Sensio Labs and it has been an awesome experience to get to work with the lead developer of The Symfony Project, Fabien Potencier. Working with the Doctrine team we accomplished many things, three major Doctrine 1 releases, integration with several popular development frameworks such as Symfony, a published and printed guide to Doctrine, the expansion of the Doctrine umbrella to many different projects including the new Doctrine2 ORM, MongoDB and CouchDB ODM. I’ve gotten the chance to travel to several different countries and talk about Doctrine and Symfony. I definitely feel very lucky. I have Fabien to thank for everything as he dedicates his time and money to open source and I don’t think most people really truly understand and appreciate what he gives.

What is next?

On November 1st I start a new full-time job with OpenSky where they use Symfony2, Doctrine2 MongoDB ODM and ORM in production! I am excited to help build and improve the business but also to continue building great open source tools along the way. It is a good opportunity to help really improve Symfony2 and Doctrine2 by having first hand experience building a large product with it. I look forward to the next few years and what evolves both on the business side and in the PHP open source world!

Posted in: Uncategorized

Tags: job

Blending the Doctrine ORM and MongoDB ODM

 11 comments     jwage

August 25th, 2010 

Since the start of the Doctrine MongoDB Object Document Mapper project people have asked how it can be integrated with the ORM. This blog post demonstrates how you can integrate the two transparently, maintaining a clean domain model.

This example will have a Product that is stored in MongoDB and the Order stored in a MySQL database.

Defining our Document and Entity

First lets define our Product document:

<?php

namespace Documents;

/** @Document */
class Product
{
    /** @Id */
    private $id;

    /** @String */
    private $title;

    public function getId()
    {
        return $this->id;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
    }
}

Next create the Order entity that has a $product and $productId property linking it to the Product that is stored with MongoDB:

<?php

namespace Entities;

use Documents\Product;

/**
 * @Entity
 * @Table(name="orders")
 * @HasLifecycleCallbacks
 */
class Order
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @Column(type="string")
     */
    private $productId;

    /**
     * @var Documents\Product
     */
    private $product;

    public function getId()
    {
        return $this->id;
    }

    public function getProductId()
    {
        return $this->productId;
    }

    public function setProduct(Product $product)
    {
        $this->productId = $product->getId();
        $this->product = $product;
    }

    public function getProduct()
    {
        return $this->product;
    }
}

Event Subscriber

Now we need to setup an event subscriber that will set the $product property of all Order instances to a reference to the document product so it can be lazily loaded when it is accessed the first time. So first register a new event subscriber:

<?php

$eventManager = $em->getEventManager();
$eventManager->addEventListener(
    array(\Doctrine\ORM\Events::postLoad), new MyEventSubscriber($dm)
);

So now we need to define a class named MyEventSubscriber and pass a dependency to the DocumentManager. It will have a postLoad() method that sets the product document reference:

<?php

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\Event\LifecycleEventArgs;

class MyEventSubscriber
{
    public function __construct(DocumentManager $dm)
    {
        $this->dm = $dm;
    }

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        $order = $eventArgs->getEntity();
        $em = $eventArgs->getEntityManager();
        $productReflProp = $em->getClassMetadata('Entities\Order')
            ->reflClass->getProperty('product');
        $productReflProp->setAccessible(true);
        $productReflProp->setValue(
            $order, $this->dm->getReference('Documents\Product', $order->getProductId())
        );
    }
}

The postLoad method will be invoked after an ORM entity is loaded from the database. This allows us to use the DocumentManager to set the $product property with a reference to the Product document with the product id we previously stored.

First create a new Product:

<?php

$product = new \Documents\Product();
$product->setTitle('Test Product');
$dm->persist($product);
$dm->flush();

Now create a new Order and link it to a Product in MySQL:

<?php

$order = new \Entities\Order();
$order->setProduct($product);
$em->persist($order);
$em->flush();

Later we can retrieve the entity and lazily load the reference to the document in MongoDB:

<?php

$order = $em->find('Order', $order->getId());

// Instance of an uninitialized product proxy
$product = $order->getProduct();

// Initializes proxy and queries the database
echo "Order Title: " . $product->getTitle();

If you were to print the $order you would see that we got back regular PHP objects:

<?php

print_r($order);

The above would output the following:

Order Object
(
    [id:Entities\Order:private] => 53
    [productId:Entities\Order:private] => 4c74a1868ead0ed7a9000000
    [product:Entities\Order:private] => Proxies\DocumentsProductProxy Object
        (
            [__isInitialized__] => 1
            [id:Documents\Product:private] => 4c74a1868ead0ed7a9000000
            [title:Documents\Product:private] => Test Product
        )

)

That is it! It is not a very abstract example right now but it demonstrates how to utilize the events to do some very interesting things with the Doctrine persistence libraries! I hope that now someone will inspired to create an extension that offers an abstract solution for blending the ORM and ODM together!

Posted in: Doctrine, MongoDB, PHP

Tags: doctrine, mongodb, odm, orm, php

New Doctrine MongoDB ODM Documentation

 2 comments     jwage

August 19th, 2010 

Yesterday I added a few new chapters to the Doctrine MongoDB ODM Documentation:

  • Capped Collections
  • Indexes
  • Geospatial Queries
  • Storing Trees/Hierarchical Data

I hope it is helpful to someone!

Posted in: MongoDB, Open Source, PHP

Tags: doctrine, mongodb, odm, php

Doctrine Annotations Library

 3 comments     jwage

August 2nd, 2010 

The Doctrine Annotations library was born from a need in the Doctrine2 ORM to allow the mapping information to be specified inside the doc-blocks of classes, properties and methods. The library is independent and can be used in your own libraries to implement doc block annotations.

Setup and Configuration

To use the annotations library is simple, you just need to create a new AnnotationReader instance:

<?php

$reader = new \Doctrine\Common\Annotations\AnnotationReader();

Usage

Using the library API is simple. Imagine you had some annotation classes that looked like the following:

<?php

namespace MyCompany\Annotations;

class Foo extends \Doctrine\Common\Annotations\Annotation
{
    public $bar;
}

class Bar extends \Doctrine\Common\Annotations\Annotation
{
    public $foo;
}

Now to use the annotations you would just need to do the following:

<?php

/**
 * @MyCompany\Annotations\Foo(bar="test")
 * @MyCompany\Annotations\Bar(foo="test")
 */
class User
{
}

Now we can write a script to get the annotations above:

<?php

$reflClass = new ReflectionClass('User');
$classAnnotations = $reader->getClassAnnotations($reflClass);
echo $classAnnotations['MyCompany\Annotations\Foo']->bar; // prints foo
echo $classAnnotations['MyCompany\Annotations\Foo']->foo; // prints bar

You have a complete API for retrieving annotation class instances from a class, property or method docblock:

  • getClassAnnotations(ReflectionClass $class)
  • getClassAnnotation(ReflectionClass $class, $annotation)
  • getPropertyAnnotations(ReflectionProperty $property)
  • getPropertyAnnotation(ReflectionProperty $property, $annotation)
  • getMethodAnnotations(ReflectionMethod $method)
  • getMethodAnnotation(ReflectionMethod $method, $annotation)

Read the full documentation to learn more about how to use the Doctrine annotations library!

Posted in: Doctrine, PHP, Uncategorized

Tags: annotations, doctrine, php

See old posts
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.