Yes, use this code
$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('visibility', 4);
It will get you the visible products, since 4 means Catalog and search visibility.
You can combine that with this to add stock check
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($products);
Based on @Flyingmana's answer I did a little digging and come up with a solution. It seams to work for me.
First my solution, then some explanations.
I've created a file called test.php
in the root of my magento instance.
<?php
require __DIR__ . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('TestApp');
$bootstrap->run($app);
Then I created a file called TestApp.php
in the same place with this content.
<?php
class TestApp
extends \Magento\Framework\App\Http
implements \Magento\Framework\AppInterface {
public function launch()
{
//dirty code goes here.
//the example below just prints a class name
echo get_class($this->_objectManager->create('\Magento\Catalog\Model\Category'));
//the method must end with this line
return $this->_response;
}
public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
{
return false;
}
}
Now I can just call test.php
in the browser and everything that is placed in TestApp::launch() will be executed.
Now, why this works:
The method createApplication
from the bootstrap class is the most important part. It creates an instance of an application class. The method createApplication
expects an implementation of the \Magento\Framework\AppInterface
that contains 2 methods.
So I created my own class in TestApp
that implements that interface. I made the method catchException
return false
always because I don't want my app to handle exceptions. In case something is wrong, just print it on the screen.
Then I implemented the method launch
. this one is called by \Magento\Framework\App\Bootstrap::run
. This run
method does almost the same thing no matter what the application passed as a parameter is.
The only thing that depends on the application is this line:
$response = $application->launch();
This means that calling \Magento\Framework\App\Bootstrap::run
will init the Magento env (maybe do some other crazy stuff...I haven't checked everything yet) then calls the launch
method from the application.
That's why you need to put all your dirty code inside that method.
Then the \Magento\Framework\App\Bootstrap::run
calls $response->sendResponse();
where $response
is what the launch
method returns.
That's why return $this->_response;
is needed. It just returns an empty response.
I made my app class extend \Magento\Framework\App\Http
so I will already have request and response parameters (and others), but you can make your class extend nothing. Then you need to copy the constructor from the \Magento\Framework\App\Http
class. Maybe add more parameters in the constructor if you need it.
Best Answer
I've build 2 small scripts for myself a while back to do just that. The project is on Github.
It's only simple products but the rest of the data is random. Images are pulled from a random image API so please take in consideration the amount of bandwidth 50K * ... images will use up. Might be smart do add a small sleep function in there to not overtask the network.
You can use it and if you make any improvements please fork it!