1

I've inherited a Craft site that is a mix of a custom plugin (the main site) plus a Laravel Dingo plugin (behind which the bulk of the data in the db lives), plus Solr, and I'm trying to untangle it.

I want to add a function to my controller that updates multiple entries in the database but I can't figure it out. I'll post a snippet of a working existing code along with my attempt:

//Controller
==working, existing code===
public function actionUpdateGuide() {
    $this->requirePostRequest();

    $attr = craft()->request->getPost('guide');
    $request = craft()->MyPlugin_guide->updateGuide($attr);

    if ($request && $request->isSuccessful()) {
        $this->clearCachedAsset($attr['id'], 'guide');
        $this->redirectToPostedUrl();
    } else {
        $this->hydrateInvalidForm($request, $attr);
    }
}

==not-working, my function===   
public function actionPositionGuide() {
    $this->requirePostRequest();

    $attr = json_decode(craft()->request->getPost('guide.json'), true);
    $neworder = array();

    foreach($attr as $row) {
        $guide = array(
            'id' => $row['name'],
            'position' => $row['value']
        );

        array_push($neworder, $guide);
    }

    $request = craft()->MyPlugin_guide->positionGuides($neworder);

Then

//Service
==working, existing code=== 
public function getGuideLocations($id, $page) {
    $url = $this->getUrl() . "/" . $id . "/locations?page=$page";
    $response = craft()->laravel_plugin->send('get', $url);

    if (!$response->isSuccessful()) {
        return array("error" => $response->getStatusCode(), "msg" => "get_guide_locations_error");
    }

    return $response->json();
}

==non-working, my function==
public function positionGuides($attr) {

    foreach($attr as $guide) {
        craft()->laravel_plugin->update($attr);
    }
}

I'm confused because I assumed the normal workflow was controller->service->model->database, but this seems to be controller->service->anotherplugin-service.

Looking in the controller for this Laravel plugin, I see:

public function update($id) {
    $guide = Guide::find($id);

    if (is_null($guide)) {
        return 'error';
    }

    $locations = Input::get("locations", array());
    if(!empty($locations)) {
        $locations =  Location::whereIn('id', $locations)->lists('id');
    }

    $guide->locations()->sync($locations);

    $guide = $guide->fill(Input::all());

    if (!Input::has('image_id')) {
        $guide->image_id = null;
    }

    return $guide->save() ? $guide : $guide->getErrors();
}

And here is the laravel_api model for it:

protected $table = "guides";
protected $fillable = ["name", "city", "type", "image_id", "description", "status", "updated_by", "document", "position"];
protected $dates = ['deleted_at'];
protected $rules = ["name" => "required"];
protected $appends = array('location_detail');

protected $searchable = ['name', 'description', 'subtitle'];

public function locations()
{
    return $this->belongsToMany('Location');
}

Any advice would be appreciated.

  • Is the getGuideLocations method relevant in your example? Nothing seems to be calling it. Also, what's the behavior you're seeing and what's the behavior you're expecting? – Brad Bell May 12 '16 at 20:10
  • getGuideLocations is not relevant except as a demo of a function that's working. I want to update the position attribute of each guide but I'm having trouble deciphering how these values are updated via this interface. – OrdinaryHuman May 12 '16 at 20:13
1

OK, I managed to figure it out and I'll post the solution for those who run into similar problems.

Essentially, what's happening is Twig template->Plugin controller->Plugin Service->Laravel API->Laravel Controller->Database

The code:

//Plugin controller
public function actionPositionGuide() {
    $this->requirePostRequest();
    $attr = json_decode(craft()->request->getPost('guide.json'), true);
    $neworder = array();
    foreach($attr as $row) {
        $guide = array(
            'id' => $row['name'],
            'position' => $row['value']
        );
        array_push($neworder, $guide);
    }
    $request = craft()->myplugin_guide->positionGuides($neworder);

}

Then

//Plugin service
public function positionGuides($attr) {
    $url = $this->getBaseUrl() . "/guides/position";
    return craft()->mylaravel_api->send('post', $url, $attr);


}

Then add a route to the Laravel routes.php file

Route::post('guides/position', 'GuidesController@position');

Then the Laravel controller:

public function position() {
    $data = Input::all();
    $response = ["msg" => "success", "status" => 200];

    foreach($data as $guide) {

        $oldguide = Guide::find($guide['id']);

        if (is_null($oldguide)) {
            $response = ["msg" => "error", "status" => 500];
        }

        $oldguide->position = $guide['position'];

        $oldguide->save() ? $oldguide : Log::debug($oldguide->getErrors());
    }

    return Response::json($response["msg"], $response["status"]);
}

Error handling is not great but if anyone has suggestions for improvement, I'm all ears.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.