title: Symfony 3 Twig\Extension\AbstractExtension not found error in production mode
body: <p>I have an app that runs fine in dev mode, but when I run it in production this pops up:</p>
  
  <pre><code>Fatal error: Class 'Twig\Extension\AbstractExtension' not found in C:\Users\wackm\PhpstormProjects\poem\vendor\symfony\symfony\src\Symfony\Bridge\Twig\Extension\LogoutUrlExtension.php on line 23
  </code></pre>
  
  <p>I'm guessing this relates to my custom twig extension:</p>
  
  <pre><code>&lt;?php
  // src/AppBundle/Twig/VersionExtension.php
  namespace AppBundle\Twig;
  
  use AppBundle\Entity\Version;
  use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
  
  /**
   * Class VersionExtension - converts versions to readable HTML.
   * @package AppBundle\Twig
   */
  class VersionExtension extends \Twig_Extension
  {
      /**
       * Defines the function name for use in twig templates.
       * @return array
       */
      public function getFunctions()
      {
          return array(
              new \Twig_SimpleFunction('version', array($this, 'versionFunction')),
          );
      }
  
      /**
       * Actual function that converts a Version object into a HTML string.
       *
       * Indent indents the associated entities within each other, but NOT
       * the individual items, it does this by incrementing in 0.5 and truncating
       * $indent with intval()
       * @param array $hydrated_entity
       * @param string $title
       * @param indent
       * @return string
       */
      public function versionFunction($hydrated_entity, $title = null, $indent = 0)
      {
          $result_html = '';
          if (!empty($hydrated_entity) and $title != null) {
              $result_html .= '&lt;div style="text-indent:' . (intval($indent) * 20) . 'px"&gt;&lt;strong&gt;' . $title . '&lt;/strong&gt;&lt;/div&gt;';
          }
          foreach ($hydrated_entity as $key =&gt; $value) {
              // Ignore meta attributes.
              if (in_array($key, array("ID", "Updated At", "Created At"))) {
                  continue;
              }
  
              if (is_array($value)) {
                  $result_html .= $this-&gt;versionFunction($value, $key, ($indent + 0.5));
              } else {
                  $value = $this-&gt;tidyValue($value);
                  if ($this-&gt;startsWith($key, "added_")) {
                      $result_html .= '&lt;div class="bg-success" style="text-indent:' . (intval($indent) * 20) . 'px"&gt;' . explode("_", $key)[1] . ': ' . '&lt;p&gt;' . $value . '&lt;/p&gt;' . '&lt;/div&gt;';
                  } else if ($this-&gt;startsWith($key, "removed_")) {
                      $result_html .= '&lt;div class="bg-danger" style="text-indent:' . (intval($indent) * 20) . 'px"&gt;' . explode("_", $key)[1] . ': ' . '&lt;p&gt;' . $value . '&lt;/p&gt;' . '&lt;/div&gt;';
                  } else {
                      $result_html .= '&lt;div class="bg-info" style="text-indent:' . (intval($indent) * 20) . 'px"&gt;' . $key . ': ' . '&lt;p&gt;' . $value . '&lt;/p&gt;' . '&lt;/div&gt;';
                  }
              }
          }
          return $result_html;
      }
  
      /**
       * Tidies up value for display.
       * @param $value
       * @return string
       */
      private function tidyValue($value)
      {
          // Convert DateTime to String.
          if ($value instanceof \DateTime) {
              $value = $value-&gt;format('Y-m-d');
          } else if (is_bool($value)) {
              $value = ($value) ? 'true' : 'false';
          } else if (is_string($value)) {
              //Remove extra &lt;p&gt; tags if present.
              $value = preg_replace('!^&lt;p&gt;(.*?)&lt;/p&gt;$!i', '$1', $value);
          }
          return $value;
      }
  
      /**
       * Checks whether a string begins with a another string.
       * @param $haystack
       * @param $needle
       * @return bool
       */
      private function startsWith($haystack, $needle)
      {
          $length = strlen($needle);
          return (substr($haystack, 0, $length) === $needle);
      }
  }
  </code></pre>
  
  <p>Should the extension be extending something else other than <code>LogoutUrlExtension.php</code>? It seems like a weird file for it to be trying to extend. PHPStorm has warned me that <code>\Twig_Extension</code> has multiple definitions, so I'm thinking this is related. </p>
  
  <p>I'm using Twig 1.8.</p>
  
  <p>Can anyone offer any insight?</p>
  
  <p>Edit:</p>
  
  <p>Composer.json:</p>
  
  <pre><code>{
    "name": "symfony/framework-standard-edition",
    "license": "MIT",
    "type": "project",
    "description": "The \"Symfony Standard Edition\" distribution",
    "minimum-stability": "dev",
    "prefer-stable": true,
    "autoload": {
      "psr-4": {
        "": "src/"
      },
      "classmap": [
        "app/AppKernel.php",
        "app/AppCache.php"
      ]
    },
    "autoload-dev": {
      "psr-4": {
        "Tests\\": "tests/"
      }
    },
    "require": {
      "php": "7.0.0",
      "symfony/symfony": "3.2.*",
      "doctrine/orm": "^2.5",
      "doctrine/doctrine-bundle": "^1.6",
      "doctrine/doctrine-cache-bundle": "^1.2",
      "symfony/swiftmailer-bundle": "^2.3",
      "symfony/monolog-bundle": "^2.8",
      "symfony/polyfill-apcu": "^1.0",
      "sensio/distribution-bundle": "^5.0",
      "sensio/framework-extra-bundle": "^3.0.2",
      "incenteev/composer-parameter-handler": "^2.0",
      "doctrine/doctrine-fixtures-bundle": "2.3.0",
      "symfony/assetic-bundle": "v2.8.0",
      "twig/twig": "1.*",
      "components/jquery": "3.1.1",
      "friendsofsymfony/user-bundle": "~2.0.0-beta2",
      "fr3d/ldap-bundle": "3.0.*@dev",
      "doctrine/doctrine-migrations-bundle": "^1.0",
      "symfony/console": "^3.2",
      "phpoffice/phpexcel": "^1.8",
      "waldo/datatable-bundle": "^4.0"
    },
    "require-dev": {
      "sensio/generator-bundle": "^3.0",
      "symfony/phpunit-bridge": "^3.0",
      "liip/functional-test-bundle": "^1.6",
      "phpunit/phpunit": "5.7"
    },
    "scripts": {
      "symfony-scripts": [
        "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
      ],
      "post-install-cmd": [
        "@symfony-scripts"
      ],
      "post-update-cmd": [
        "@symfony-scripts"
      ]
    },
    "config": {
      "platform": {
        "php": "7.0.0"
      }
    },
    "extra": {
      "symfony-app-dir": "app",
      "symfony-bin-dir": "bin",
      "symfony-var-dir": "var",
      "symfony-web-dir": "web",
      "symfony-tests-dir": "tests",
      "symfony-assets-install": "relative",
      "incenteev-parameters": {
        "file": "app/config/parameters.yml"
      },
      "branch-alias": {
        "dev-master": "3.1-dev"
      }
    }
  }
  </code></pre>