diff --git a/README.md b/README.md
index 2e70032b..1065bda0 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,7 @@ is not needed to install packages with these frameworks:
| Sylius | `sylius-theme`
| symfony1 | **`symfony1-plugin`**
| TAO | `tao-extension`
+| TastyIgniter | **`tastyigniter-extension`
`tastyigniter-theme`**
| Tusk | `tusk-task`
`tusk-command`
`tusk-asset`
| TYPO3 Flow | `typo3-flow-package`
`typo3-flow-framework`
`typo3-flow-plugin`
`typo3-flow-site`
`typo3-flow-boilerplate`
`typo3-flow-build`
| TYPO3 CMS | `typo3-cms-extension` (Deprecated in this package, use the [TYPO3 CMS Installers](https://packagist.org/packages/typo3/cms-composer-installers) instead)
diff --git a/composer.json b/composer.json
index 61c0b7f4..48e71553 100644
--- a/composer.json
+++ b/composer.json
@@ -68,6 +68,7 @@
"SyDES",
"Sylius",
"symfony",
+ "TastyIgniter",
"Thelia",
"TYPO3",
"WHMCS",
diff --git a/src/Composer/Installers/Installer.php b/src/Composer/Installers/Installer.php
index 5869c177..cf3a09ac 100644
--- a/src/Composer/Installers/Installer.php
+++ b/src/Composer/Installers/Installer.php
@@ -50,6 +50,7 @@ class Installer extends LibraryInstaller
'fuelphp' => 'FuelphpInstaller',
'grav' => 'GravInstaller',
'hurad' => 'HuradInstaller',
+ 'tastyigniter' => 'TastyIgniterInstaller',
'imagecms' => 'ImageCMSInstaller',
'itop' => 'ItopInstaller',
'joomla' => 'JoomlaInstaller',
diff --git a/src/Composer/Installers/TastyIgniterInstaller.php b/src/Composer/Installers/TastyIgniterInstaller.php
new file mode 100644
index 00000000..e20e65b8
--- /dev/null
+++ b/src/Composer/Installers/TastyIgniterInstaller.php
@@ -0,0 +1,32 @@
+ 'extensions/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * Cut off leading 'ti-ext-' or 'ti-theme-' if present.
+ * Strip vendor name of characters that is not alphanumeric or an underscore
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'tastyigniter-extension') {
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+ $vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']);
+ }
+
+ if ($vars['type'] === 'tastyigniter-theme') {
+ $vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']);
+ }
+
+ return $vars;
+ }
+}
\ No newline at end of file
diff --git a/tests/Composer/Installers/Test/InstallerTest.php b/tests/Composer/Installers/Test/InstallerTest.php
index 59ae5320..b5f82276 100644
--- a/tests/Composer/Installers/Test/InstallerTest.php
+++ b/tests/Composer/Installers/Test/InstallerTest.php
@@ -223,6 +223,8 @@ public function dataForTestSupport()
array('sydes-theme', true),
array('sylius-theme', true),
array('symfony1-plugin', true),
+ array('tastyigniter-extension', true),
+ array('tastyigniter-theme', true),
array('thelia-module', true),
array('thelia-frontoffice-template', true),
array('thelia-backoffice-template', true),
@@ -435,6 +437,8 @@ public function dataForTestInstallPath()
array('sylius-theme', 'themes/my_theme/', 'shama/my_theme'),
array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'),
array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'),
+ array('tastyigniter-extension', 'extensions/shama/my_extension/', 'shama/my_extension'),
+ array('tastyigniter-theme', 'themes/my_theme/', 'shama/my_theme'),
array('thelia-module', 'local/modules/my_module/', 'shama/my_module'),
array('thelia-frontoffice-template', 'templates/frontOffice/my_template_fo/', 'shama/my_template_fo'),
array('thelia-backoffice-template', 'templates/backOffice/my_template_bo/', 'shama/my_template_bo'),
diff --git a/tests/Composer/Installers/Test/TastyIgniterInstallerTest.php b/tests/Composer/Installers/Test/TastyIgniterInstallerTest.php
new file mode 100644
index 00000000..f79070b4
--- /dev/null
+++ b/tests/Composer/Installers/Test/TastyIgniterInstallerTest.php
@@ -0,0 +1,94 @@
+installer = new TastyIgniterInstaller(
+ new Package('NyanCat', '4.2', '4.2'),
+ new Composer()
+ );
+ }
+
+ /**
+ * @dataProvider packageNameInflectionProvider
+ *
+ * @return void
+ */
+ public function testInflectPackageVars($type, $vendor, $name, $expectedVendor, $expectedName)
+ {
+ $this->assertEquals(
+ $this->installer->inflectPackageVars(array(
+ 'vendor' => $vendor,
+ 'name' => $name,
+ 'type' => $type,
+ )),
+ array(
+ 'vendor' => $expectedVendor,
+ 'name' => $expectedName,
+ 'type' => $type
+ )
+ );
+ }
+
+ public function packageNameInflectionProvider()
+ {
+ return array(
+ array(
+ 'tastyigniter-extension',
+ 'acme',
+ 'pages',
+ 'acme',
+ 'pages',
+ ),
+ array(
+ 'tastyigniter-extension',
+ 'acme',
+ 'ti-ext-pages',
+ 'acme',
+ 'pages',
+ ),
+ // tests vendor name containing a hyphen
+ array(
+ 'tastyigniter-extension',
+ 'foo-bar-co',
+ 'blog',
+ 'foobarco',
+ 'blog',
+ ),
+ // tests that exactly one '-theme' is cut off
+ array(
+ 'tastyigniter-theme',
+ 'acme',
+ 'ti-theme-theme',
+ 'acme',
+ 'theme',
+ ),
+ // tests that names without '-theme' suffix stay valid
+ array(
+ 'tastyigniter-theme',
+ 'acme',
+ 'someothertheme',
+ 'acme',
+ 'someothertheme',
+ ),
+ );
+ }
+}