You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

Yii forward with params

Yii’s forward doesn’t work with passing params to actions. I.e. This doesn’t work: $this->forward(“/mycontroller/myaction/1/2”);

Because of the way urlmanager works I made the decision early on to have all action parameters take on the var names $id and $id2. So in the main config:

'components'=>array(
			// uncomment the following to enable URLs in path-format
			'urlManager'=>array(
				'urlFormat'=>'path',
				'rules'=>array(
					'<controller:\w+>/<id:\d+>'=>'<controller>/view',
					'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
					'<controller:\w+>/<action:\w+>/<id:\d+>/<id2:\d+>'=>'<controller>/<action>',
					'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
					'<controller:\w+>/<action:\w+>/<cact:\w+>'=>'<controller>/<cact>',
				),
			),

So I used Controller.php in the components directory to override the forward method like so:

	 /**
	 * Overloading CController::forward
	 * added the routeArr lines so the ids are passed
	 */
	public function forward($route,$exit=true){
		//error_log("Controller::forward");
		$routeArr = explode("/", $route);
		if(isset($routeArr[3]))
			$_GET['id'] = $routeArr[3];
		if(isset($routeArr[4]))
			$_GET['id2'] = $routeArr[4];

		parent::forward($route, $exit);

	}

And that’s it.

Posted in ATG, Quizmo, Yii. Tags: , . Comments Off on Yii forward with params »

Yii Javascript redirect: jsredirect

One of the platforms I have to develop for is iSites. This is a Harvard grown LMS that is complicated and annoying, but functional.

Since I have to develop tools that fit within this framework I have to work around its limitations. One of the simpler to understand limitations is the idea of not having control of the headers sent. Since by the time it gets to my tool, the page has already started loading, output has already been sent, so doing a redirect with PHP’s header function is impossible.

Yii has 2 ways to forward things through the controller. redirect and forward. Redirect uses header and forward doesn’t change the URL. So the best way to forward within isites is to use a js forward. I.e. document.location = “www.google.com”

So in the controller.php in components which extends CController I added a method jsredirect:
https://github.com/jazahn/Quizmo/blob/master/quizmo/protected/components/Controller.php

	protected function jsredirect($url){
		// set the redirect in a session
		Yii::app()->session['jsredirect'] = $url;

		// forward to the jsredirect action
		$this->forward('/site/jsredirect');
	}

This just sets a session var for the redirect and forwards to site/jsredirect so in SiteController.php I have

public function actionJsredirect(){
		
		if(isset(Yii::app()->session['jsredirect'])){
			$this->render('jsredirect',array(
				'url'=>Yii::app()->session['jsredirect'],
			));
		}
		
	}

And then in the jsredirect template file we have

<script>
window.location.replace("{$url}");
</script>
Posted in ATG, Javascript, PHP, Yii. Tags: , , , . Comments Off on Yii Javascript redirect: jsredirect »

Using git with svn

If you have the choice, don’t. Pick one and stick with it. My personal preference at this time is git because it facilitates smaller commits — but who cares what I prefer, you’re probably tied to a versioning system based on what someone long before you decided to use.

I for one am tied to svn for doing deploys, but since I’m gaga over git and doing things in the open, I want to use git on a day to day basis and just use svn for deploys.

This sucks, but if you’re going to do it, you shouldn’t be a douche and add your .git directory to svn. That was my first attempt, even though I knew it was bad, I wanted to see the performance hit on svn firsthand I guess.

So I have the deployment related files in svn, so git is free of any environment specific files, like database configs.

So I do all development in git with “.svn” in the .gitignore. That part is easy. Getting svn to ignore git is a little more annoying, especially if you have multiple submodules. So when you’re ready, you add everything to svn, then rm the .git files. It’s better to rm them with the –keep-local flag.

If you delete the .git files because you forgot to –keep-local, or, more likely you’ve had to blow away your development and bring it back via svn, then you have to restore the .git files. Restoring them isn’t so bad:

git init
git remote add origin git@github.com/your_project.git
git pull origin master

Posted in ATG, Git, SVN, Version Control. Tags: , . Comments Off on Using git with svn »

Giving up on Yii Oracle Clobs

Started off yesterday with the intention of trying to implement functional Oracle Clobs in Yii similar to how I implemented it in CakePHP a couple years ago. As yesterday went on I kept busting through boundaries and was feeling great about my progress. But Then I hit the roadblock and I wasn’t able to continue. It’s not worth spending another couple days on when I have a deadline for a pilot by Fall. 4000 characters is enough for the pilot.

The result has been to alter the Yii COciSchema. Just changing the declaration of text to a varchar2(4000).

   public $columnTypes=array(
        'pk' => 'NUMBER(10) NOT NULL PRIMARY KEY',
        'string' => 'VARCHAR2(255)',
        //'text' => 'CLOB',
        'text' => 'VARCHAR2(4000)',
        'integer' => 'NUMBER(10)',
        'float' => 'NUMBER',
        'decimal' => 'NUMBER',
        'datetime' => 'TIMESTAMP',
        'timestamp' => 'TIMESTAMP',
        'time' => 'TIMESTAMP',
        'date' => 'DATE',
        'binary' => 'BLOB',
        'boolean' => 'NUMBER(1)',
		'money' => 'NUMBER(19,4)',
    );

The issue is Yii (PDO) doesn’t support LOBs well at all, so that declaration didn’t make any sense to begin with.

Yii default ORDER BY

I ran into an issue with a minor difference between Oracle and MySQL. Apparently MySQL is better about returning rows in the order they were inserted than Oracle. Now if you want to let me know it’s wrong to assume results are returned in any specific order, I know! Neither gives any guarantee on the order of results without an ORDER BY, but Oracle is semi-random.

It took me a little while to find the right way to add default items to queries. Yii uses CActiveRecords for model queries. I already had an overridden CActiveRecord class from Yii handling “getLastInsertId” with Oracle. So I knew I would be able to use that somehow.

I finally discovered scopes. It allows me to define a scope:

public function scopes()
{
    return array(
        'sort_order'=>array(
            'order'=>'SORT_ORDER ASC',
        ),
        'id_order'=>array(
            'order'=>'ID ASC',
        ),
    );
}

and then use it as such:

MyModel::model()->id_order()->FindAllByAttributes(array('SOMECOLUMN'=>1))

But still I didn’t find anything on default scopes. On a whim I did a grep -i “defaultscope” on the code and discovered it exists in the Yii framework. So I was able to piece together the following:

public function defaultScope()
{
    return array(
 	'order'=>'ID ASC'
    );
}

and bam. Add that to my QActiveRecord, and it’s golden.

Posted in ATG, Databases, MySQL, Oracle, PHP, Quizmo, Yii. Tags: , , , . Comments Off on Yii default ORDER BY »

Working with Submodules

I’m using submodules in my current application. All over the place. And I’ve hit some issues with using them properly. Regardless of the warnings I’ve read about, I still did things in the wrong order.


cd ./subm
git checkout master
git commit -a -m "commit to submodule"
git push
cd ..
git add subm
git commit -m "committing submodule's commit to main project"

The thing I’ve done wrong twice now is committing the change to the main project first. That creates a link to a nonexistant commit on the submodule as that is what a submodule is, a link to a specific commit on a different project. The commit has to be done within the submodule first.

Edit: found this after the fact, edited my code to match the code there as it’s more succinct. Stackoverflow has everything
http://stackoverflow.com/questions/5814319/git-submodule-push

Posted in ATG, Git, Quizmo, Version Control. Tags: , . Comments Off on Working with Submodules »

Github Pull Request for Just One Commit

I have a forked Yii which I use as a submodule in a couple of my applications. I haven’t made many changes, but most would probably not be useful most people. i.e. I put a conditional in that checks the version of PHPUnit and if it’s older than 3.5 it uses a different include file. Thereby letting me get around the limitation I have in one of my development environments.

My last commit, however, directly relates to an issue Yii had identified. So I wanted to push only that last commit upstream.

First make sure you have the upstream remote.
Then fetch from upstream — this creates upstream/master.
Then we create a new branch calling it upstream — not to be confused with the local remote we just created with the same name.


cd yii
git remote add upstream git://github.com/yiisoft/yii.git
git fetch upstream
git checkout -b upstream upstream/master
git cherry-pick
git push origin upstream

Then use something that was new to me, cherry-pick and give it the hash of the specific commit. That will merge over only that commit to the new branch you made. Then just push it.

From github, you can then make a Pull Request from that specific branch and contribute. Since that’s what it’s all about.

Helpful links:
https://help.github.com/articles/fork-a-repo
http://kurogo.org/guide/github.html
http://stackoverflow.com/questions/5256021/send-a-pull-request-on-github-for-only-latest-commit

Functional Testing: what to test?

I’ve been working with PHPUnit’s SeleniumTestCase. I worked out some good login switching for the two authentication schemes I’m working with. Then came time to actually write some tests. But what to test?

Unit testing tests a single class. A singular piece of code or a unit. I typically write unit tests for Models only. Integration testing tests the interaction of multiple units or units with multiple resources. I’ve been thinking of these as sort of testing the Controller. That’s a little simplified, but it’s not really something I have a framework for with Yii and PHPUnit. Functional testing likewise has varying definitions. Some people like to focus on the testing of “functional requirements of the product” and some people have a more simplistic view of it, that it’s just automating tests of the views — so it can be used as integration testing. I personally think the former is a better way to look at it, but it also sounds a little douchey to say it out loud.

So I’m totally agile. I’ve got all these user stories. And all these tasks. What I’m doing is writing the functional tests in terms of the user stories and tasks. This is sort of BDD, except I’m ignoring the excessive mocking, which basically makes the BDD tests unit tests, and doing the whole shebang at once. Shebang isn’t being picked up by spellcheck. #!

Posted in ATG, Yii. Tags: , , , , , . Comments Off on Functional Testing: what to test? »

Agile: doing UI first

I was going nuts about BDD recently. One of the most exciting things about it was the idea of doing all of the UI first. The idea is to deliver something to the client before too much of the back end is developed, so they can say if you’re on the right track — apparently this is a major agile tenet.

I’ve thought this way for a long time. For my current job’s interview, when asked how to start a project I replied to do all the UI first. I don’t think that’s what any job actually wanted to hear, I know I’d given that answer 100 times before, and I know no one ever liked it. I got lucky that the group I interviewed with was in such disarray they didn’t realize it probably wasn’t the answer they were supposed to be looking for. But that was years ago, so maybe that answer makes more sense in these agile driven days.

Oddly, this wasn’t covered in the 3 day agile training I recently finished. Maybe it’s covered in the recommended 5 day version.

My issue has been trying to write user stories that only cover the UI without basically duplicating all user stories and adding “UI” to them. I originally went with one user story that just had (basically) “do all UI”. Artie rightly pointed out that is an epic, and needs to be broken down for user stories.

The best I got was to break it down by themes. Take Quizmo as a simple example.

  • All Quiz Management UI
  • All Question Management UI
  • All Quiz Taking UI
  • All User Management UI
  • All Student Viewable Reporting
  • All Admin viewable Reporting

I don’t actually think this is right, because this relies on implicitly knowing all user stories from the get-go. Perhaps the right way would be to have 2 sets of story points for each story, one for the UI and one for the complete execution. This would mean running the same story card twice.

I’m sticking with the “UI by theme” approach for now.

Posted in ATG, Quizmo. Tags: , , . 2 Comments »

Git Template Application Repository

I titled this post what I wanted, but the result wasn’t quite so succinct.

What I wanted was a git repository that contained a template for future applications. I have done so much what I’m considering good work with Quizmo, I wanted to create a skeleton framework that I could fork into applications. So all of the components that I’ve created could be contained in one place and when I update them in Quizmo, they would likewise be updated in the template repository, and future applications would be able to easily pull down those same changes from the template repo. So I could really live the dream of rapid development RoR has been trying to sell for the last decade.

My first thought was to create a repo that had a dummy application in it and just forking it. Then I should be able to pass things back via the upstream and down with merges. It seems like such a simple operation. Unfortunately, that’s not how forking works. The problem is if you want to merge upstream, you have to merge everything. You can’t just merge the things that are in the upstream, there’s no mechanism for adding or committing one revision without committing every revision prior to that one.

So the only way to have different components connected via other repositories is to have multiple submodules. Everything needs to be contained in its own directory. There’s also fake submodules*. Which just relies on a lot more setup, I haven’t encountered problems with using submodules yet, so that isn’t an issue.

Instead of having the awesome application template repo I wanted, I’ve got a bit of a mish mash which currently looks like this:

The most important thing with this discovery of using a mish mash of submodules is that I should modularize my code. That is to say I need to have all related components in the same place. That seems obvious, but when going with the flow of yii, I put things where yii wanted them, not necessarily where they would be best served. Like twitter bootstrap, which got just strewn about all over the app.

The authentication abstraction I’m using is an IdentityFactory that chooses which xIdentity component to use which is an extension of UserIdentity but each individual xIdentity calls on its respective extension. So do the xIdentities go with the appropriate extension or with the IdentityFactory/UserIdentity? Asking the question makes me think it has to be with the extension.

Interesting links:

* Update: Upon working more with submodules, and paying attention to the pitfalls (outlined here) I’ve actually become very opposed to fake submodules (see above). Fake submodules relies on the person checking out your code to check everything out, and leaves the repository with no explicit link to the submodules. You basically just have to know. Which is fine for one guy working on one project, but is horribly irresponsible for a developer working for anyone other than themselves.

Posted in ATG, Git, Quizmo, Version Control, Yii. Tags: , , , , . Comments Off on Git Template Application Repository »