[
  {
    "path": ".editorconfig",
    "content": "; This file is for unifying the coding style for different editors and IDEs.\n; More information at http://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nindent_size = 4\nindent_style = space\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Path-based git attributes\n# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html\n\n# Ignore all test and documentation with \"export-ignore\".\n/.gitattributes     export-ignore\n/.gitignore         export-ignore\n/.travis.yml        export-ignore\n/phpunit.xml.dist   export-ignore\n/.scrutinizer.yml   export-ignore\n/tests              export-ignore\n/.editorconfig      export-ignore\n"
  },
  {
    "path": ".gitignore",
    "content": "build\ncomposer.lock\ndocs\nvendor\n"
  },
  {
    "path": ".scrutinizer.yml",
    "content": "filter:\n    excluded_paths: [tests/*]\n\nchecks:\n    php:\n        remove_extra_empty_lines: true\n        remove_php_closing_tag: true\n        remove_trailing_whitespace: true\n        fix_use_statements:\n            remove_unused: true\n            preserve_multiple: false\n            preserve_blanklines: true\n            order_alphabetically: true\n        fix_php_opening_tag: true\n        fix_linefeed: true\n        fix_line_ending: true\n        fix_identation_4spaces: true\n        fix_doc_comments: true\n\n"
  },
  {
    "path": ".styleci.yml",
    "content": "preset: laravel\n\nlinting: true\n\ndisabled:\n  - single_class_element_per_statement\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: php\n\nphp:\n  - 7.0\n  - 7.1\n  - 7.2\n\nenv:\n  matrix:\n    - COMPOSER_FLAGS=\"--prefer-lowest\"\n    - COMPOSER_FLAGS=\"\"\n\nbefore_script:\n  - travis_retry composer self-update\n  - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source\n\nscript:\n  - composer dump-autoload -o\n  - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover\n\nafter_script:\n  - php vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to `laravel-tinker-tools` will be documented in this file\n\n## 1.0.1 - 2017-07-28\n\n- avoid aliasing interfaces\n\n## 1.0.0 - 2017-05-22\n\n- initial release\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Spatie bvba <info@spatie.be>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "**The functionality of this package is built into Laravel 5.5 and above, only install this in older Laravel versions**\n\n# Use short class names in an Artisan Tinker session\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-tinker-tools.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-tinker-tools)\n[![Build Status](https://img.shields.io/travis/spatie/laravel-tinker-tools/master.svg?style=flat-square)](https://travis-ci.org/spatie/laravel-tinker-tools)\n[![StyleCI](https://styleci.io/repos/91980495/shield?branch=master)](https://styleci.io/repos/91980495)\n[![Quality Score](https://img.shields.io/scrutinizer/g/spatie/laravel-tinker-tools.svg?style=flat-square)](https://scrutinizer-ci.com/g/spatie/laravel-tinker-tools)\n[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-tinker-tools.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-tinker-tools)\n\nWhen using Artisan's Tinker command it can be quite bothersome having to type the fully qualified classname to do something simple.\n\n```php\n\\App\\Models\\NewsItem::first();\n```\n\nThis package contains a class that, when fully installed lets you use the short class names:\n\n```php\nNewsItem::first();\n```\n\n## Support us\n\n[<img src=\"https://github-ads.s3.eu-central-1.amazonaws.com/laravel-tinker-tools.jpg?t=1\" width=\"419px\" />](https://spatie.be/github-ad-click/laravel-tinker-tools)\n\nWe invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).\n\nWe highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).\n\n## Installation\n\nFirst install the package via Composer:\n\n``` bash\ncomposer require spatie/laravel-tinker-tools\n```\n\nNext, create a file named `.psysh.php` in the root of your Laravel app with this content:\n\n```php\n<?php\n\n\\Spatie\\TinkerTools\\ShortClassNames::register();\n```\n\nFinally, dump the optimized version of the autoloader so `autoload_classmap.php` gets created:\n\n```bash\ncomposer dump-autoload -o\n```\n\n## Usage\n\nOpen up a Tinker session with:\n\n```bash\nphp artisan tinker\n```\n\nInside that Tinker session you can now use short class names:\n\n```php\nNewsItem::first();\n```\n\n## A peek behind the curtains\n\nWhen you use a class that hasn't been loaded in yet, PHP will call the registered autoloader functions. Such autoloader functions are responsible for loading up the requested class. In a typical project Composer will register an autoloader function that can `include` the file where the class is stored in.\n\nComposer has a few ways to locate the right files. In most cases it will convert the fully qualified class name to a path. For example, when using a class `App\\Models\\NewsItem` Composer will load the file in `app/Models/NewsItem.php`. It's a bit more complicated behind the scenes but that's the gist of it. To make the process of finding a class fast, Composer caches all the fully qualified classnames and their paths in the generated `autoload_classmap.php`, which can be found in `vendor/composer`. \n\nNow, to make this package work, `\\Spatie\\TinkerTools\\ShortClassNames` will read Composer's `autoload_classmap.php` and [convert the fully qualified class names to short class names](https://github.com/spatie/laravel-tinker-tools/blob/d3a3287/src/ShortClassNames.php#L23). The result is a collection that's being kept in [the `$classes` property](https://github.com/spatie/laravel-tinker-tools/blob/098e595/src/ShortClassNames.php#L8)\n\nOur class will also [register an autoloader](https://github.com/spatie/laravel-tinker-tools/blob/098e595/src/ShortClassNames.php#L33). When you use `NewsItem` in your code. PHP will first call Composer's autoloader. But of course that autoloader can't find the class. So the autoloader from this package comes next. Our autoloader will use the aforementioned `$classes` collection to find to fully qualified class name. It will then [use `class_alias`](https://github.com/spatie/laravel-tinker-tools/blob/098e595/src/ShortClassNames.php#L46) to alias `NewsItem` to `App\\Models\\NewsItem`.\n\n## What happens if there are multiple classes with same name?\n\nNow you might wonder what'll happen it there are more classes with the same name in different namespaces? E.g. `App\\Models\\NewsItem`, `Vendor\\PackageName\\NewsItem`. Well, `autoload_classmap.php` is sorted alphabetically on the fully qualified namespace. So `App\\Models\\NewsItem` will be used and not `Vendor\\PackageName\\NewsItem`.\n\nBecause `App` starts with an \"A\" there's a high chance that, in case of a collision, a class inside your application will get picked. Currently there are no ways to alter this. I'd accept PRs that make this behaviour customizable.\n\n## Need more Tinker magic?\n\nThere are a lot of other options that can be set in `tinker.config.php`. Learn all the options by reading [the official psysh configuration documentation](http://psysh.org/#configure).\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Testing\n\n``` bash\n$ composer test\n```\n\n## Contributing\n\nPlease see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.\n\n## Security\n\nIf you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.\n\n## Postcardware\n\nYou're free to use this package (it's [MIT-licensed](LICENSE.md)), but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.\n\nOur address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.\n\nWe publish all received postcards [on our company website](https://spatie.be/en/opensource/postcards).\n\n## Credits\n\n- [Freek Van der Herten](https://github.com/freekmurze)\n- [All Contributors](../../contributors)\n\nWe got the idea for `ShortClassnames` by reading the \"Tailoring Tinker with custom config\" section of [Caleb Porzio](https://twitter.com/calebporzio)'s excellent blogpost \"[Supercharge Your Laravel Tinker Workflow](https://blog.tighten.co/supercharge-your-laravel-tinker-workflow)\".\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information."
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"spatie/laravel-tinker-tools\",\n    \"description\": \"Use short class names in an Artisan tinker session\",\n    \"keywords\": [\n        \"spatie\",\n        \"laravel-tinker-tools\",\n        \"flysystem\",\n        \"dropbox\",\n        \"v2\",\n        \"api\"\n    ],\n    \"homepage\": \"https://github.com/spatie/laravel-tinker-tools\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Freek Van der Herten\",\n            \"email\": \"freek@spatie.be\",\n            \"homepage\": \"https://spatie.be\",\n            \"role\": \"Developer\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"^7.0\",\n        \"illuminate/support\": \"5.3.*|5.4.*\"\n    },\n    \"require-dev\": {\n        \"phpunit/phpunit\": \"^6.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"Spatie\\\\TinkerTools\\\\\": \"src\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Spatie\\\\TinkerTools\\\\Test\\\\\": \"tests\"\n        }\n    },\n    \"scripts\": {\n        \"test\": \"vendor/bin/phpunit\"\n    },\n    \"config\": {\n        \"sort-packages\": true\n    }\n}\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit bootstrap=\"vendor/autoload.php\"\n         backupGlobals=\"false\"\n         backupStaticAttributes=\"false\"\n         colors=\"true\"\n         verbose=\"true\"\n         convertErrorsToExceptions=\"true\"\n         convertNoticesToExceptions=\"true\"\n         convertWarningsToExceptions=\"true\"\n         processIsolation=\"false\"\n         stopOnFailure=\"false\">\n    <testsuites>\n        <testsuite name=\"Spatie Test Suite\">\n            <directory>tests</directory>\n        </testsuite>\n    </testsuites>\n    <filter>\n        <whitelist>\n            <directory suffix=\".php\">src/</directory>\n        </whitelist>\n    </filter>\n    <logging>\n        <log type=\"tap\" target=\"build/report.tap\"/>\n        <log type=\"junit\" target=\"build/report.junit.xml\"/>\n        <log type=\"coverage-html\" target=\"build/coverage\" charset=\"UTF-8\" yui=\"true\" highlight=\"true\"/>\n        <log type=\"coverage-text\" target=\"build/coverage.txt\"/>\n        <log type=\"coverage-clover\" target=\"build/logs/clover.xml\"/>\n    </logging>\n</phpunit>\n"
  },
  {
    "path": "src/ShortClassNames.php",
    "content": "<?php\n\nnamespace Spatie\\TinkerTools;\n\nuse ReflectionClass;\n\nclass ShortClassNames\n{\n    /** @var \\Illuminate\\Support\\Collection */\n    public $classes;\n\n    public static function register(string $classMapPath = null)\n    {\n        $classMapPath = $classMapPath ?? base_path('vendor/composer/autoload_classmap.php');\n\n        (new static($classMapPath))->registerAutoloader();\n    }\n\n    public function __construct(string $classMapPath)\n    {\n        $classFiles = include $classMapPath;\n\n        $this->classes = collect($classFiles)\n            ->map(function (string $path, string $fqcn) {\n                $name = last(explode('\\\\', $fqcn));\n\n                return compact('fqcn', 'name');\n            })\n            ->filter()\n            ->values();\n    }\n\n    public function registerAutoloader()\n    {\n        spl_autoload_register([$this, 'aliasClass']);\n    }\n\n    public function aliasClass($findClass)\n    {\n        $class = $this->classes->first(function ($class) use ($findClass) {\n            if ($class['name'] !== $findClass) {\n                return false;\n            }\n\n            return ! (new ReflectionClass($class['fqcn']))->isInterface();\n        });\n\n        if (! $class) {\n            return;\n        }\n\n        class_alias($class['fqcn'], $class['name']);\n    }\n}\n"
  },
  {
    "path": "tests/NamespacedClass.php",
    "content": "<?php\n\nnamespace Spatie\\TinkerTools\\Test;\n\nclass NamespacedClass\n{\n    public static function getGreeting(): string\n    {\n        return 'Oh, hi Mark';\n    }\n}\n"
  },
  {
    "path": "tests/ShortClassNamesTest.php",
    "content": "<?php\n\nnamespace Spatie\\TinkerTools\\Test;\n\nuse Error;\nuse PHPUnit\\Framework\\TestCase;\nuse Spatie\\TinkerTools\\ShortClassNames;\n\nclass ShortClassNamesTest extends TestCase\n{\n    /** @test */\n    public function it_can_register_short_name_classes()\n    {\n        $foundClass = false;\n\n        try {\n            \\NamespacedClass::getGreeting();\n\n            $foundClass = true;\n        } catch (Error $error) {\n        }\n\n        $this->assertFalse($foundClass);\n\n        ShortClassNames::register(__DIR__.'/../vendor/composer/autoload_classmap.php');\n\n        $this->assertEquals('Oh, hi Mark', \\NamespacedClass::getGreeting());\n    }\n}\n"
  }
]