ModelAdmin custom action

Silverstripe Version:
4.1.0
Question:
I’ve implemented a custom DataObject for Behance Projects which I would like to import on the ModelAdmin instance I’ve created.

What I thought would be the best solution is to include a button along side the export / print / import buttons.

My questions is what would be the best way to do this or if it’s even possible?

Thanks in advance.

Hi @ekersten, it sounds like you want to create an import button, but as you noted yourself, an import button already exists. Can you describe in more detail what you want your new button to do?

@JonoM what I would like to do is make a request to the Behance API and import the projects.

I currently have a DataObject setup to host some of the API data and some extra fields. So the request would match based on the Behance ID and update or create my DataObjects accordingly.

Thanks,

I don’t have much experience with this so hopefully someone else will chime in, but if you want to work on multiple records at once I would take a look at the GridFieldImportButton code and try making a new button based on that. If you want to work on individual records instead BetterButtons was a great solution in 3.x for adding a button to the Edit form but I don’t know of an equivalent technique in 4 yet. You could add a custom action to each row in the GridField though by following these instructions.

You could also consider setting up a queued job to run as frequently as you like that checks for new or outdated records and adds any missing information from the API as necessary, saving you some manual effort.

1 Like

I’ve managed to make it work using the following code

<?php

namespace ClientName\Site\GridField;

use SilverStripe\Core\Environment;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\Config\Config;
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_URLHandler;
use SilverStripe\Forms\GridField\GridField_FormAction;

use ClientName\Site\BehanceProject;
use ClientName\Site\BehanceProjectModule;

/**
 * Adds an "Export list" button to the bottom of a {@link GridField}.
 */
class GridFieldImportFromBehanceButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
{
    /**
     * Fragment to write the button to
     */
    protected $targetFragment;


    /**
     * @param string $targetFragment The HTML fragment to write the button into
     * @param array $exportColumns The columns to include in the export
     */
    public function __construct($targetFragment = "buttons-before-left")
    {
        $this->targetFragment = $targetFragment;
    }

    /**
     * Place the export button in a <p> tag below the field
     *
     * @param GridField $gridField
     * @return array
     */
    public function getHTMLFragments($gridField)
    {
        $button = new GridField_FormAction(
            $gridField,
            'import_behance',
            'Import from Behance',
            'import_behance',
            null
        );
        $button->addExtraClass('btn btn-secondary no-ajax font-icon-down-circled');
        $button->setForm($gridField->getForm());
        return array(
            $this->targetFragment => $button->Field()
        );
    }

    /**
     * export is an action button
     *
     * @param GridField $gridField
     * @return array
     */
    public function getActions($gridField)
    {
        return array('import_behance');
    }

    public function handleAction(GridField $gridField, $actionName, $arguments, $data)
    {
        if ($actionName == 'import_behance') {
            return $this->handleImportFromBehance($gridField);
        }
        return null;
    }

    /**
     * it is also a URL
     *
     * @param GridField $gridField
     * @return array
     */
    public function getURLHandlers($gridField)
    {
        return array(
            'import_behance' => 'handleImportFromBehance',
        );
    }

    /**
     * Handle the export, for both the action button and the URL
     *
     * @param GridField $gridField
     * @param HTTPRequest $request
     * @return HTTPResponse
     */
    public function handleImportFromBehance($gridField, HTPRequest $request = null)
    {
        $url = 'https://api.behance.net/v2/users/ClientName/projects?client_id=' . Environment::getEnv('BEHANCE_API_KEY');
        //  Initiate curl
        $ch = curl_init();
        // Disable SSL verification
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // Will return the response, if false it print the response
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // Set the url
        curl_setopt($ch, CURLOPT_URL,$url);
        // Execute
        $result=curl_exec($ch);
        // Closing
        curl_close($ch);

        // Will dump a beauty json :3
        // return json_decode($result, true);
        $data = json_decode($result, true);
        foreach($data['projects'] as $item) {
            $project = BehanceProject::get()->filter([
                'BehanceID' => $item['id']
            ])->first();

            if(!$project) {
                $project = BehanceProject::create();
                $project->BehanceID = $item['id'];
                $project->Name = $item['name'];
            }
            $project->BehanceName = $item['name'];
            $project->Cover = $item['covers']['original'];

            $project_url = "https://www.behance.net/v2/projects/" .  $item['id'] . "?api_key=" . Environment::getEnv('BEHANCE_API_KEY');
            //  Initiate curl
            $ch = curl_init();
            // Disable SSL verification
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            // Will return the response, if false it print the response
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            // Set the url
            curl_setopt($ch, CURLOPT_URL,$project_url);
            // Execute
            $result=curl_exec($ch);
            // Closing
            curl_close($ch);

            $data = json_decode($result, true);
            $project_item = $data['project'];

            // borrar modulos actuales
            $project->Modules()->removeAll();
            $counter = 1;
            foreach($project_item['modules'] as $module) {
                if($module['type'] === 'image') {
                    $project_module = BehanceProjectModule::create();
                    $project_module->Image = $module['sizes']['original'];
                    $project_module->Order = $counter;
                    $project_module->write();
                    $project->Modules()->add($project_module);
                    $counter++;
                }
            }


            $project->write();
        }
        $response = HTTPResponse::create();
        $response->redirect($_SERVER['HTTP_REFERER']);
        return $response;
    }

}

Thanks for your help!

1 Like