CodeIgniter Forums
DataMapper 1.6.0 - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DataMapper 1.6.0 (/showthread.php?tid=11358)



DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]OverZealous[/eluser]
I figured out why. It makes sense, although I'll need to discuss with stensi how he'd like to solve it.

Basically, the test to see if $object->delete($other_object) should delete the provided $other_object or the whole $object itself checks to see if $other_object is empty. If you pass in an empty array, that's the same thing as passing in nothing.

The short-term solution, for now, is to check to see if $products->all is empty first, and only delete if it isn't:
Code:
if ( ! empty($products->all))
{
    $client->delete($products->all);
}
Note: I realize this is basically what you are doing, but more "accurate".

Since DataMapper is not my project, I'll pass this on to stensi.


DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]macigniter[/eluser]
Thanks!

I feel bad to ask another question. But it's a hair-puller...

I have a "Login" controller and want to instantiate a "Login" object of my "Login" Model. Somehow I can't get it to work. Is that a namespace issue?

Controller:
Code:
<?php
    class Login extends Controller {

    function Login()
    {
        parent::Controller();
    }
    
    function index()
    {
                [...]

            $u = new User();
                
        $u->username = $this->input->post('user');
        $u->password = $this->input->post('pass');
                    
        if ($u->login())
        {
             $l = new Login();
             // this is where the output stops
             // even if I put this in the model method login()
        }
    }

How do I have to call the model? Or is it not possible to name a model with the same name as an existing controller?


DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]OverZealous[/eluser]
Yes. Obviously, if both PHP Classes are named Login, only one Login class can exist. You'll need to rename your Login model.

Maybe more importantly, are you sure it's a model you want for that? Models are meant to store data (to and from the database).

You should use a Library to place all of your login code in one location, that can easily be loaded and used as needed. I have a Login_Manager library that I use for this purpose. You just create a Login_manager class, place it in libraries, and call
Code:
// inside my controller
$this->load->libary('login_manager');
$this->login_manager->process_login($user);

If you need to access it from within a model, you'll need to be more creative, although I recommend keeping your business code separate from your model code whenever possible.
Code:
// only within a model
// get CodeIgniter
$CI =& get_instance();
$CI->load->library('login_manager');
$CI->login_manager->process_login($this);

Finally, CodeIgniter lets you do some creative things with routing controllers. If you choose, you could create a controller called Access_control (for example), but add routes for /login and /logout, etc, to your routes.php under config/.


DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]macigniter[/eluser]
Thank you so much Phil. I really appreciate your patience Smile

My login model actually stores the user "logins". It's not the login management. It contains the number of logins, browser, ip address etc. of a logged-in user. So I guess I just have to rename it...


DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]OverZealous[/eluser]
A-Ha! That makes more sense!

Yes, that's a basic "problem" with OOP code. Sometimes, you just have to be more verbose with your naming.

(How 'bout Accesslog? ;-) )


DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]Yman[/eluser]
help! i can't save relationship
this is what i've done:

Controller
Code:
$n = new Entry();
        $n->limit(1)->get();
        
        //saving relationship here
        $c1 = new Horizontal();
        $c1->where('name', $this->input->post('horizontal'))->get();
        $n->save($c1);

Model (Entry)

Code:
class Entry extends DataMapper {

    var $has_one = array("horizontal");
    
    var $validation = array(
        array(
            'field' => 'know_fragment',
            'label' => 'Knowledge Fragment',
            'rules' => array('required', 'trim')
        ),
        array(
            'field' => 'severity',
            'label' => 'Severity Level',
            'rules' => array('integer', 'required')
        ),
        array(
            'field' => 'remark',
            'label' => 'Remarks',
            'rules' => array('trim')
        ),
        array(
            'field' => 'solution',
            'label' => 'Solutions',
            'rules' => array('trim')
        ),
        array(
            'field' => 'switch',
            'label' => 'Switch On Off',
            'rules' => array('integer')
        )
    );

Model (Horizontal)
Code:
class Horizontal extends DataMapper {

    var $has_many = array("entry");
    
    var $validation = array(
        array(
            'field' => 'name',
            'label' => 'Name',
            'rules' => array('required', 'trim', 'unique')
        ),
        array(
            'field' => 'entry',
            'label' => 'Entry',
            'rules' => array()
        )
    );

when i try saving the relationship, no error shown but yet fail to save.

Quote:Error

A Database Error Occurred

Error Number: 1054

Unknown column 'entry_id' in 'where clause'

SELECT * FROM (`entries_horizontals`) WHERE `entry_id` = '1' AND `horizontal_id` = '2'



DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]OverZealous[/eluser]
Why are you re-getting your Entry in the first section? You do not ever have to do this. By doing this, you are re-querying the Entry table, and resetting it to whatever item happens to be first.

Also, as a shortcut, DM now supports combining the save for relationships and objects, just use this:
Code:
$n = new Entry();
$n->entry_no = $this->input->post('entry_no');
$n->know_fragment = $this->input->post('know_fragment');
$n->severity = $this->input->post('severity');
$n->remark = $this->input->post('remark');
$n->solution = $this->input->post('solution');
$n->onoff = $this->input->post('onoff');
$c1 = new Horizontal();
$c1->where('name', $this->input->post('horizontal'));
$n->save($c1);

DataMapper automatically sets the ID that the new object was saved as. If you still want to re-look it up for some reason (such as retrieving default values for other columns), do it like this:
Code:
$n->get_by_id($n->id);



DataMapper 1.6.0 - El Forum - 02-09-2009

[eluser]Yman[/eluser]
thanks OverZealous,

i have a question here, is there anyway plugins or something for us to import .csv file and saving relationship simultaneously


DataMapper 1.6.0 - El Forum - 02-10-2009

[eluser]OverZealous[/eluser]
No, there is not. You can write one in PHP without too much trouble. I wrote one for debugging and testing purposes, but it is fairly specific. My design was this:

Name of CSV file was the model.
First row of CSV has the field or related object names.
Process the CSV using example code from the php website.
On the first loop, store the header row so you can figure out the field names.
Create a new object, save the fields, and save it to the database.

Here's something to get you started. It's hacked down from my code, so there may be mistakes.
Code:
// set these yourself
$csv_files = array('model1', 'model2', ...);
$path = APPPATH . 'import/';

foreach($csv_files as $model) {
    if(! class_exists($model)) {
        $this->_show_error("Error: unable to find class $model");
    }
    $handle = fopen($path . $model . '.csv', 'r');
    ini_set('auto_detect_line_endings', TRUE);
    $row = 0;
    $header;
    while (($data = fgetcsv($handle)) !== FALSE) {
        if($row == 0) {
            // save the header, ...
            $header = $data;
        } else {
            $o = new $model();
            echo "  Saving $model(";
            foreach($data as $index => $d) {
                if($index > 0) {
                    echo ", ";
                }
                echo "\"$d\"";
            }
            echo ") ... ";
            foreach($header as $index => $field) {
                if($index >= count($data)) {
                    // we've looked up everything, there must be extra header columns
                    break;
                }
                $d = $data[$index];
                // skip empty columns
                if( $d === '') {
                    continue;
                }
                if(in_array($field, $o->fields)) {
                    // save the data
                    $o->{$field} = $d;
                } else if(in_array($field, $o->has_one)) {
                    // hopefully, all of the $fields were first.  Otherwise this can be wasteful
                    $other_obj = new $field();
                    $other_obj->get_by_id($d);
                    if( ! $other_obj->exists()) {
                        $this->_show_error("Error loading relationship $field($d) on object $model: That id does not exist.");
                    }
                    if( ! $o->save($other_obj) ) {
                        print_r($o->error->string);
                        $this->_show_error("Error saving object $model($id) with one relationship to $field($d).");
                    }
                } else if(in_array($field, $o->has_many)) {
                    // hopefully, all of the $fields were first.  Otherwise this can be wasteful
                    $other_ids = explode(',',$d);
                    foreach($other_ids as $other_id) {
                        $other_obj = new $field();
                        $other_obj->get_by_id(trim($other_id));
                        if( ! $other_obj->exists()) {
                            $this->_show_error("Error loading relationship $field($other_id) on object $model: That id does not exist.");
                        }
                        if( ! $o->save($other_obj, $field) ) {
                            print_r($o->error->string);
                            $this->_show_error("Error saving object $model($id) with many relationship to $field($other_id).");
                        }
                    }
                } else {
                    $this->_show_error("Error saving object $model: No field or relationship for $field.  (Data: $d)");
                }
            }
            if( ! $o->save() ) {
                print_r($o->error->string);
                $this->_show_error("Error saving object $model with expected id $id");
            }
            echo "done.\n";
        }
        $row++;
    }
    fclose($handle);
}



DataMapper 1.6.0 - El Forum - 02-10-2009

[eluser]Yman[/eluser]
waoh, thanks man!

let me try it out 1st =D