How to Auto Create Issues in Jira From PHP

February 4th, 2011

Good morning again everyone, in an effort to always increase productivity and reduce friction I have a new weapon in my workflow arsenal. To gain some context regarding this post here is some background. We use Jira at Gravity for tracking issues and bugs. Since I'm not always on VPN or have access to our network managing my todos has been cumbersome. I've tried every Todo app out there and always fail to use them for more than 2 days.

I finally saw a great article on just using a simple Todo.txt file in your Dropbox folder and working from that. It's been a dream and working out great. I can use all my fav shell commands and have amazing Quicksilver integration that I'll show in a little video soon.

Anyway, the final joy was to be able to have a cron job run every hour and automatically create jira issues from my todo file for any item that has a tag. That helps me sync with Jira when I want others to know what I have on my plate at the moment. My script that calls this PHP file strips out the tag after it creates the issue

Here is a typical sample of my todo list

read the full entry on the new blog site JimPlush.com

http://jimplush.com/blog/article/176/How-to-Auto-Create-Issues-in-Jira-From-PHP


DailySrc.com released to showcase article extraction

January 9th, 2011

This week I was happy to get up a little project called http://dailysrc.com which shows you the 20 most viral sports articles right now. It used a combination of technologies behind the scenes but it relies on the newly released Goose Article Extractor from http://gravity.com Labs. It's formatted for the iPhone and iPad as well so you can get a quick digest of what's happening in the sporting world right now. Goose is available on GitHub at: https://github.com/jiminoc/goose


Goose - Article Extractor now open source, same as Flipboard/Instapaper

December 21st, 2010

Today I'm releasing a project I worked on for http://gravity.com. It's an HTML Article Extractor ala Flipboard / Instapaper style. It will take an article, run some calculations on it and give you an Article object back with the text of the extracted Article as well as the main image that we think is relevant to the article.

https://github.com/jiminoc/goose/wiki

The goal is to create an open source article extractor for use with open source applications, crawlers or academic NLP processing initiatives.

see more at the new blog: http://jimplush.com

Fix when compiling the Redis php extension on OSX - mach-o, but wrong architecture

September 13th, 2010

If you happen to get the error:


PHP Warning: PHP Startup: Unable to load dynamic library '/Users/jim/Downloads/owlient-phpredis-2675d15/modules/redis.so' - dlopen(/Users/jim/Downloads/owlient-phpredis-2675d15/modules/redis.so, 9): no suitable image found. Did find:
/Users/jim/Downloads/owlient-phpredis-2675d15/modules/redis.so: mach-o, but wrong architecture in Unknown on line 0

this is how I fixed it:

create a test.sh file anywhere, chmod 777 it, run it then do your normal


make clean
phpize
./configure
make
sudo make install


SCRIPT:


#!/bin/bash
MACOSX_DEPLOYMENT_TARGET=10.6
CFLAGS="-arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp"
CCFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
CXXFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
LDFLAGS="-arch i386 -arch x86_64 -bind_at_load"
export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET

If Zend Form was a girl I'd marry it

July 31st, 2009

So a few months ago I took the leap and spent some time getting down and dirty with Zend_Form. The elements, decorators, display sub groups, validations, filtering, etc...
In our new project we are now creating a single form class and are able to use that for our edit form, creation form and also a method for "read only" that will just display the contents properly all using the same form code. We have custom validators plugging into the elements. It's just a beautiful thing. Once you get the hang of it whipping out quality forms is a snap.

Nice job Framework devs

I'll be speaking at ZendCon 2009

July 29th, 2009

I'm currently set to speak at ZendCon 2009 on the topic of "How to run an enterprise PHP Shop" (http://zendcon.com/)

I'd love to see what people may be most interested in talking about. I've be a lead developer at McAfee and Panasonic, two large, very different corporations.

Here's what my blurb on the Zend site says:

"How to run an enterprise PHP Shop

Speaker: Jim Plush

In this session we'll take a look at how to successfully manage and lead PHP teams. We'll cover finding and interviewing PHP developers, the processes involved with producing products (build, qa, release, continuous integration, and development processes), building the team, team standards (coding, documentation, unit testing, reviews), providing ongoing education, and preventing developer burn out. We will also touch on the balacing act between process and productivity.

22.10.2009 | 09:15 bis 10:15 Uhr "


I'm currently working on the outline for the talk. It's only an hour and I have a lot to cover so if there's anything you want me to focus on just drop me a comment. Here is my super rough outline so far:

How to find, interview and hire PHP developers
How to manage teams
Coding Standards
Testing standards
Build Processes
Release Processes
Bug reporting and mitigation processes (bug scrub meetings with steering team)
Requirements gathering
Deploying Code
Training the team
Unit Testing
Continuous Integration Servers
System Testing
Weekly team meetings
Pre-release Bug Parties, prizes for most show stoppers, most bugs found
Tools we use at Panasonic (svn, why not to use telelogic change, phing, phpunit, zend framework, twiki wiki)
Team Building
Importance of certifications
Importance of the balance between process and performance
Wikis for collaboration
Why we chose Zend Framework



Rethinking Zend Models Part 4 - Create new user

July 22nd, 2009

I've gone ahead and added the createuserAction to my indexController to illustrate how we could reuse all the code previously written to validate and save creating a new user. If you want to view the change log to see the code I added to support this, you can view it here: http://code.google.com/p/plushcode/source/detail?r=23


Here's what our createuserAction code looks like now


  1.  
  2. public function createuserAction()
  3. {
  4. // we're going to be creating a user
  5. $userRepo = new user_UserRepository();
  6. $user = $userRepo->getNewUser();
  7. // pass the form the validator it needs to work with
  8. $form = new forms_CreateUserForm(array('Validator' => new user_validation_Default($user)));
  9.  
  10. // find a user with id 1 in the DB
  11. if ($this->getRequest()->isPost()) {
  12. if($form->isValid($_POST)) {
  13. $values = $form->getValues();
  14.  
  15. // let's update the user's email address to what was posted from the form
  16. $user->setEmailAddress($values['email']);
  17. // update the profile's nickname
  18. $user->Profile->setNickname($values['nickname']);
  19. // check to make sure the whole user object is valid with these new changes
  20. if(!$user->isValid()) {
  21. $this->view->errors = $user->getMessages();
  22. } else {
  23. $userRepo->save($user);
  24. $this->view->message = "USER CREATED!";
  25. }
  26. }
  27. }
  28. $this->view->form = $form;
  29. }
  30.  


Rethinking Zend Models Part 3 - Validation

July 21st, 2009

I've gone ahead and added validation to our test project: http://code.google.com/p/plushcode/source/browse/#svn/trunk/ZendModel/application/default/models
If you take a look at the indexController you'll now see I've added an updateAction that uses a Zend Form component.

The goal of the validation was to provide context sensitive validation on a model. A model by itself might not know if it's valid or not so you'll want to apply different contexts depending on what the client operation is. Saving an order might have a different validation need than shipping an order. Instead of hacking a bunch of if/else statements you can simple say

  1.  
  2. $order->setValidator(new order_validation_NewOrder());
  3.  
  4. // OR
  5.  
  6. $order->setValidator(new order_validation_ShipOrder());
  7.  
  8. if(!$order->isValid()) {
  9. $messages = $order->getMessages();
  10. }



and $order->isValid() will operate on that context object. The form object get's pass a validator so it can also operate on the same validator chains as the model so you don't have to duplicate that logic.

Anyway, I think it can be improved so take a look!
If you've downloaded and installed the code you'll be able to find the example on your local machine: http://youraddress/index/update


Followup on rethinking Zend Models with DDD - Framework code included

July 16th, 2009

As a follow up to my previous post I'm going to post some live examples of model layer with Zend framework based on Domain Driven Design concepts. I've spent the past few days studying up on domain driven design as well as a lot of Martin Fowler's work in relation to domain modeling and I think I have at least some code to start with that could get some conversations rolling. The issue is Zend Framework doesn't have a formal model layer and it shouldn't. Models are very much domain specific to what you're working on. As I've mentioned in my previous post sometimes you need complex business logic that will need to rapidly change and adapt to growing business needs. Active record can only get you so far when complexity expands.

I've posted a working Zend Framework project that has a basic working set of models so far. The current concept has a User who in turn owns a profile object. That profile object holds a nickname attribute that we can play around with. I have two tables users and profiles that are joined with a foreign key (user_id). Normally when you want profile information you'd just do a join and work with the result. What if that profile becomes context sensitive? What if a user can have a different profile based on the location he's in? Maybe he's a CIA agent and if he's overseas he needs a different profile to be covert. You'd now have to start adding conditions to your logic to account for this. Having the user own a profile object that can be injected at runtime allows for these contexts to be more manageable.

What if your user is going to be used in a workflow engine, a piece of marketing business logic that operates on users, it will be nice to be able to pass around a complete User object that has well documented properties and APIs instead of forcing each business logic service to know the details of your database.

Here is the google code repository you can checkout and play around with: Google Code Repository for Zend Model project
It's all working, just create a database and dump in the zendmodel_DB.sql file, change your config.ini file settings and you're all set assuming you handle your apache settings



Take a look at the default/controllers/IndexController.php file for how the client code will be used.

  1.  
  2. // instantiate the user repository who will be in charge of building a proper user
  3. $userRepo = new user_UserRepository();
  4. // find a user with id 1 in the DB and grab their current nickname from the profile
  5. $user = $userRepo->find(1);
  6. $this->view->nickname = $user->Profile->getNickname();
  7. // set their nickname in their profile to something new
  8. $user->Profile->setNickname('tommy tom');
  9. // find the user again, it should pull the same object reference and not create a brand new object (Identity Map)
  10. $user = $userRepo->find(1);
  11. $this->view->nickname2 = $user->Profile->getNickname();
  12. // a fictional web service to check to see how popular your new nickname is
  13. $profileService = new services_ProfileService();
  14. $popularity = $profileService->howCommonIsMyNickname($user);
  15. $this->view->popularity = $popularity;
  16. // let's update the user's email address
  17. $user->setEmailAddress('newdude@yahoo.com');
  18. // you can manually commit the save to the database like this or in the destruct method of ObjectManager
  19. // it will do it automatically for you, this will save all the changes we've made to all our objects
  20. // using the unit of work pattern in ObjectManager, the profile and the user will get updated
  21. ObjectManager::performOperations();


We have a User model and we have some supporting files around it.
in models/user/ you'll see some files:
/User.php
/UserMapper.php
/UserRepository.php

Each one plays a role within the domain User.php is the model itself that models a user in our system. It contains no SQL or knowledge of the persistence layer and can be passed around to any app on ths system. UserMapper.php is our basic DB Mapper that is in charge of doing the dirty work of putting things into our database. UserRepository is the default User Factory for creating a valid User object along with it's dependencies. Because this could be context sensitive we can contain that logic in a central place in there or add another Repository.

if you look in models/infrastructure/ObjectManager.php you'll see this file is a combination identity map and unit of work. It's job is to make sure if we have already instantiated a User object for example that we get back the same exact one and don't try to recreate it. It's basically an object cache.

Anyway, take a look and let's talk about what's right and what's wrong and how we can improve the complex domain model with Zend Framework. I'd like to start building on this example with everyday issues like logging, authentication, transactions, validation, unit tests, etc...




Rethinking the Zend Models

July 14th, 2009

I'm currently in requirements mode for an upcoming project that should prove to be pretty complex. The current active record/table gateway patterns just aren't going to cut it for the complex business logic that's approaching. I'm starting to lean towards the domain model approach which would increase the initial complexity of the design but allow for the flexibility for future changes and features. The issue is with where to put your business logic? Most of the rails and Zend framework examples show a more active record type pattern which means that the business logic is tied into the persistence storage layer.

For example...
$user = new User();
$user->salary = 100;
$user->updatePayroll();
$user->save();

This works well for smaller apps where your models are tied tightly to your database structure however in my case I'll need to add the application layer above an existing database structure that may have 5 tables per object. For the example above I've diagrammed a possible solution



In this example I've created a User and Company class. Each one holds it's own data and basic operations. There is no sql in these, no direct knowledge of the outside world. Each model has a corresponding Mapper class (data mapper pattern) that knows how to save, find, create and delete it's own model. On top of those layers will sit a service layer that handles the real business logic. The UserPayrollService deals specifically with managing payroll for a user. UserAuthService is strictly for authenticating and logging out a user. As more and more complexity is added such as the need to have a User as part of a workflow engine I can simply create a new service or modify an existing one to implement the new business logic. Some additional benefits are that you can show the diagrams to your stakeholders and they can see concrete evidence that you've captured their business requirements as well as having the components testable on an individual level.

here are some examples of how it could be used...

  1.  
  2. /**
  3. * high level use case for an immediate login and update of salary
  4. */
  5.  
  6. $userAuth = new UserAuthService();
  7.  
  8. if($user = $userAuth->authorize($_request['email'], $_request['password'])) {
  9. $payroll = new UserPayrollService($user);
  10. $payroll->updateSalary(100000);
  11. $currentPay = $user->getSalary();
  12. // currentPay would now equal 100000
  13. } else {
  14. // auth fail
  15. }


  1.  
  2. /**
  3. * example of creating a new user
  4. */
  5. $userMapper = new UserMapper();
  6. if(!$userMapper->userExists($_request['email'])) {
  7. $user = new User();
  8. $user->email = $_request['email'];
  9. $user->firstName = $_request['firstName']
  10. $user->lastName = $_request['lastName']
  11. $userMapper->save($user);
  12. redirect('/home');
  13. } else {
  14. // user already exists
  15. }


Anyone have any thoughts on this implementation? What has served you well?