Kaynağa Gözat

Merge branch 'master' of ssh://200.50.168.30:222/VendorSoftwareFlowdat3/Webservice

Maximiliano Schvindt 8 yıl önce
ebeveyn
işleme
fdc321fc2e

+ 37 - 0
Controller/WebserviceController.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace WebserviceBundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+class WebserviceController extends Controller
+{
+
+    /**
+     * @param Request $request
+     * @return JsonResponse
+     */
+    public function getClientListAction(Request $request)
+    {
+        $query = $request->query->get('q', '');
+
+        $choice_loader = $this->get('webservice.client.choiceloader');
+        $choice_list = $choice_loader->getChoicesList($query);
+        $list_values = [];
+
+        foreach ($choice_list as $label => $id) {
+            $list_values[] = [
+                'id' => $id,
+                'text' => $label
+            ];
+        }
+
+        $response = new JsonResponse();
+        $response->setData(['results' => $list_values]);
+
+        return $response;
+    }
+
+}

+ 200 - 0
Form/ChoiceList/Loader/ClientChoiceLoader.php

@@ -0,0 +1,200 @@
+<?php
+
+namespace WebserviceBundle\Form\ChoiceList\Loader;
+
+use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
+use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\FormEvent;
+use Symfony\Component\Form\FormEvents;
+
+class ClientChoiceLoader implements ChoiceLoaderInterface
+{
+    
+    /**
+     * @var Webservice
+     */
+    protected $webservice;
+
+    // Currently selected choices
+    protected $selected = [];
+
+    
+    /**
+     * @param Webservice $webservice
+     */
+    public function __construct($webservice)
+    {
+        $this->webservice = $webservice;
+    }
+    
+    /**
+     * @param FormBuilderInterface $builder
+     */
+    public function setBuilder(FormBuilderInterface $builder)
+    {
+        if (is_object($builder) && ($builder instanceof FormBuilderInterface)) {
+            $builder->addEventListener(
+                FormEvents::POST_SET_DATA, [$this, 'onFormPostSetData']
+            );
+
+            $builder->addEventListener(
+                FormEvents::POST_SUBMIT, [$this, 'onFormPostSetData']
+            );
+        }
+    }
+
+    /**
+     * Form submit event callback
+     * Here we get notified about the submitted choices.
+     * Remember them so we can add them in loadChoiceList().
+     */
+    public function onFormPostSetData(FormEvent $event)
+    {
+        $this->selected = [];
+
+        $formdata = $event->getData();
+
+        if (!is_object($formdata)) {
+            return;
+        }
+
+        if ($formdata->getClientId()) {
+            $this->selected = array($formdata->getClientId());
+        }
+    }
+
+    /**
+     * Choices to be displayed in the SELECT element.
+     * It's okay to not return all available choices, but the
+     * selected/submitted choices (model values) must be
+     * included.
+     * Required by ChoiceLoaderInterface.
+     */
+    public function loadChoiceList($value = null)
+    {
+        $choices = $this->getChoicesList(false);
+
+        $missing_choices = array_flip($this->selected);
+
+        foreach ($choices as $label => $id) {
+            if (isset($missing_choices[$id])) {
+                unset($missing_choices[$id]);
+            }
+        }
+
+        // Now add selected choices if they're missing
+        foreach (array_keys($missing_choices) as $id) {
+            $label = $this->getChoiceLabel($id);
+
+            if (strlen($label) === 0) {
+                continue;
+            }
+
+            $choices[$label] = $id;
+        }
+        
+        return new ArrayChoiceList($choices);
+    }
+
+    /**
+     * Validate submitted choices, and turn them from strings
+     * (HTML option values) into other datatypes if needed
+     * (not needed here since our choices are strings).
+     * We're also using this place for creating new choices
+     * from new values typed into the autocomplete field.
+     * Required by ChoiceLoaderInterface.
+     */
+    public function loadChoicesForValues(array $values, $value = null)
+    {
+        $result = [];
+        foreach ($values as $id) {
+            if ($this->choiceExists($id)) {
+                $result[] = $id;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Turn choices from other datatypes into strings (HTML option
+     * values) if needed - we can simply return the choices as 
+     * they're strings already.
+     * Required by ChoiceLoaderInterface.
+     */
+    public function loadValuesForChoices(array $choices, $value = null)
+    {
+        $result = [];
+        foreach ($choices as $id) {
+            if ($this->choiceExists($id)) {
+                $result[] = $id;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get first n choices
+     */
+    public function getChoicesList($filter)
+    {
+        $params = array();
+        if ($filter !== false) {
+            $params['name'] = $filter;
+        }
+        $choices = $this->webservice->getChoices('client', $params);
+
+        $result = [];
+        $cnt = 0;
+        $limit = 10;
+        $filter = mb_strtolower($filter);
+        $filter_len = mb_strlen($filter);
+
+        foreach ($choices as $label => $id) {
+            if ($filter_len > 0) {
+                if (mb_substr(mb_strtolower($label), 0, $filter_len) !== $filter) {
+                    continue;
+                }
+            }
+
+            $result[$label] = $id;
+
+            if (++$cnt >= $limit) {
+                break;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Validate whether a choice exists
+     */
+    protected function choiceExists($id)
+    {
+        $label = array_search($id, $this->initChoices());
+
+        return $label === false ? false : true;
+    }
+
+    /**
+     * Get choice label
+     */
+    protected function getChoiceLabel($id)
+    {
+        $label = array_search($id, $this->initChoices());
+
+        return $label === false ? false : $label;
+    }
+
+    /**
+     * @return array
+     */
+    protected function initChoices()
+    {
+        return $this->webservice->getChoices('client');
+    }
+
+}

+ 43 - 0
Form/Type/RemoteClientType.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace WebserviceBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+use WebserviceBundle\Form\ChoiceList\Loader\ClientChoiceLoader;
+
+class RemoteClientType extends AbstractType
+{
+
+    /**
+     * @var ClientChoiceLoader 
+     */
+    protected $choiceLoader;
+
+    
+    /**
+     * @param ClientChoiceLoader $choiceLoader
+     */
+    public function __construct(ClientChoiceLoader $choiceLoader)
+    {
+        $this->choiceLoader = $choiceLoader;
+    }
+
+    /**
+     * @param OptionsResolver $resolver
+     */
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults(array(
+            'required' => false,
+            'choice_loader' => $this->choiceLoader
+        ));
+    }
+
+    public function getParent()
+    {
+        return ChoiceType::class;
+    }
+
+}

+ 3 - 0
Resources/config/routing.yml

@@ -0,0 +1,3 @@
+ajax_client_list:
+    path:      /ajax_client_list
+    defaults:  { _controller: WebserviceBundle:Webservice:getClientList }

+ 25 - 1
Resources/config/services.yml

@@ -1,4 +1,28 @@
 services:
+    
    webservice:
        class: WebserviceBundle\Services\Webservice
-       arguments: ["@service_container"]
+       arguments: ["@service_container"]
+       
+   webservice.client.choiceloader:
+       class: WebserviceBundle\Form\ChoiceList\Loader\ClientChoiceLoader
+       arguments: ["@webservice"]
+       
+   webservice.client.admin:
+       class: WebserviceBundle\Services\ClientAdmin
+       tags:
+           - { name: kernel.event_listener, event: sonata.admin.event.configure.form, method: addType }
+           - { name: kernel.event_listener, event: sonata.admin.event.configure.show, method: addClient }
+           - { name: kernel.event_listener, event: sonata.admin.event.configure.list, method: addClient }
+            
+   webservice.form.type.remoteclient:
+       class: WebserviceBundle\Form\Type\RemoteClientType
+       arguments: ["@webservice.client.choiceloader"]
+       tags:
+           - { name: form.type }
+            
+   webservice.twig_remote_client_extension:
+       class: WebserviceBundle\Twig\RemoteClientExtension
+       arguments: ["@webservice"]
+       tags:
+           - { name: twig.extension }

+ 5 - 0
Resources/views/CRUD/remote_client_field.html.twig

@@ -0,0 +1,5 @@
+{% extends "SonataAdminBundle:CRUD:base_#{field_description.options.data}_field.html.twig" %}
+
+{% block field %}
+    {{ remote_client(value) }}
+{% endblock %}

+ 0 - 1
Resources/views/Default/index.html.twig

@@ -1 +0,0 @@
-Hello World!

+ 39 - 0
Resources/views/Type/remote_client_widget.html.twig

@@ -0,0 +1,39 @@
+{% block remote_client_widget %}
+    {% spaceless %}
+        {% set locale = app.request.locale %}
+        {# SE AGREGA UNA VERSION DE SELECT2 MAS NUEVA QUE LA DE SONATA ADMIN #}
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
+        <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/i18n/{{ locale }}.js"></script>
+        <style type="text/css">
+            .select2-selection.select2-selection--single {
+                height: 34px;
+            }
+        </style>
+        <script type="text/javascript">
+        $(function () {
+            var getAjaxListData = function (params) {
+                return {
+                    q: params.term,
+                    p: params.page
+                };
+            };
+
+            $('select[id$="clientId"]').select2({
+                ajax: {
+                    url: '{{ path('ajax_client_list') }}',
+                    dataType: 'json',
+                    delay: 250,
+                    data: getAjaxListData,
+                    cache: true
+                },
+                language: "{{ locale }}",
+                debug: true,        
+                minimumInputLength: 3
+            });
+        });
+        </script>
+        {{ block('choice_widget') }}
+    {% endspaceless %}
+{% endblock %}

+ 32 - 0
Services/ClientAdmin.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace WebserviceBundle\Services;
+
+use Sonata\AdminBundle\Event\ConfigureEvent;
+use WebserviceBundle\Form\Type\RemoteClientType;
+
+class ClientAdmin
+{
+
+    /**
+     * @param ConfigureEvent $event
+     */
+    public function addType(ConfigureEvent $event)
+    {
+        if ($event->getMapper()->has('clientId')) {
+            $event->getMapper()->add('clientId', RemoteClientType::class);
+        }
+    }
+    
+    /**
+     * @param ConfigureEvent $event
+     */
+    public function addClient(ConfigureEvent $event)
+    {
+        if ($event->getMapper()->has('clientId')) {
+            $event->getMapper()->get('clientId')->setTemplate('WebserviceBundle:CRUD:remote_client_field.html.twig');
+            $event->getMapper()->get('clientId')->setOption('data', $event->getType());
+        }
+    }
+
+}

+ 22 - 5
Services/Webservice.php

@@ -21,15 +21,32 @@ class Webservice
     public function getChoices($webservice, $params = array())
     {
         $choices = array();
+        $objectsJson = $this->getArray($webservice, $params);
+        foreach ($objectsJson as $object) {
+            $choices[$object['name']] = $object['id'];
+        }
+
+        return $choices;
+    }
+    
+    /**
+     * @param string $webservice
+     * @param array $params
+     * @return array
+     */
+    public function getArray($webservice, $params = array())
+    {
+        $objectsJson = array();
         if ($this->serviceContainer->hasParameter($webservice)) {
             $url = $this->serviceContainer->getParameter($webservice);
-            $objectsJson = json_decode(file_get_contents($url), true);
-            foreach ($objectsJson as $object) {
-                $choices["{$object['name']} - {$object['external_id']}"] = $object['id'];
+            $url .= '?filters[qb-criteria]';
+            foreach ($params as $param => $value) {
+                $url .= "&filters[{$param}]=$value";
             }
+            $objectsJson = json_decode(file_get_contents($url), true);
         }
-
-        return $choices;
+        
+        return $objectsJson;
     }
 
     /**

+ 55 - 0
Twig/RemoteClientExtension.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace WebserviceBundle\Twig;
+
+use WebserviceBundle\Services\Webservice;
+
+class RemoteClientExtension extends \Twig_Extension
+{
+    
+    /**
+     * @var Webservice
+     */
+    protected $webservice;
+    
+    
+    /**
+     * @param Webservice $webservice
+     */
+    public function __construct(Webservice $webservice)
+    {
+        $this->webservice = $webservice;
+    }
+
+    /**
+     * @return array
+     */
+    public function getFunctions()
+    {
+        return array(
+            new \Twig_SimpleFunction('remote_client', array($this, 'getClient')),
+        );
+    }
+
+    /**
+     * @param int $clientId
+     * @return string
+     */
+    public function getClient($clientId)
+    {
+        $client = $this->webservice->getArray('client', array(
+            'id' => $clientId
+        ));
+        
+        return isset($client[0]) ? "{$client[0]['id']} - {$client[0]['name']}" : $clientId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return 'remote_client_extension';
+    }
+
+}