Skip to content

Instantly share code, notes, and snippets.

@colinmollenhour
Last active March 19, 2019 17:36
Show Gist options
  • Save colinmollenhour/75f65a63e5f66adc8639aa8b9b1eef5f to your computer and use it in GitHub Desktop.
Save colinmollenhour/75f65a63e5f66adc8639aa8b9b1eef5f to your computer and use it in GitHub Desktop.
Vardoc generator for Magento collection classes
<?php
/* This script generates @method annotations for magento collection classes.
* Example:
* cd [magento root]
* php shell/collections.php
*
*/
// Init framework
require __DIR__.'/../app/Mage.php';
Mage::app();
// Factory methods to search for
$methods = array(
'Mage::getModel',
);
// Path to search for source files
$projectPath = 'app';
$sourceRegex = '/^.+\.(?:php|phtml)$/';
// Collect class names
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($projectPath, FilesystemIterator::FOLLOW_SYMLINKS));
$files = new RegexIterator($iterator, $sourceRegex, RecursiveRegexIterator::GET_MATCH);
$classes = $collections = [];
foreach($files as $file) {
$code = file_get_contents($file[0]);
if ($code === FALSE) die("Could not get contents of {$file[0]}\n");
foreach($methods as $method) {
if(preg_match_all('#'.preg_quote($method).'\s*\(\s*[\'"]([a-zA-Z0-9/_]+)[\'"]#', $code, $matches)) {
if(empty($classes[$method])) $classes[$method] = array();
foreach($matches[1] as $token) {
if(isset($classes[$method][$token])) continue;
$className = Mage::getConfig()->getModelClassName($token);
if ($className && preg_match('/^Mage_/', $className) && ! preg_match('/_(Paypal|Api|Api2|Service|Config|Calculator|Exception|Import|Export|Uploader|Install|XmlConnect|Acl)/', $className)) {
$object = Mage::getModel($token);
if ($object && $object instanceof Mage_Core_Model_Abstract && method_exists($object, 'getCollection')) {
try {
$collection = $object->getCollection();
if ($collection) {
$collectionClass = get_class($collection);
$collections[$collectionClass] = $className;
} else {
$collections[$collectionClass] = 'FAILED (getCollection)';
}
} catch (Exception $e) {
$collections[$collectionClass] = 'FAILED (exception)';
}
} else {
$collections[$collectionClass] = 'SKIPPED (instanceof)';
}
$classes[$method][$token] = $className;
} else {
$collections[$collectionClass] = 'SKIPPED (pattern)';
}
}
}
}
}
foreach ($collections as $collectionClass => $className) {
if (preg_match('/^(SKIPPED|FAILED)/', $className)) {
echo "$className $collectionClass\n";
}
$classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $collectionClass))).'.php';
$classFilePath = stream_resolve_include_path($classFile);
if ($classFilePath) {
$contents = file("$classFilePath");
foreach ($contents as $index => $line) {
if ($line == " * @category Mage\n") {
$insertAfter = $index - 1;
}
}
if ($insertAfter) {
$newLines = [
" *\n",
" * @method {$className}[] getIterator()\n",
" * @method {$className} getFirstItem()\n",
" * @method {$className}[] getItems()\n",
" * @method {$className} getItemById(\$value)\n",
" * @method {$className}[] getItemsByColumnValue(\$column, \$value)\n",
" * @method {$className} getItemByColumnValue(\$column, \$value)\n",
];
array_splice($contents, $insertAfter, 0, $newLines);
file_put_contents("$classFilePath", implode("", $contents));
echo "$className::$classFilePath\n";
} else {
echo "No insertion point found for $className::$classFilePath";
}
#exit; // Testing
} else {
echo "Could not resolve file for $className::$collectionClass\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment