3. 3
Introduction
Version5representsanevolutionaryleapforthe InfoPay system. Engineered fromthe groundup for
stability,maintainability,extensibility,andscalability,the systemwillhelppropel businessgrowthfor
yearsto come.
In orderto make thisa reality,itisessential thatcode be clean,efficient,maintainable,andeasyfor
otherdeveloperstoread,understand,andmodify. Tohelpensure this,anumberof standardsand
practicesneedtobe followed.
Thismanual servesasyou guide tothe principles,practices,methods,andproceduresthatgovernthe
developmentof IP5. It alsoprovidesanintroductiontothe available toolsand codebase layouttohelp
youhit the groundrunning.
Tools
NetBeans
NetBeansisthe preferrededitorforInfoPayv5development. The IDEisfreelyavailable at
http://www.netbeans.org. While youare notrequiredtouse NetBeans,itisstronglyencouragedandis
the onlyeditorthatwe can officiallysupport.
Whencreatinga newprojectinNetBeans,be sure tocheck the “Put NetBeansmetadataintoaseparate
directory”checkbox onthe secondstepandensure thatthe “SourcesFolder”issetto the “source”
subdirectoryof the “MetadataFolder”. Thiswill keepyourNetBeansprojectfilesoutof versioncontrol.
A videoshowingthe stepsinvolved isavailableathttp:// REDACTED. Be sure to finishreadingthe
manual for the correct repositorylocations,etc.,astheymayhave changedsince the videowascreated.
Make sure that whenyousetup the uploadlocation,youchoose touploadmanually(notonsave). The
“dev”path for SFTPuploadsis“REDACTED”.
Note that the defaulteditorformattingsettingsinNetBeansdonotcomplywiththe codingstandards
listedinthisdocument. Youwill needtoensure thatNetBeansisproperlyconfiguredsothatit doesnot
replace tabswithspaces,placesbracketscorrectly,etc. The CodingStandards sectiondetailsthe proper
conventions.
ActiveCollab
The main projectmanagementtool forthe InfoPayv5projectis ActiveCollab. All taskswill be assigned
and monitoredin AC,soit’sessential thatall developersmake optimumuse of thisresource.
Tasks are createdby management withthe label “DRAFT”. Taskslabeledasdraftsare notfinalized,and
shouldnotbe started. Once the detailsare finalized,managementwill assignthe tasktoa developer
and change the label to“ASSIGNED”.
Once a storyisassignedtoyou withthe label “ASSIGNED”,youare free tostart work onthat task as
soonas your previous tasksare completed. Whenyou startwork on a story, change the label to
4. 4
“INPROGRESS”. Once you’ve finished ataskand committed/pushedyourcode,change the label to
“DELIVERED” and add a commentindicatingwhichGitbranchcontainsyourworkon the task. A
managerwill thenreview yourworkandeitherapprove it,orrejectitwithcommentsindicatingwhat
needstobe changed.
If you needtomake additional changesaftera task hasbeensubmittedbuthasn’tbeenreviewedyet,
please adda note to the task,indicatingwhatchangesyoufeel youneedtomake,andthenwaitfora
response. Pleasedonotmake furtherchangesafterdeliveringa task withoutcheckingfirst,as amerge
for deploymentmayalreadybe inprogress.
Whenone of yourtasks isrejected, don’tbe discouraged. Itmaymeanthat there were some problems
inthe code that needtobe addressed,orit mayjustmean thatthe task’screatorforgot something,and
needsyoutotake care of the oversight. Eitherway,readthe comments, change the label backto
“INPROGRESS”, andstart the processagain.
Git
The main codebase forInfoPayisstoredinthe IP5Git repositorylocatedatssh://REDACTED. When
accessingthe repositories,you’ll alwaysuse the username “REDACTED”. All developersshould maintain
local copiesof the repositoryonwhichtowork.
The Git workflowisasfollows:
1. Clone the repositoryintothe “sources”folderof yourproject. Thiscreatesa full local
repository,aswell asa workingcopyof HEAD. To clone inNetBeans:
a. Create yourprojectfirst,andensure the sourcesfolderisempty(delete the “index.php”
file thatNetBeanscreatesautomatically).
b. From the menubar,select“Team” -> “Git” -> “Clone”
c. Enter the properrepositoryaddressforthe projectyou’re cloning,specifyingthe
username “git”andyour Git private key,thenclick“Next”.
d. Selectall remote branches andclick“Next”.
e. For the “ParentDirectory”,choose yourprojectdirectory. Forthe “Clone Name”type
“source”. This will clone the repositoryintothe source directoryof yourproject. Ensure
you’re checkingout“master*”withremote name “origin”. Uncheckthe “Scan for
NetBeansProjectsafterClone”box –you’ve alreadycreatedyourproject,andthe
repositorydoesn’tcontainprojectfiles. Finally,click “Next”andthe repositorywill be
cloned.
f. A videoshowingthe stepsforthe mainprojectisavailableat http:// REDACTED
2. All developmentworkwill be done onbranches,keeping“master”cleanfordeploymenttothe
live servers. Workforeachtask will be committedtoitsownbranch. To create a new branch
(whenatask doesn’talreadyhave abranch),right-clickthe project’s“Source Files”node and
choose “Git” -> “Branch” -> “Create Branch”. Give the branch a name appropriate tothe task
you’re working on,usinguppercamel-case. Ensure that“Revision”is“master”and click
“Create”. Once the branchis created,youcan switchto itby right-clickingthe project’s“Source
5. 5
Files”node andselecting“Git”-> “Branch” -> “SwitchTo Branch”. Choose the branchyou want
to switchto,make sure that“Checkoutas New Branch” isNOT selected,andclick“Switch”. Any
commitsyoumake will nowbe onthe selectedbranch. A videoshowingthe stepstocreate and
switchto a branch isavailable at http:// REDACTED
3. To commitin NetBeans,right-clickthe project’s“Source Files”node,andchoose “Git” ->
“Commit”. Provide adescriptive commitmessage indicatingwhatyouworkedon. Make sure
that Authorand Committerare bothsetto “Firstname Lastname <youremail@example.com>"
(withoutthe quotes,of course). The email addressshouldbe the emailaddressyouuse for
work – youraccucomcorp.com email addressif youhave one,orthe email addressyougenerally
use for work-relatedcommunicationotherwise. Clickthe “Commit”buttontomake the
commit. Video: http:// REDACTED.
4. CommitsinGit are to your local repository –you needtodo a remote pushto origintoupload
your commitstothe central repository. Todo thisin NetBeans:
a. Right-clickthe project’s“Source Files”node andselect“Git”-> “Remote”-> “Push”.
b. Selectthe preconfiguredoriginremote (thiswillbe the locationfromwhichyoucloned
the project) andclick“Next”.
c. For local branches,choose the branchesyou’ve workedon. Make sure thatyou don’t
selectmaster– thiswill cause yourpushto fail,asmasteris a protectedbranch.
d. On the final screen, ensure the branchesyou’ve workedonare selected andclick
“Finish”. Yourcommitswill be pushedtothe central repository.
e. Video: http://REDACTED
5. To update yourlocal repositoryfromthe central repositoryandmerge changes,doa pull from
origin.
a. Right-clickthe project’s“Source Files”node andselect“Git” -> “Remote”-> “Pull”.
b. Selectthe preconfiguredoriginremote (thiswillbe the locationfromwhichyoucloned
the project) andclick“Next”.
c. Choose all remote branches andclick“Finish”. All commitsmade onthe central
repositorywill be pulledintoyourlocal repository,andyourworkingcopywill be
updatedtowiththe latestchanges.
d. Video: http:// REDACTED
There are a couple importantprinciplesconcerningoptimaluse of Git:
1. Pull frequently –at leastonce perday. Thisensuresthatyou’re alwaysworkingonthe most
recentcode versionandreducesyourchancesof creatingconflicts.
2. CommitandPush regularly. Ingeneral,youshouldcommiteverytimeyoucompleteatask,and
at the endof everyday. Pushaftereach commit,sothat your changesare reflectedinthe
central repository.
3. It’salwaysa good ideatopull rightbefore a push. Thiswill ensure that youhave anychanges
made by otherdevelopersmergedintoyourworkingcopybefore committing. Thisgreatly
reducesthe changesof encounteringconflicts.
7. 7
Step4: Copythe entire contentsof the toptextarea, and email to brent@accucomcorp.com. Thisis
your publickey,whichwillbe uploadedtothe server.
Step5: Choose a passphrase andsave your private keyinPuTTY keyformat. Your private keymust
remaina secret,andmust neverbe sharedwithanyone.
Step6: Exportyour private key inthe formatrequiredbyNetBeans. Thiswillletyouuploadtoand
downloadfromthe serverfromwithinNetBeans.
Each developerwill need2separate SSHkeys – one forSFTP uploadtothe devserver,andone forGit
access. Please be sure toname yourprivate keysinsucha waythat you’ll be able totell whichiswhich.
Please donotgive the keysambiguousnameslike1and 2. Use “sftp” inthe name of one,and “git”in
8. 8
the name of the other. Email the publickeyforSFTP to brent@accucomcorp.com. You’ll uploadyour
Git publickeydirectlythroughGitLab.
Task Scopes
Whenworkingonthe InfoPayv5 system, itiscritical to rememberthatseveral otherdevelopersare
workingonthe same codebase,andthat one developer’staskmaydependonthe completionof
anotherdeveloper’stasks. Because of this,itisvitallyimportantthatall developersrespectthe scope of
assignedtasks,andnotmake changesto otherparts of the systemwithoutpriorapproval.
Changesmade outside the scope of anassignedtaskhave the potential tomake other,establishedparts
of the systemunusable,andmayunnecessarilyinterfere withthe workof others. Theyalsonegatively
impactthe timeline of atask,whichmay delayother developerswhoare waitingfor the completionof
that task.
If you needa change that isoutside the immediate scope of yourassignedtask,addacommentto the
storyexplainingthe change youneedandwhyyouneedit. While awaitingaresponse,youshould
alwaysattempttocontinue workingonthe taskas much as possible.
Credentials and Access Controls
Authentication credentials,includingusernames,passwords,SSHkeys,authtokens,etc.are assignedto
an individualperson,andmust neverbe sharedwithothers. Anyattempttosubvertaccesscontrols,
includinguse of anotherperson’scredentials,isconsideredunauthorizedaccesstothe system,whichis
strictlyforbidden.
Please use commonsense withthe machineyou’re usingfordevelopment,since it hasaccessto our
core systems. Whenyouwalkawayfromthe computer,lockit sothat access isn’tavailable toanyone
walkingpast. For windowscomputers,holdingthe WindowskeyandhittingLwill lockthe computer–
everythingwill keeprunning,but apasswordwill be requiredtouse the system.
Coding Standards
In orderto ensure efficiencyandeasymaintenance,it’sessential thatall developersadhere toa
commonsetof codingstandards. The standardsdescribedinthissectionare intendedtocreate a
commongroundso that all developerscaneasilyreadeachother’s code,andto avoidcertain
inefficiencies.
PHP
Comments
Commentsmustbe usedtodocumentall code. It shouldbe possible todeterminehow andwhyall
code functionsbasedsolelyonthe code itself andthe commentsitcontains. PhpDocumentor
9. 9
(http://www.phpdoc.org/docs/latest/index.html) style commentsmustbe usedtodocument every
function,method,property,andclass.
Each file’sdocblockshouldcontainatleastone @authorannotation,indicatingthe personwho
originallycreatedthe file. Whenyouupdate afile thatsomeone else hasworkedon,addanew author
annotationwithyourowninfo. Authorannotationsshouldhave the same formatasGitauthor /
committerlines.
For commentsthatare not intendedforphpDocumentor,suchasthose documentingcode withina
function,startthe commentwithslashes(notahashsymbol) thenaspace,thenthe properlycapitalized
comment. UsingproperEnglishmakescommentsmuchmore helpfultoothers.
Commentsmustnotbe usedto store unusedcode. Whencode is nolongerneededitshouldbe
removedcompletely. Since all code isstoredin Git,itis possible torecovercode thathasbeenremoved
if it isneededagaininthe future.
ErrorsandExceptions
Errors and exceptionsshouldneverbe displayedtothe enduserinraw form. Raw messagesmustbe
properlyloggedforlaterreview. If anerror conditionpreventsnormal operationof a page,a user-
friendlyerrormessage shouldbe displayed. Thismessage shouldgivethe userbasicinformationabout
whetherornot theyshouldretrythe operation,but mustnotreveal anypotentiallysensitive
information.
FilePaths
Avoidusingfull file systempathswhenreferencinglocal filesfromPHP. These wouldbe difficultto
trace and update incase the projectisredeployedtoadifferentfile systempath.
It isalso importanttonote that, whenaparticularfile isexecuted,the currentworking directorymay
not be the directorycontainingthatfile.
The bestpractice forbuildingfilepathsistouse the magic constant__DIR__, whichwill give the
directorycontainingthe currentfile.
Note that all filestowhichPHPmustwrite needtobe placedinthe application’sruntime directory
(./runtime),whichcanbe retrievedfromwithinthe applicationbyusing:
Yii::app()->runtimePath;
PHP scriptscannotwrite withinthe applicationdirectory orthe webroot.
NamingConventions
All identifiersshould have intuitive namesthatreflecttheircontentandpurpose. Please checkyour
spellingof identifiers –misspellinganidentifiername isasure way to create bugslaterwhensomeone
else accidentlyusesthe correctspelling. Identifiernames mustfollow the followingconventions:
Constants,includingclassconstants,mustbe inall capitals(e.g.“ENCRYPTION_KEY”).
10. 10
ClassNamesmustuse camel case withthe firstlettercapitalized(e.g.“EmailSearch”).
Variable,property,function,andmethodnamesmust use camel case withthe firstletterlower-
cased(e.g.“$orderTotal”,“getCustomerEmail()”).
CodeStyle
Indentsmustuse tabs,neverspaces. Make sure you setthisproperlyinyoureditor/ IDE,as
many (NetBeansandNotepad++,inparticular) will expand tabstospacesautomatically unless
youset themnotto. All code shouldbe indentedinBSD-Allman
(http://en.wikipedia.org/wiki/Indent_style#Allman_style) style.
The openingbracketforcode blocksmust alwaysbe onits ownline,indentedtothe same level
as the functiondefinition,conditionalexpression,etc.
All control structuresmustbe implementedinstandardsyntax (usingbracketstosurroundthe
code block) NOTthe alternate syntax describedathttp://php.net/manual/en/control-
structures.alternative-syntax.php.
Conditional code blocksmustalwaysuse brackets,as described above,even if onlyone line.
Conditional code mustneverbe placedonthe line withitsconditional expression,oronthe line
below(whichmustcontainthe properlyindentedbracketandnothingelse).
Booleanvaluesandthe null value mustbe typedinall capital letters(i.e.TRUE,FALSE,and
NULL).
Blanklinesshouldbe usedwhere theyincreasereadability(e.g.betweenseparatelogical
blocks),butshouldnotbe usedexcessively. One blankline issufficienttodistinguishbetween
logical code blocks – don’tuse more.
Stringsshouldbe enclosedbysingle-quotesunlessusinginline variableinterpolationorescape
sequences. Stringliteralsmust neverbe leftbare (unquoted).
Binaryoperators(e.g.“==”, “>”, “=”, etc.) shouldhave a space to each side,separatingthe
operatorfromthe operands.
Unary operators(like “!”or “++”) shouldhave nospace betweenoperatorandoperand.
Logical operatorsmustuse the symbolicform(“&&”or “||”),not the textual form(“AND”,
“OR”). Note thatthese operatorshave differentprecedence andwill behave differentlyin
certainedge cases.
Functionargumentsmusthave a space followingthe commaseparator. Nootherspacesmay
appearwithinthe parentheses,exceptinsidestrings.
CodeLibraries
Code librariesfoundonthe internetcanprovide usefulfunctionswhichcansave time andeffort.
However,theycanalsointroduce securityvulnerabilities andcreate dependenciesoncode thatis
difficulttomaintain. Because of thisdouble-edgedsword,all code foundonthe internetmustbe
reviewedandapprovedbymanagementbefore inclusionintothe projectcode base. Unapproved
librarieswillnotbe mergedfordeployment,and taskscompletedusingunapprovedlibrarieswill notbe
accepted.
11. 11
JavaScript
CodeStyle
JavaScriptmustuse the same code style asPHP,exceptwhere the nature of the language mandates
differences. Asan additional exception,the openingcurlybracketinJavaScriptmaybe placedon the
same line asthe conditional expressionorfunctionsignature –thisis justJavaScriptdogma,andthere’s
no pointfightingit.
CodeLibraries
As withcode librariesforPHP,all JavaScriptcode librariesmustbe reviewedandapprovedby
managementbefore inclusioninthe project’scodebase.
The jQueryand jQueryUI libraries are pre-approved,andmaybe usedon anypage. Please use the
Google CDN URLs for these libraries(see
https://developers.google.com/speed/libraries/devguide#jquery) ratherthanservingthemdirectlyfrom
our servers.
Markup
All markup returnedtothe browsermustbe well-formed,validXHTML1.1, includingXMLdeclaration
and doctype,andmustpass validationagainstthisstandard,asdeterminedbythe W3C markup
validationservice at http://validator.w3.org.
Codebase Layout
There are two importanttop-level foldersinthe IP5codebase. The core applicationisstoredinthe
“app” folder,andthe frontendcode andstaticfilesare storedinthe “www”folder.
Core
The core applicationfilesconsistof REDACTED.
Classesinthe REDACTED and REDACTED namespacesare designedtobe separable fromthe restof the
application,andshouldhave nodependenciesoutside of those namespaces,exceptforstandardPHP
extensions.
Classesthatare tightlyintegratedintothe systemandcannotbe readilyseparatedforreuse are placed
inthe REDACTED namespace.
Testcases are placedinthe REDACTED namespace. Unittestsgo under REDACTED while functional
testsgo underREDACTED.
The placementof modelsandcontrollersisdiscussedinthe sectionon Yii,while the placementof views
iscoveredin the sectiononthe Frontend.
Frontend
The frontendfilesconsistof REDACTED.
12. 12
REDACTED
Staticfiles(e.g.images,JavaScript,andCSS) shouldbe placedinlogically-nameddirectoriesinthe
frontendfile structure. Resourcesthatare specifictoa givensite shouldbe placedunderasubdirectory
namedforthat merchant,while global resourcesshouldbe placesindirectoriesnamedforthe type of
resource (e.g.“img”,“js”,or “css”).
Yii
Basics
Yii (http://www.yiiframework.com) providesthe MVCframeworkusedbythe IP5application. The
Definitive GuidetoYii (http://www.yiiframework.com/doc/guide/1.1/en/)providesagoodintroduction
to the basicsof Yii,butbe aware that we’re using the framework inasomewhatunusual manner,so
manyof Yii’sconventionsdon’tapplytothisproject.
File Locations
One aspectwhere ourimplementationdiffersfromYii’sdocumentationisthe locationof files. In
particular,configuration,controller,model,andview filesare notplacedinthe prescribedlocations.
REDACTED.
Models and Repositories
Anotherdeviation isouruse of “repository”classestoretrieve datafromthe database. InYii’sstandard
active recordimplementation,asingle modelclassisusedforbothretrievingandmanipulatingrecords
inthe database. Inour implementation,modelsare usedtomanipulateindividual records,while
correspondingrepositoryclasses REDACTEDare usedto retrieve existingrecordsfromthe database. All
record retrieval logicmustbe keptwithinthe appropriate repositoryclasses,toensure easyupdating
whenchanges are made to the database.
The ODM layerpersistsall publicpropertiesof amodel tothe database onsave,and populatesthose
same propertiesonretrieval. Private propertiesmaybe usedinmodels,butthese will notbe persisted
to the database.
Before makinganychangesor additionstothe documentmodels,email brent@accucomcorp.com and
CC REDACTED witha linkto the task you’re workingon,anda descriptionof the changesyoufeel are
needed. Afterreviewingyourrequest,we’llprovideguidanceonhow toproceed. Thisway we can
ensure thatwe maintainanoptimal database structure,includingall necessaryindexes,shardkeys,etc.
Full documentationonthe ODMlayerisavailable at
http://canni.github.com/YiiMongoDbSuite/xhtml_single/index.html.
Controllers and Actions
As statedpreviously,controllersare placedinthe namespace REDACTED. Because of thisnonstandard
placement,controllersmustbe mappedtoURL pathsin REDACTED.
13. 13
Controlleractions(http://www.yiiframework.com/doc/guide/1.1/en/basics.controller#action) are
implementedasdiscrete classes,ratherthanmethodswithinthe controller. Actionsforagiven
controllerare placedinthe namespace REDACTED,where CONTROLLERNAMEisthe (unqualified) class
name of the controller. Again,this isanonstandardplacementwhichrequiresspecial treatment. Each
controllermusthave a method“actions()”whichreturnsanassociativearray. The array keysmustbe
the controller-relative URLpathsusedto accessthe actions,and the valuesmustbe the fully-qualified
classnamesof the actionimplementations. Note thatexistingcontrollersuse anarray of action names
whichisusedinboth the actions() method,andforapplyingaccesscontrol filters.
Widgets
Widgetsare componentsthatare primarily forpresentation,butwhichcancontain some programming
logic. They are createdbythe Engineeringteamtoprovide presentational logicthatthe UI team can use
increatingviews.
Widgetsare placedin REDACTED and extend REDACTED. Widgetclassesthemselvesare not
namespaced. Thisistokeepthe usage syntax forthe UI teamas simple aspossible.
Defaultwidgetviewsshouldbe placedinFrontendunderthe folder REDACTEDwhere WIDGETNAMEis
the class name of the widget. If a specificmerchanttheme needstooverride the defaultview fora
widget,the theme-specificviewshouldbe placedin REDACTED.