Move some function from long model file to another file

How put some new or existing function related to model to another file, but still get access to parent model?

Let’s say I’ve got orders table in db, OrdersController, OrdersTable.
In OdrersTable I have:

public function fun1($id)
{
  $order = $this->get($id);
}

private function helper(Order $order)
{
  //do some repetitive work
}

I want make new file and connect it somehow to OrdersTable, so I can have in Orders2Table:

//Orders2Table
public function fun2($id)
{
  $order = $this->get($id); //which take record from orders, as above
  $this->helper($order);
}

Maybe I can “extend” somehow OrdersTable? But I’m not good at this level of object programing.
My problem is, that my models and controllers files have 2k+ lines.

The details you want are in this section of the php manual

The bigger question is what will you move to improve the situation.

As a self taught coder I found this book - Refactoring
Improving the Design of Existing Code
- helpful in focusing my attention on problems in my code and giving me ideas on how to improve them.

Perhaps chapter three on code smells would help you as much as it did me

1 Like

So I tried this, initially worked, but it seems calling fun1 plced in table1 from table2 change repository and functions in corresponding entity file doesn’t work.

You would have to show some code from your two classes and methods to get any advice.

But a first guess (assuming these are table classes) is that you’re not accounting for the file/class naming conventions and how you have to manage things if you don’t follow those conventions.

class WidgetsTable extends Table {

// will work with the db table 'widgets'
// will create entity classes 'Widget'
// will be known by the alias 'Widgets' in controllers
// will be automatically available as $this->Widgets in the class 'WidgetsController'
}
class ExtendWidgetsTable extends WidgetsTable {

// will default to working with 'extends_widgets' table if you don't take steps to manage this.
// will default to creating 'ExtendsWidget' entities if you don't take steps to manage this.
// etc.
}

This section on basic use of table classes should help if that is the problem.

1 Like

Thanks @dreamingmind ! I have some hardware work last weeks but I’m getting back to programming. I added those to initialize (I’m using 3.1):

$this->table('kratki4s');
$this->belongsTo('Orders');
$this->entityClass('App\Model\Entity\Kratki4');

and it helped. Of course I am not sure if it is good idea, but I don’t have better and I need add more code relevant to more than one model and 2k lines is a lot even for me.
I was trying using include / require but it have their own problems.

I don’t know if this is what you mean but you could create a service class:

<?php 
// src/Service/Orders2Table.php

namespace App\Service;

use App\Model\Table\OrdersTable;

class Orders2Table {

    public OrdersTable $table;

    public function __construct(OrdersTable $table)
    {
        $this->table = $table;
    }

    public function fun2($id) {
        $order = $this->table->get($id);
        $this->table->helper($order);
    }
}
// src/Model/Table/OrdersTable

class OrdersTable extends Table {
            // pass OrdersTable to your service class
           // and defer to the service class
            public function someFunc($id) {
                       $orders2 = new Orders2Table($this);
                       $orders2->fun2($id);
            }
}

Thanks, it seems like I can define new functions in new file and call them from old one? Thanks for all php syntax, I probably will not figure out my self than I can pass “$this” as an old table via constructor :slight_smile:
How about accessing new functions from new file from controller? In first version I add $this->loadModel('Orders2'); and I get access to all methods, probably it doesn’t want work that way with service?

Anyway I will give it a try and write how it works.

It seems that you’re trying to do some pretty advanced structuring of your code without really understanding object oriented code design in general, and PHP namespaces and Cake’s MVC structure in particular. Spending a bit of time reading up on these topics will be time that you very quickly get back as you become a more efficient programmer.

2 Likes

You are probably right, but I have to put this code somewhere. Can you point me some reading for start?

Most of this particular problem does not generate view aka html for browser, so I think V part and Template folders are out.
It should react to some user input, which is received via Controller which pass it to a Table / Model.
There is lot of data processing and DB changes so I put it it in corresponding table file, but it is huge.