当前位置: 首页>>代码示例>>PHP>>正文


PHP RouteProviderInterface::getRouteByName方法代码示例

本文整理汇总了PHP中Drupal\Core\Routing\RouteProviderInterface::getRouteByName方法的典型用法代码示例。如果您正苦于以下问题:PHP RouteProviderInterface::getRouteByName方法的具体用法?PHP RouteProviderInterface::getRouteByName怎么用?PHP RouteProviderInterface::getRouteByName使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Drupal\Core\Routing\RouteProviderInterface的用法示例。


在下文中一共展示了RouteProviderInterface::getRouteByName方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。

示例1: canRedirect

 /**
  * Determines if redirect may be performed.
  *
  * @param Request $request
  *   The current request object.
  * @param string $route_name
  *   The current route name.
  *
  * @return bool
  *   TRUE if redirect may be performed.
  */
 public function canRedirect(Request $request, $route_name = NULL)
 {
     $can_redirect = TRUE;
     if (isset($route_name)) {
         $route = $this->routeProvider->getRouteByName($route_name);
         if ($this->config->get('access_check')) {
             // Do not redirect if is a protected page.
             $can_redirect &= $this->accessManager->check($route, $request, $this->account);
         }
     } else {
         $route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT);
     }
     if (strpos($request->getScriptName(), 'index.php') === FALSE) {
         // Do not redirect if the root script is not /index.php.
         $can_redirect = FALSE;
     } elseif (!($request->isMethod('GET') || $request->isMethod('HEAD'))) {
         // Do not redirect if this is other than GET request.
         $can_redirect = FALSE;
     } elseif ($this->state->get('system.maintenance_mode') || defined('MAINTENANCE_MODE')) {
         // Do not redirect in offline or maintenance mode.
         $can_redirect = FALSE;
     } elseif ($this->config->get('ignore_admin_path') && isset($route)) {
         // Do not redirect on admin paths.
         $can_redirect &= !(bool) $route->getOption('_admin_route');
     }
     return $can_redirect;
 }
开发者ID:isramv,项目名称:camp-gdl,代码行数:38,代码来源:RedirectChecker.php

示例2: getRouteParameters

 /**
  * {@inheritdoc}
  */
 public function getRouteParameters(RouteMatchInterface $route_match)
 {
     $parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array();
     $route = $this->routeProvider->getRouteByName($this->getRouteName());
     $variables = $route->compile()->getVariables();
     // Normally the \Drupal\Core\ParamConverter\ParamConverterManager has
     // processed the Request attributes, and in that case the _raw_variables
     // attribute holds the original path strings keyed to the corresponding
     // slugs in the path patterns. For example, if the route's path pattern is
     // /filter/tips/{filter_format} and the path is /filter/tips/plain_text then
     // $raw_variables->get('filter_format') == 'plain_text'.
     $raw_variables = $route_match->getRawParameters();
     foreach ($variables as $name) {
         if (isset($parameters[$name])) {
             continue;
         }
         if ($raw_variables && $raw_variables->has($name)) {
             $parameters[$name] = $raw_variables->get($name);
         } elseif ($value = $route_match->getRawParameter($name)) {
             $parameters[$name] = $value;
         }
     }
     // The UrlGenerator will throw an exception if expected parameters are
     // missing. This method should be overridden if that is possible.
     return $parameters;
 }
开发者ID:sojo,项目名称:d8_friendsofsilence,代码行数:29,代码来源:LocalActionDefault.php

示例3: canRedirect

 /**
  * Checks access to the route.
  *
  * @param string $route_name
  *   The current route name.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The current request.
  *
  * @return bool
  *   TRUE if access is granted.
  */
 public function canRedirect($route_name, Request $request)
 {
     $do_redirect = TRUE;
     /** @var \Symfony\Component\Routing\Route $route */
     $route = $this->routeProvider->getRouteByName($route_name);
     if ($this->config->get('access_check')) {
         $do_redirect &= $this->accessManager->check($route, $request, $this->account);
     }
     if ($this->config->get('ignore_admin_path')) {
         $do_redirect &= !(bool) $route->getOption('_admin_route');
     }
     return $do_redirect;
 }
开发者ID:Progressable,项目名称:openway8,代码行数:24,代码来源:RedirectChecker.php

示例4: getBaseRoute

 /**
  * {@inheritdoc}
  */
 public function getBaseRoute()
 {
     if ($this->routeCollection) {
         return $this->routeCollection->get($this->getBaseRouteName());
     } else {
         return $this->routeProvider->getRouteByName($this->getBaseRouteName());
     }
 }
开发者ID:ddrozdik,项目名称:dmaps,代码行数:11,代码来源:ConfigNamesMapper.php

示例5: checkNamedRoute

 /**
  * {@inheritdoc}
  */
 public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account = NULL, $return_as_object = FALSE)
 {
     try {
         $route = $this->routeProvider->getRouteByName($route_name, $parameters);
         // ParamConverterManager relies on the route object being available
         // from the parameters array.
         $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route;
         $upcasted_parameters = $this->paramConverterManager->convert($parameters + $route->getDefaults());
         $route_match = new RouteMatch($route_name, $route, $upcasted_parameters, $parameters);
         return $this->check($route_match, $account, NULL, $return_as_object);
     } catch (RouteNotFoundException $e) {
         // Cacheable until extensions change.
         $result = AccessResult::forbidden()->addCacheTags(array('extension'));
         return $return_as_object ? $result : $result->isAllowed();
     } catch (ParamNotConvertedException $e) {
         // Uncacheable because conversion of the parameter may not have been
         // possible due to dynamic circumstances.
         $result = AccessResult::forbidden()->setCacheable(FALSE);
         return $return_as_object ? $result : $result->isAllowed();
     }
 }
开发者ID:davidsoloman,项目名称:drupalconsole.com,代码行数:24,代码来源:AccessManager.php

示例6: login

 /**
  * Logs in a user.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   A response which contains the ID and CSRF token.
  */
 public function login(Request $request)
 {
     $format = $this->getRequestFormat($request);
     $content = $request->getContent();
     $credentials = $this->serializer->decode($content, $format);
     if (!isset($credentials['name']) && !isset($credentials['pass'])) {
         throw new BadRequestHttpException('Missing credentials.');
     }
     if (!isset($credentials['name'])) {
         throw new BadRequestHttpException('Missing credentials.name.');
     }
     if (!isset($credentials['pass'])) {
         throw new BadRequestHttpException('Missing credentials.pass.');
     }
     $this->floodControl($request, $credentials['name']);
     if ($this->userIsBlocked($credentials['name'])) {
         throw new BadRequestHttpException('The user has not been activated or is blocked.');
     }
     if ($uid = $this->userAuth->authenticate($credentials['name'], $credentials['pass'])) {
         $this->flood->clear('user.http_login', $this->getLoginFloodIdentifier($request, $credentials['name']));
         /** @var \Drupal\user\UserInterface $user */
         $user = $this->userStorage->load($uid);
         $this->userLoginFinalize($user);
         // Send basic metadata about the logged in user.
         $response_data = [];
         if ($user->get('uid')->access('view', $user)) {
             $response_data['current_user']['uid'] = $user->id();
         }
         if ($user->get('roles')->access('view', $user)) {
             $response_data['current_user']['roles'] = $user->getRoles();
         }
         if ($user->get('name')->access('view', $user)) {
             $response_data['current_user']['name'] = $user->getAccountName();
         }
         $response_data['csrf_token'] = $this->csrfToken->get('rest');
         $logout_route = $this->routeProvider->getRouteByName('user.logout.http');
         // Trim '/' off path to match \Drupal\Core\Access\CsrfAccessCheck.
         $logout_path = ltrim($logout_route->getPath(), '/');
         $response_data['logout_token'] = $this->csrfToken->get($logout_path);
         $encoded_response_data = $this->serializer->encode($response_data, $format);
         return new Response($encoded_response_data);
     }
     $flood_config = $this->config('user.flood');
     if ($identifier = $this->getLoginFloodIdentifier($request, $credentials['name'])) {
         $this->flood->register('user.http_login', $flood_config->get('user_window'), $identifier);
     }
     // Always register an IP-based failed login event.
     $this->flood->register('user.failed_login_ip', $flood_config->get('ip_window'));
     throw new BadRequestHttpException('Sorry, unrecognized username or password.');
 }
开发者ID:eigentor,项目名称:tommiblog,代码行数:59,代码来源:UserAuthenticationController.php

示例7: checkNamedRoute

 /**
  * Checks a named route with parameters against applicable access check services.
  *
  * Determines whether the route is accessible or not.
  *
  * @param string $route_name
  *   The route to check access to.
  * @param array $parameters
  *   Optional array of values to substitute into the route path patern.
  * @param \Drupal\Core\Session\AccountInterface $account
  *   The current user.
  * @param \Symfony\Component\HttpFoundation\Request $route_request
  *   Optional incoming request object. If not provided, one will be built
  *   using the route information and the current request from the container.
  *
  * @return bool
  *   Returns TRUE if the user has access to the route, otherwise FALSE.
  */
 public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL)
 {
     try {
         $route = $this->routeProvider->getRouteByName($route_name, $parameters);
         if (empty($route_request)) {
             // Create a request and copy the account from the current request.
             $defaults = $parameters + $route->getDefaults();
             $route_request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), $this->urlGenerator->generate($route_name, $defaults));
             $defaults[RouteObjectInterface::ROUTE_OBJECT] = $route;
             $route_request->attributes->add($this->paramConverterManager->convert($defaults, $route_request));
         }
         return $this->check($route, $route_request, $account);
     } catch (RouteNotFoundException $e) {
         return FALSE;
     } catch (ParamNotConvertedException $e) {
         return FALSE;
     }
 }
开发者ID:alnutile,项目名称:drunatra,代码行数:36,代码来源:AccessManager.php

示例8: checkNamedRoute

 /**
  * {@inheritdoc}
  */
 public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL)
 {
     try {
         $route = $this->routeProvider->getRouteByName($route_name, $parameters);
         if (empty($route_request)) {
             // Create a cloned request with fresh attributes.
             $route_request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), $this->urlGenerator->generate($route_name, $parameters));
             $route_request->attributes->replace(array());
             // Populate $route_request->attributes with both raw and converted
             // parameters.
             $parameters += $route->getDefaults();
             $route_request->attributes->set('_raw_variables', new ParameterBag($parameters));
             $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route;
             $route_request->attributes->add($this->paramConverterManager->convert($parameters, $route_request));
         }
         return $this->check($route, $route_request, $account);
     } catch (RouteNotFoundException $e) {
         return FALSE;
     } catch (ParamNotConvertedException $e) {
         return FALSE;
     }
 }
开发者ID:anatalsceo,项目名称:en-classe,代码行数:25,代码来源:AccessManager.php

示例9: getDerivativeDefinitions

 /**
  * Implements DerivativeInterface::getDerivativeDefinitions().
  */
 public function getDerivativeDefinitions($base_plugin_definition)
 {
     if (!isset($this->derivatives)) {
         // Add in the default plugin configuration and the resource type.
         foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
             $this->derivatives[$entity_type_id] = array('id' => 'entity:' . $entity_type_id, 'entity_type' => $entity_type_id, 'serialization_class' => $entity_type->getClass(), 'label' => $entity_type->getLabel());
             $default_uris = array('canonical' => "/entity/{$entity_type_id}/" . '{' . $entity_type_id . '}', 'http://drupal.org/link-relations/create' => "/entity/{$entity_type_id}");
             foreach ($default_uris as $link_relation => $default_uri) {
                 // Check if there are link templates defined for the entity type and
                 // use the path from the route instead of the default.
                 if ($route_name = $entity_type->getLinkTemplate($link_relation)) {
                     // @todo remove the try/catch as part of
                     // http://drupal.org/node/2158571
                     try {
                         $route = $this->routeProvider->getRouteByName($route_name);
                         $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath();
                     } catch (RouteNotFoundException $e) {
                         if (($collection = $this->routeBuilder->getCollectionDuringRebuild()) && ($route = $collection->get($route_name))) {
                             $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath();
                         } else {
                             // If the route does not exist it means we are in a brittle state
                             // of module enabling/disabling, so we simply exclude this entity
                             // type.
                             unset($this->derivatives[$entity_type_id]);
                             // Continue with the next entity type;
                             continue 2;
                         }
                     }
                 } else {
                     $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $default_uri;
                 }
             }
             $this->derivatives[$entity_type_id] += $base_plugin_definition;
         }
     }
     return $this->derivatives;
 }
开发者ID:anatalsceo,项目名称:en-classe,代码行数:40,代码来源:EntityDerivative.php

示例10: testDynamicRoutes

 /**
  * Tests dynamic routes.
  */
 public function testDynamicRoutes()
 {
     $this->installConfig(['entity_browser_test']);
     $this->container->get('router.builder')->rebuild();
     /** @var $entity \Drupal\entity_browser\EntityBrowserInterface */
     $entity = $this->controller->load('test');
     $route = $entity->route();
     $this->assertEquals($route->getPath(), '/entity-browser/test', 'Dynamic path matches.');
     $this->assertEquals($route->getDefault('entity_browser_id'), $entity->id(), 'Entity browser ID matches.');
     $this->assertEquals($route->getDefault('_controller'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::page', 'Controller matches.');
     $this->assertEquals($route->getDefault('_title_callback'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::title', 'Title callback matches.');
     $this->assertEquals($route->getRequirement('_permission'), 'access ' . $entity->id() . ' entity browser pages', 'Permission matches.');
     try {
         $registered_route = $this->routeProvider->getRouteByName('entity_browser.' . $entity->id());
     } catch (\Exception $e) {
         $this->fail(t('Expected route not found: @message', array('@message' => $e->getMessage())));
         return;
     }
     $this->assertEquals($registered_route->getPath(), '/entity-browser/test', 'Dynamic path matches.');
     $this->assertEquals($registered_route->getDefault('entity_browser_id'), $entity->id(), 'Entity browser ID matches.');
     $this->assertEquals($registered_route->getDefault('_controller'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::page', 'Controller matches.');
     $this->assertEquals($registered_route->getDefault('_title_callback'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::title', 'Title callback matches.');
     $this->assertEquals($registered_route->getRequirement('_permission'), 'access ' . $entity->id() . ' entity browser pages', 'Permission matches.');
 }
开发者ID:DrupalTV,项目名称:DrupalTV,代码行数:27,代码来源:EntityBrowserTest.php

示例11: getUrl

 /**
  * Get the URL for the current view.
  *
  * This URL will be adjusted for arguments.
  *
  * @param array $args
  *   (optional) Passed in arguments.
  * @param string $display_id
  *   (optional) Specify the display ID to link to, fallback to the current ID.
  *
  * @return \Drupal\Core\Url
  */
 public function getUrl($args = NULL, $display_id = NULL)
 {
     if (!empty($this->override_url)) {
         return $this->override_url;
     }
     if (!isset($path)) {
         $path = $this->getPath();
     }
     $display_handler = $this->displayHandlers->get($display_id ?: $this->current_display)->getRoutedDisplay();
     if (!$display_handler instanceof DisplayRouterInterface) {
         throw new \InvalidArgumentException('You cannot create a URL to a display without routes.');
     }
     if (!isset($args)) {
         $args = $this->args;
         // Exclude arguments that were computed, not passed on the URL.
         $position = 0;
         if (!empty($this->argument)) {
             foreach ($this->argument as $argument) {
                 if (!empty($argument->is_default) && !empty($argument->options['default_argument_skip_url'])) {
                     unset($args[$position]);
                 }
                 $position++;
             }
         }
     }
     // Don't bother working if there's nothing to do:
     if (empty($path) || empty($args) && strpos($path, '%') === FALSE) {
         return $display_handler->getUrlInfo();
     }
     $argument_keys = isset($this->argument) ? array_keys($this->argument) : array();
     $id = current($argument_keys);
     /** @var \Drupal\Core\Url $url */
     $url = $display_handler->getUrlInfo();
     $route = $this->routeProvider->getRouteByName($url->getRouteName());
     $variables = $route->compile()->getVariables();
     $parameters = $url->getRouteParameters();
     foreach ($variables as $variable_name) {
         if (empty($args)) {
             // Try to never put % in a URL; use the wildcard instead.
             if ($id && !empty($this->argument[$id]->options['exception']['value'])) {
                 $parameters[$variable_name] = $this->argument[$id]->options['exception']['value'];
             } else {
                 // Provide some fallback in case no exception value could be found.
                 $parameters[$variable_name] = '*';
             }
         } else {
             $parameters[$variable_name] = array_shift($args);
         }
         if ($id) {
             $id = next($argument_keys);
         }
     }
     $url->setRouteParameters($parameters);
     return $url;
 }
开发者ID:nsp15,项目名称:Drupal8,代码行数:67,代码来源:ViewExecutable.php

示例12: buildRow

 /**
  * Builds a table row for the system modules page.
  *
  * @param array $modules
  *   The list existing modules.
  * @param \Drupal\Core\Extension\Extension $module
  *   The module for which to build the form row.
  * @param $distribution
  *
  * @return array
  *   The form row for the given module.
  */
 protected function buildRow(array $modules, Extension $module, $distribution)
 {
     // Set the basic properties.
     $row['#required'] = array();
     $row['#requires'] = array();
     $row['#required_by'] = array();
     $row['name']['#markup'] = $module->info['name'];
     $row['description']['#markup'] = $this->t($module->info['description']);
     $row['version']['#markup'] = $module->info['version'];
     // Generate link for module's help page, if there is one.
     $row['links']['help'] = array();
     if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) {
         if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) {
             $row['links']['help'] = array('#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))));
         }
     }
     // Generate link for module's permission, if the user has access to it.
     $row['links']['permissions'] = array();
     if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) {
         $row['links']['permissions'] = array('#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))));
     }
     // Generate link for module's configuration page, if it has one.
     $row['links']['configure'] = array();
     if ($module->status && isset($module->info['configure'])) {
         $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
         if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
             $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']);
             /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
             $link = reset($links);
             // Most configure links have a corresponding menu link, though some just
             // have a route.
             if ($link) {
                 $description = $link->getDescription();
             } else {
                 $request = new Request();
                 $request->attributes->set('_route_name', $module->info['configure']);
                 $route_object = $this->routeProvider->getRouteByName($module->info['configure']);
                 $request->attributes->set('_route', $route_object);
                 $request->attributes->add($route_parameters);
                 $description = $this->titleResolver->getTitle($request, $route_object);
             }
             $row['links']['configure'] = array('#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $description)));
         }
     }
     // Present a checkbox for installing and indicating the status of a module.
     $row['enable'] = array('#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status);
     // Disable the checkbox for required modules.
     if (!empty($module->info['required'])) {
         // Used when displaying modules that are required by the installation profile
         $row['enable']['#disabled'] = TRUE;
         $row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : '');
     }
     // Check the compatibilities.
     $compatible = TRUE;
     // Initialize an empty array of reasons why the module is incompatible. Add
     // each reason as a separate element of the array.
     $reasons = array();
     // Check the core compatibility.
     if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) {
         $compatible = FALSE;
         $reasons[] = $this->t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY));
     }
     // Ensure this module is compatible with the currently installed version of PHP.
     if (version_compare(phpversion(), $module->info['php']) < 0) {
         $compatible = FALSE;
         $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : '');
         $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $required, '!php_version' => phpversion()));
     }
     // If this module is not compatible, disable the checkbox.
     if (!$compatible) {
         $status = implode(' ', $reasons);
         $row['enable']['#disabled'] = TRUE;
         $row['description']['#markup'] = $status;
         $row['#attributes']['class'][] = 'incompatible';
     }
     // If this module requires other modules, add them to the array.
     foreach ($module->requires as $dependency => $version) {
         if (!isset($modules[$dependency])) {
             $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency)));
             $row['enable']['#disabled'] = TRUE;
         } elseif (empty($modules[$dependency]->hidden)) {
             $name = $modules[$dependency]->info['name'];
             // Disable the module's checkbox if it is incompatible with the
             // dependency's version.
             if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> version @version)', array('@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version']));
                 $row['enable']['#disabled'] = TRUE;
             } elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
//.........这里部分代码省略.........
开发者ID:brstde,项目名称:gap1,代码行数:101,代码来源:ModulesListForm.php


注:本文中的Drupal\Core\Routing\RouteProviderInterface::getRouteByName方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。