Cleaning up and wrapping up

Update: Smoc is dead, long live h2octrine!

I’ve used smoc in production for a week or two now and there were some real cleaning up to do, this is the recap. Let’s start with some really low level stuff first. In the Common class:

static function index(){
	$req 		= array_slice(explode('/', $_SERVER['REQUEST_URI']), 1);
	$base_count = empty($GLOBALS['base_dir']) ? 0 : count(explode('/', $GLOBALS['base_dir']));
	$cur_ctrl 	= $req[$base_count];
	$cur_meth 	= $req[$base_count + 1];
	$args_start = $base_count + 2;
	if(empty($cur_ctrl) || empty($cur_meth)){ echo "No ctrl or method"; exit; }
	$args		= self::array_trim(array_slice($req, $args_start));
	if(count($args) % 2 != 0){ echo "key/missing value"; exit; }
	for($i = 0; $i < count($args) - 1; $i += 2)
		$_GET[ $args[$i] ] = $args[$i + 1];
		
	$smarty 	= new SmartyDoctrine();
	$obj 		= self::loadCtrl($cur_ctrl);
	$smarty->assign('site_dir', "/{$GLOBALS['base_dir']}/");
	$smarty->assign('content', $obj->$cur_meth());
	$smarty->display('index.tpl');
}

Yes, yet again this one had to be remade. I realized this after uploading to the present server, it’s in a sub directory two levels deep and the prior logic couldn’t handle that. Learn from my mistake and shape up, don’t be lazy, just do the right thing right away. The above routing logic can now handle an arbitrarily deep structure, finally 100% finished after like half a year or more.

A whole lot more had to be rearranged in the AdminCtrl class too:

function arrWithRelations($collection, $hide = true){
	$rarr = array();
	foreach($collection as $item){
		$rarr[$item->id] = $item->toArray();
		foreach($this->t->getRelations() as $key => $value){
			$ctrl = $this->getCtrl( $value->getClass() );
			if($this->isListHidden($key) == false){
				if($value instanceof Doctrine_Relation_Association)
					$rarr[$item->id][$key] = $item->fluent2d($key)->flatten( $ctrl->label )->join('<br/>')->c;
				else if($value instanceof Doctrine_Relation_LocalKey)
					$rarr[$item->id][$value->getLocal()] = $item->fluent($key)->at($ctrl->label);
			}
		}
	}
	return $rarr;
}

function assignRelations($hide = true, $hide_with = array()){
	$hide_with = empty($hide_with) ? $this->hidden : $hide_with;
	foreach($this->t->getRelations() as $key => $value){
		if($value instanceof Doctrine_Relation_Association){
			$relations[ $key ]['foreign'] = true;
			$this->columns += array($key => array());
		}else if($value instanceof Doctrine_Relation_LocalKey)
			$key = $value->getLocal();
		
		$relations[ $key ]['label'] = $this->getCtrl($value->getClass())->label;
		$relations[ $key ]['Mdl'] 	= $value->getClass();
	}
	$this->assign('relations', $relations);
	$columns = $hide ? array_diff_key($this->t->getColumns(), $hide_with) : $this->t->getColumns();
	$this->assign('columns', $columns + $this->columns);
}

function isListHidden($field){
	if($this->getTplVar('hidden')){
		if(in_array($field, $this->list_hidden))
			return true;
	}
	return false;
}

I’ve moved a lot of the hidden/not hidden logic into the templates instead, here is the current ui.tpl:

<form {$form_head} > 
<table> 
    {foreach from=$columns key=c item=info}
		{if $hide eq true}
			{if !in_array($c, $hidden)}
				{include file="../ui_field.tpl" c=$c info=$info}
			{/if}
		{else}
			{include file="../ui_field.tpl"} 
		{/if}
    {/foreach}
	{if $ext_form}
		{include file=$ext_form}
	{/if}
</table> 
<input type="submit" value="Submit"> 
</form>

Note the $ext_form novelty, the form() function can be extended and this value assigned there for some extra stuff. I’ve had reason to do this on one occasion.

And ui_field.tpl:

<tr> 
    <td>{$c}: </td> 
    <td> 
        {if !empty($relations.$c)}
			{if $relations.$c.foreign eq true}
				{obj->checkBoxes lbl=$relations.$c.label mdl=$relations.$c.Mdl idname=$c}
			{else}
				{obj->selBox lbl=$relations.$c.label mdl=$relations.$c.Mdl idname=$c}
			{/if} 
		{elseif $info.type eq "boolean"} 
			{obj->radioBox idname=$c}
        {elseif $info.length > 500} 
            {obj->textArea idname=$c}
		{elseif $c eq "password"}
			{obj->textBox idname=$c pwd=true}
        {else} 
            {obj->textBox idname=$c} 
        {/if} 
    </td> 
</tr>

Some new stuff now. It turns out Doctrine is not really well suited for inserting stuff through the save() method, not when you’re importing over a hundred thousand records anyway 🙂

And no it didn’t help much to use the free() method, I ended up writing a small auxiliary library for doing this in pure SQL which only works with MySQL. So much for trying to be DB agnostic.

Here is the end result anyway:

public function import(){
	ini_set('max_execution_time', '3000');
	ini_set('memory_limit', '500M');
	$emails = Arr::fluent(file($_FILES['import']['tmp_name']))->map('trim')->uniq()->trim()->c;
	$conn = new Mysql();
	foreach($emails as $email){
		$rid = $conn->insertRaw('recipient', "`id` ,`email` ,`subscribing`", "NULL , '$email', '1'");
		if($rid){
			foreach($this->p['Folders'] as $fid)
				$conn->insertRaw('folderlist', "`id` ,`recipient_id` ,`folder_id`", "NULL , '$rid', '$fid'");
			echo "$email <br>";
		}
	}
	echo "Import finished";
}

I’m not gonna go through the Mysql class, it’s very unexciting.

Anyway, here’s the final upload.

Related Posts

Tags: , , ,