【问题标题】:Typo3 Extbase AJAX without page typenumTypo3 Extbase AJAX 没有页面 typenum
【发布时间】:2014-02-04 01:27:10
【问题描述】:

有什么方法可以在 Extbase 扩展中创建 AJAX 调用而不使用页面 typeNum?

【问题讨论】:

    标签: typo3 extbase


    【解决方案1】:

    编辑:

    Helmut Hummel,TYPO3 CMS 团队的成员,measured 表示将 EID 与 Extbase 一起使用比使用 typeNum 方法要慢。但是由于typeNum方式配置繁琐,所以他开发了第三种方式。

    扩展 typoscript_rendering 提供了一种无需额外配置即可直接调用 Extbase 操作的方法。它包含一个生成此类链接的 ViewHelper,可以在 Fluid 模板中像这样使用:

    {namespace h=Helhum\TyposcriptRendering\ViewHelpers}
    <script>
    var getParticipationsUri = '<h:uri.ajaxAction controller="Participation" action="listByCompetition" arguments="{competition:competition}" />';
    </script>
    

    这会生成一个 URI,它调用我的“ParticipationController”的“listByCompetition”操作。可以正常传递参数。

    唯一的缺点是出于安全原因,扩展使用 cHash 来验证请求参数。 cHash 由 GET 提交,但您不能同时通过 GET 传递其他参数,因为它会使 cHash 无效。所以如果你想在这样的请求中传递表单数据,你需要混合使用 GET(用于有效的 AJAX 调用)和 POST(用于提交用户数据):

    <script>
    var createAddressUri = '<h:uri.ajaxAction controller="Address" action="create" />';
    $body.on('submit', '#myForm', function(e) {
        e.preventDefault();
        emailAddress = $('#myForm').find('#email');
        if (typeof(emailAddress) === 'string') {
            $.ajax({
                url: createAddressUri,
                type: 'POST',
                data: { 'tx_myext_pluginname[address][email]' : emailAddress},
                success: function() {
                  // things to do on success
                }
            })
        }
    });
    </script>
    

    (当然这只是一个非常基本的示例。您可以发布整个模型等)

    EID方式:

    是的,您可以为此使用 EID(扩展 ID)机制。没有官方声明应该使用哪种方式(pageType 或 eID)来进行 Extbase AJAX 调用,这似乎只是一个口味问题。

    here 有一个不错的教程,我将源代码复制到这里:

    <?php
    
    /** *************************************************************
     *
     * Extbase Dispatcher for Ajax Calls TYPO3 6.1 namespaces
     *
     * IMPORTANT Use this script only in Extensions with namespaces
     *
     * Klaus Heuer <klaus.heuer@t3-developer.com>
     *
     * This script is part of the TYPO3 project. The TYPO3 project is
     * free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * The GNU General Public License can be found at
     * http://www.gnu.org/copyleft/gpl.html.
     *
     * This script is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details.
     *
     * This copyright notice MUST APPEAR in all copies of the script!
     * ************************************************************* */
    
    /** ************************************************************
     * Usage of this script:
     *
     * - Copy this script in your Extension Dir in the Folder Classes
     * - Set the Vendor and Extension Name in Line 82 + 83
     * - Include the next line in the ext_localconf.php, change the ext name!
     * - $TYPO3_CONF_VARS['FE']['eID_include']['ajaxDispatcher'] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('myExtension').'Classes/EidDispatcher.php';
     *
     * Use for Ajax Calls in your jQuery Code:
     *
     *     $('.jqAjax').click(function(e)  {
     *       var uid = $(this).find('.uid').html();
     *       var storagePid = '11';
     *      
     *       $.ajax({
     *           async: 'true',
     *           url: 'index.php',      
     *           type: 'POST', 
     *        
     *           data: {
     *               eID: "ajaxDispatcher",  
     *               request: {
     *                   pluginName:  'patsystem',
     *                   controller:  'Todo',
     *                   action:      'findTodoByAjax',
     *                   arguments: {
     *                       'uid': uid,
     *                       'storagePid': storagePid
     *                   }
     *               }
     *           },
     *           dataType: "json",      
     *          
     *           success: function(result) {
     *               console.log(result);
     *           },
     *           error: function(error) {
     *              console.log(error);               
     *           }
     *       });
     *************************************************************** */
    
    
    /**
     * Gets the Ajax Call Parameters
     */
    $ajax = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('request');
    
    /**
     * Set Vendor and Extension Name
     *
     * Vendor Name like your Vendor Name in namespaces
     * ExtensionName in upperCamelCase
     */
    $ajax['vendor'] = 'T3Developer';
    $ajax['extensionName'] = 'ProjectsAndTasks';
    
    /**
     * @var $TSFE \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
     */
    $TSFE = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController', $TYPO3_CONF_VARS, 0, 0);
    \TYPO3\CMS\Frontend\Utility\EidUtility::initLanguage();
    
    // Get FE User Information
    $TSFE->initFEuser();
    // Important: no Cache for Ajax stuff
    $TSFE->set_no_cache();
    
    //$TSFE->checkAlternativCoreMethods();
    $TSFE->checkAlternativeIdMethods();
    $TSFE->determineId();
    $TSFE->initTemplate();
    $TSFE->getConfigArray();
    \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadConfigurationAndInitialize();
    
    $TSFE->cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
    $TSFE->settingLanguage();
    $TSFE->settingLocale();
    
    /**
     * Initialize Database
     */
    \TYPO3\CMS\Frontend\Utility\EidUtility::connectDB();
    
    /**
     * @var $objectManager \TYPO3\CMS\Extbase\Object\ObjectManager
     */
    $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
    
    
    /**
     * Initialize Extbase bootstap
     */
    $bootstrapConf['extensionName'] = $ajax['extensionName'];
    $bootstrapConf['pluginName'] = $ajax['pluginName'];
    
    $bootstrap = new TYPO3\CMS\Extbase\Core\Bootstrap();
    $bootstrap->initialize($bootstrapConf);
    
    $bootstrap->cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tslib_cObj');
    
    /**
     * Build the request
     */
    $request = $objectManager->get('TYPO3\CMS\Extbase\Mvc\Request');
    
    $request->setControllerVendorName($ajax['vendor']);
    $request->setcontrollerExtensionName($ajax['extensionName']);
    $request->setPluginName($ajax['pluginName']);
    $request->setControllerName($ajax['controller']);
    $request->setControllerActionName($ajax['action']);
    $request->setArguments($ajax['arguments']);
    
    $response = $objectManager->create('TYPO3\CMS\Extbase\Mvc\ResponseInterface');
    
    $dispatcher = $objectManager->get('TYPO3\CMS\Extbase\Mvc\Dispatcher');
    
    $dispatcher->dispatch($request, $response);
    
    echo $response->getContent();
    //die();
    ?>
    

    查看说明如何注册 eID 的“此脚本的用法”部分。该脚本适用于 TYPO3 6.1 及更高版本。

    【讨论】:

      【解决方案2】:

      用于测试扩展。

      在 ext_localconf.php 文件中包含 EID

      ## Ajax configuration
      $TYPO3_CONF_VARS['FE']['eID_include']['Test'] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('test').'Classes/Ajax/EidDispatcher.php';
      

      在类中创建目录——Classes/Ajax/EidDispatcher.php

      namespace TYPO3\Test\Ajax;
      
      class EidDispatcher {
          /**
         * @var \array
         */
          protected $configuration;
      
          /**
         * @var \array
         */
          protected $bootstrap;
      
          /**
         * The main Method
         *
         * @return \string
         */
          public function run() {
              return $this->bootstrap->run( '', $this->configuration );
          }
      
          /**
         * Initialize Extbase
         *
         * @param \array $TYPO3_CONF_VARS
         */
          public function __construct($TYPO3_CONF_VARS) {
      
              $ajaxRequest = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_Test_addhours');
      
              // create bootstrap
              $this->bootstrap = new \TYPO3\CMS\Extbase\Core\Bootstrap();
      
              // get User
              $feUserObj = \TYPO3\CMS\Frontend\Utility\EidUtility::initFeUser();
      
              // set PID
              $pid = (\TYPO3\CMS\Core\Utility\GeneralUtility::_GET( 'id' )) ? \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('id') : 1;
      
              // Create and init Frontend
              $GLOBALS['TSFE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( 'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController', $TYPO3_CONF_VARS, $pid, 0, TRUE );
              $GLOBALS['TSFE']->connectToDB();
              $GLOBALS['TSFE']->fe_user = $feUserObj;
              $GLOBALS['TSFE']->id = $pid;
              $GLOBALS['TSFE']->determineId();
              $GLOBALS['TSFE']->getCompressedTCarray(); //Comment this line when used for TYPO3 7.6.0 on wards
              $GLOBALS['TSFE']->initTemplate();
              $GLOBALS['TSFE']->getConfigArray();
              $GLOBALS['TSFE']->includeTCA(); //Comment this line when used for TYPO3 7.6.0 on wards
      
              // Get Plugins TypoScript
              $TypoScriptService = new \TYPO3\CMS\Extbase\Service\TypoScriptService();
              $pluginConfiguration = $TypoScriptService->convertTypoScriptArrayToPlainArray($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_Test.']);
      
              // Set configuration to call the plugin
              $this->configuration = array (
                      'pluginName' => $ajaxRequest['pluginName'],
                      'vendorName' => 'TYPO3',
                      'extensionName' => 'Test',
                      'controller' => $ajaxRequest['controller'],
                      'action' => $ajaxRequest['action'],
                      'mvc' => array (
                              'requestHandlers' => array (
                                      'TYPO3\CMS\Extbase\Mvc\Web\FrontendRequestHandler' => 'TYPO3\CMS\Extbase\Mvc\Web\FrontendRequestHandler'
                              )
                      ),
                      'settings' => $pluginConfiguration['settings'],
                      'persistence' => array (
                              'storagePid' => $pluginConfiguration['persistence']['storagePid']
                      )
              );
      
          }
      }
      global $TYPO3_CONF_VARS;
      // make instance of bootstrap and run
      $eid = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( 'TYPO3\Test\Ajax\EidDispatcher', $TYPO3_CONF_VARS );
      echo $eid->run();
      

      从脚本调用

      $.ajax({
          async: 'true',
          url: 'index.php',      
          type: 'GET', 
          data: {
              eID: "Test",  
              tx_ExtName_PluginName: {
                  pluginName:  'Plugin_Name',
                  controller:  'Controller_Name',
                  action:      'Action_Name',
              }
          },
          success:function(data){
              // code
          }
      });
      

      【讨论】:

        【解决方案3】:

        我使用了一种没有 typeNum 的快速且可能很脏的方法。 我使用 jQuery ajax 调用的常用方式。 我的目标操作以以下结束。

        $headers = DivUtilities::createHeader();
        foreach ($headers as $header => $data) {
            $this->response->setHeader($header, $data);
        }
        $this->response->sendHeaders();
        echo $this->view->render();
        exit;
        

        createHeader 方法

        /**
          *
          * @param string $type
          * @return array
          */
        public static function createHeader($type = 'html')
        {
          switch ($type) {
            case 'txt':
                    $cType   = 'text/plain';
                    break;
            case 'html':
                    $cType   = 'text/html';
                    break;
            case 'json':
                    $cType   = 'application/json';
                    break;
            case 'pdf':
                    $cType   = 'application/pdf';
                    break;
          }
          $headers = array(
                  'Pragma' => 'public',
                  'Expires' => 0,
                  'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
                  'Cache-Control' => 'public',
                  'Content-Type' => $cType
          );
          return $headers;
        }
        

        输出是被调用动作的模板。这可以是 html、json 或任何你需要的。

        【讨论】:

          【解决方案4】:

          我必须将 makeInstance 的第一个 0 更改为页面的 id 才能正常工作。

          $id = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id');
          $TSFE = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController', $TYPO3_CONF_VARS, $id, 0);
          

          【讨论】:

            【解决方案5】:

            对于 TYPO3 6.2 更改以下行:

            \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadConfigurationAndInitialize();
            

            \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-09-09
              • 2013-06-17
              • 1970-01-01
              • 2013-07-29
              • 1970-01-01
              • 1970-01-01
              • 2012-05-28
              相关资源
              最近更新 更多