Welcome Guest, Not a member yet? Register   Sign In
[Deprecated] DMZ 1.6.2 (DataMapper OverZealous Edition)

[eluser]PoetaWD[/eluser]
Hey Phil!

I see that you still working very hard on this project, and version 1.7 is on its way!

Thank you VERY much for this!

I am planning to release a Auth Library based on DMZ to contribute with the community.

I also have another sugestion to DMZ:

A validation rule to check if there is already a related object with the same property.

I had to create my own function to check for this:

Code:
function check_relationship($field_id, $otherfield)
    {
        $o = new Gene_relationship;
        $o->where('gene_section_id', $field_id);
        $o->where('stNome', $otherfield);
        $o->get();
        
        if($o->exists())
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }

But it would be much easier if we had a validation rule for this:

I tried the unique_pair validation rule but it didnt work:

Code:
var $validation = array(
                            
        'stName' => array(
            'rules' => array('required', 'max_length' => 200, 'unique_pair' => 'gene_section_id'),                        
            'label' => 'Nome'
        )

The way I suggest:

Code:
var $validation = array(
                            
        'stName' => array(
            'rules' => array('required', 'max_length' => 200, 'unique_relationship' => 'gene_section'),                        
            'label' => 'Nome'
        )

That would check if there is a record related to "gene_section" with that property, in this case, "stName".

[eluser]OverZealous[/eluser]
@Poetawd

That's an interesting validation rule. Did you know you can easily add new validation rules via an extension?

The rule you are suggesting would be a perfect example of an extension validation rule!

As soon as you get your extension ready, please add it to the 3rd-party extensions page. That link is to a document I've written that hopefully will help get you started how.

[eluser]GregX999[/eluser]
Doh! I posted this in the wrong thread at first...

Is there a way to write a trigger? (I think it’s called a trigger.) I want to put a method in a model that gets called when an object of that type gets deleted. It’s an “Image” model, and if an Image object gets deleted, I want the model to delete all the appropriate image files.

Greg

[eluser]OverZealous[/eluser]
@GregX999

Not specifically, but there are a couple of options. The best way, IMO, is to simply overload the delete method, like so:

Code:
class Image extends DataMapper {

    ...

    function delete($object = '', $related_field = '') {
        // capture any important information here (id, etc)

        // delete the item
        $success = parent::delete($object, $related_field;

        // if the item was successfully deleted, then cleanup
        if($success && empty($object) && !is_array($object)) {
            // do the cleanup
        }
    }

    ...

}

[eluser]GregX999[/eluser]
Ok, looks straight-forward. Thanks!

[eluser]GregX999[/eluser]
I've hit (another) bump.

I have a PressItem model that has_many PressImage models. I want to be able to "foreach" through all of the images that belong to a specific item, and I want to do it in a specific order given by an array of PressImage ids.

So, with an example PressItem id of 2, an SQL query might be:
SELECT * FROM pressimages WHERE pressimage.pressitem_id = 2 ORDER BY FIELD (pressimage.id,4,1,3,2);

Can I do that with DMZ somehow? I'm not sure if using "order_by_func" is what I want, or if I need to use the "query" function like:

Code:
$pressitem = new PressItem();
$sql = "SELECT * FROM pressimages WHERE pressimage.pressitem_id = 2 ORDER BY FIELD (pressimage.id,4,1,3,2)"
$pressitem->pressimages->query($sql);

foreach($pressitem->pressimages){ ... }

:grrr:

[eluser]OverZealous[/eluser]
@GregX999

Out of curiosity, in what situation would you need an order that is not stored in the database? It seems like the issue might be solved more correctly without using the MySQL-only ORDER BY FIELD clause.

At any rate, you can try this:
Code:
$pressitem = new PressItem($press_item_id);
$pressitem->pressimage->order_by_func('FIELD', '@id',4,1,3,2, ' ');

That might work. You must include the last value, as stated in the manual. Due to the fact that CodeIgniter requires ASC or DESC, it might not work. If you need a dynamic list of ids to sort on, you can do this:
Code:
$args = array('@id') + $ordered_ids;
$pressimage->order_by_func('', array('FIELD' => $args), ' ');

// Alternatively, this might be required instead
$args = array('FIELD') + $args;
$args[] = ' ';
call_user_func_array(array($pressimage, 'order_by_func'), $args);

Or, you might be able to just make your life simpler:
Code:
$pressimage->order_by('FIELD (pressimage.id,4,1,3,2)', ' ');

None of this has been tested, you might have to tweak it to get it working.

FYI: You kinda confused me with the relationship stuff, as I thought this was a related item issue. For future reference, you can add any query clause on top of a basic relationship query.

[eluser]GregX999[/eluser]
I need to select the images in a specific order so I can iterate through them and update their "position" field. The position field is used to order them when they are being displayed. I'm using drag-n-drop sorting w/ AJAX so an admin can sort them, and when an item is drag-dropped, the new sequence is sent through AJAX. And since there are multiple pressitems, I only want to re-sequence the images that belong to the item being edited.

So I ended up going with this:

Code:
$pressimage->query("SELECT * FROM pressimages WHERE pressitem_id={$pressitem->id} ORDER BY FIELD(id,{$images_in_order})");

$i = 1;
foreach ($pressimage->all as $image) {
    $image->position = $i;
    $image->save();
    $i++;
}

I just couldn't get any of the other things to work because of CI putting single quotes around everything.

Greg

[eluser]OverZealous[/eluser]
@GregX999

Just flip the problem around, this is by far more efficient, because you don't need to sort the query at all:
Code:
// assume $order is array of sorted IDs
$order = array_flip($order);

$pressitem->pressimages->select('id', 'position')->get();

foreach($pressitem->pressimages as $pressimage) {
    $pressimage->position = $order[$pressimage->id];
    $pressimage->save();
}

Edit: added the select limiter to the query, to increase performance.

Edit2:
Hey, new PHP function for me: array_flip!

[eluser]GregX999[/eluser]
Brilliant!! It works perfectly, and is SO much cleaner!

I was unaware of array_flip() as well.

The only change I made was:
Code:
$pressimage->position = $order[$pressimage->id] + 1;

So that the position field goes from 1 to X instead of 0 to X.

Thanks!
Greg




Theme © iAndrew 2016 - Forum software by © MyBB