Blade :: compileString() and embedded variables - laravel

I am able to parse HTMl that uses blade template variables through the following code:
$generated = Blade::compileString($string);
ob_start();
try
{
eval($generated);
}
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
$content = ob_get_clean();
return $content;
And it works fine as long as i don't use blade variables within. Which on being parsed give me undefined variable error. How can i make sure that blade variables are available in my custom parsing method?

This works for me with the latest version of Laravel 5.7. Notice how I include the __env var so that functions like #include, #foreach, etc can work.
public static function renderBlade($string, $data = null)
{
if (!$data) {
$data = [];
}
$data['__env'] = app(\Illuminate\View\Factory::class);
$php = Blade::compileString($string);
$obLevel = ob_get_level();
ob_start();
extract($data, EXTR_SKIP);
try {
eval('?' . '>' . $php);
} catch (Exception $e) {
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw $e;
} catch (Throwable $e) {
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw new FatalThrowableError($e);
}
return ob_get_clean();
}

Turns out I was not passing the arguments array to the method that parses the Blade structure. My assumption was that the Mail::send method takes care of making variables available which it takes in as a second parameter. I also had to extract($args, EXTR_SKIP).
$generated = Blade::compileString($string);
ob_start(); extract($args, EXTR_SKIP)
try
{
eval($generated);
}
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
$content = ob_get_clean();
return $content;

Related

Laravel Send Request to endpoint

These codes throw "Bad Request" error because of parameter. What is the problem of parameter syntax.
try{
$client = new Client();
$response = $client->post("url",
['s' => $s, 'p'=> $p]);
} catch (ClientException $e) {
echo $e->getMessage();
} catch (RequestException $e) {
echo $e->getMessage();
}
You can use Http::post();
use Illuminate\Support\Facades\Http;
$response = Http::post('http://example.com/users',['your data']);

File isn't deleted when code is in a specific order

I ran into the problem that when I try to delete a record from database using ->delete() and my code stopped after successfully deleted the record.
This code doesn't execute the Storage::delete($image)
public function productImageDelete(Request $request){
if($request->ajax()):
$image_id = Input::get('image-id');
$image = Input::get('image');
try {
$image = Image::findOrFail($image_id);
$image->delete();
Storage::delete($image); //This doesn't execute at all
return "success";
} catch ( \Illuminate\Database\QueryException $e) {
return $e;
}
endif;
}
However when I placed Storage::delete($image) before $image->delete(); the code works.
public function productImageDelete(Request $request){
if($request->ajax()):
$image_id = Input::get('image-id');
$image = Input::get('image');
try {
Storage::delete($image); //This executes first
$image = Image::findOrFail($image_id);
$image->delete();
return "success";
} catch ( \Illuminate\Database\QueryException $e) {
return $e;
}
endif;
}
You need to take a look at the details. You're creating two variables named $image and that's your issue.
On the first case, you're calling Storage::delete($image); where $image is an object and on the second case, you're calling the same method but in that case $image is a Input::get('image').
If you simply rename the variable of Input::get('image') to, say $imageParam = Input::get('image') and execute Storage::delete($imageParam);, it should work on both cases.
The bottomline is: never use the same variable name, as it will led to such unnecessary confusions.

Laravel 5 - Compile String and Interpolate Using Blade API on Server

Using the Blade service container I want to take a string with markers in it and compile it down so it can be added to the blade template, and further interpolated.
So I have an email string (abridge for brevity) on the server retrieved from the database of:
<p>Welcome {{ $first_name }},</p>
And I want it to interpolated to
<p>Welcome Joe,</p>
So I can send it to a Blade template as $content and have it render all the content and markup since Blade doesn't interpolate twice and right now our templates are client made and stored in the database.
Blade::compileString(value) produces <p>Welcome <?php echo e($first_name); ?>,</p>, but I can't figure out how to get $first_name to resolve to Joe in the string using the Blade API, and it doesn't do it within the Blade template later. It just displays it in the email as a string with PHP delimiters like:
<p>Welcome <?php echo e($first_name); ?>,</p>
Any suggestions?
This should do it:
// CustomBladeCompiler.php
use Symfony\Component\Debug\Exception\FatalThrowableError;
class CustomBladeCompiler
{
public static function render($string, $data)
{
$php = Blade::compileString($string);
$obLevel = ob_get_level();
ob_start();
extract($data, EXTR_SKIP);
try {
eval('?' . '>' . $php);
} catch (Exception $e) {
while (ob_get_level() > $obLevel) ob_end_clean();
throw $e;
} catch (Throwable $e) {
while (ob_get_level() > $obLevel) ob_end_clean();
throw new FatalThrowableError($e);
}
return ob_get_clean();
}
}
Usage:
$first_name = 'Joe';
$dbString = '<p>Welcome {{ $first_name }},</p>';
return CustomBladeCompiler::render($dbString, ['first_name' => $first_name]);
Thanks to #tobia on the Laracasts forums.

Magento. Saving data in custome table

I am trying insert data in my table but allways get this error
Fatal error: Call to undefined method UltimoValue_Warranty_Model_Mysql4_Warranty_Collection::setData() in
/var/www/magento.dev/app/code/community/UltimoValue/Warranty/controllers/IndexController.php
on line 17
here is the saving code in IndexController
public function saveAction()
{
$warrantiesCollection = Mage::getModel('warranty/warranty')->getCollection();
$post = $this->getRequest()->getPost();
if(isset($post['order_number']) && isset($post['save'])) {
try {
$warrantiesCollection->setData('id', null);
$warrantiesCollection->setData('first_name', $post['first_name']);
$warrantiesCollection->setData('last_name', $post['last_name']);
$warrantiesCollection->setData('order_number', $post['order_number']);
$warrantiesCollection->setData('tablet_serial_number', $post['tablet_serial_number']);
$warrantiesCollection->setData('date_purchased', $post['date_purchased']);
$warrantiesCollection->save();
} catch(Exception $e) {
echo $e->getMessage(), "\n";
}
header("Location: " . $_SERVER['HTTP_ORIGIN'] . "/index.php/warranty/index/thankyou/");
exit();
}
}
when i am using getData - all fine...
What i am doing wrong ?
instead
$warrantiesCollection = Mage::getModel('warranty/warranty')->getCollection();
i have to write
$warrantiesCollection = Mage::getModel('warranty/warranty');
thanks to all

"File was not uploaded" magento error even file is uploaded to particular folder

I am making an application in which i am uploading file from my custom tab as follows
i created a observer for event called catalog_product_save_after. In the particular function, i am uploading those files to catalog/product folder and its get uploaded to those folder without any error.
But when i am trying to assign those images to that particular product, i got the following error.
File was not uploaded at file E:\xampp\htdocs\magento\lib\Varien\File\Uploader.php on line 152
If i check system.log then i see the 2012-08-24T11:33:15+00:00 ERR (3): User Error: Some transactions have not been committed or rolled back in E:\xampp\htdocs\magento\lib\Varien\Db\Adapter\Pdo\Mysql.php on line 3645 this error.
My observer function is as follows
public function Savedata($observer)
{
$params = Mage::app()->getRequest()->getParams();
$product = $observer->getEvent()->getProduct();
$product_id = $product->getId();
$filesData = array();
$keysData = array_keys($_FILES);
foreach($keysData as $keys)
{
$uploader = new Varien_File_Uploader("$keys");
$uploader->setAllowedExtensions(array('jpeg', 'jpg', 'png', 'tiff'));
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . "catalog" . DS . "product";
if(!is_dir($path))
{
mkdir($path);
}
$extension = pathinfo($_FILES["$keys"]['name'], PATHINFO_EXTENSION);
$date = new DateTime();
$file_name = $keys . "_" . $product_id . "." . $extension;
$_FILES["$keys"]['name'] = $file_name;
$uploader->save($path, $_FILES["$keys"]['name']);
$filesData[] = $path .DS. $_FILES["$keys"]['name'];
}
print_r($filesData);
///till this works file.. when i add following code, program dies.
try
{
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
foreach($filesData as $file)
{
$productData->addImageToMediaGallery($file, "image" ,false, false);
}
$productData->save();
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
}
catch (Exception $e)
{
echo $e->getMessage() . "||" . $e->getCode() . "||" . $e->getFile() . "||" . $e->getLine();
}
exit();
}
any suggestion where i am going wrong? why this error occur?
i am using magento 1.7
I see that you're going to update your catalog/product object when you're saving it.
You are using event catalog_product_save_after.
Inside the observer, you call:
$productData = Mage::getModel('catalog/product')->load($product_id);
...
$productData->save();
$productData is catalog/product object -> you saved it.
You can guess what will happen, it will trigger event catalog_product_save_after and so on, looping forever.
I see that you call $productData->save(); because in this event, the value has been saved and can not be changed.
So instead of using catalog_product_save_after, you can use catalog_product_save_before.
The same like your code, but remove $productData->save(); because it will automatically call save.
Mage_Core_Model_Abstract
public function save()
{
/**
* Direct deleted items to delete method
*/
if ($this->isDeleted()) {
return $this->delete();
}
if (!$this->_hasModelChanged()) {
return $this;
}
$this->_getResource()->beginTransaction();
$dataCommited = false;
try {
$this->_beforeSave();
if ($this->_dataSaveAllowed) {
//see this line below, it will call save, so you don't need to call save in your `catalog_product_save_before` (no looping forever)
$this->_getResource()->save($this);
$this->_afterSave();
}
$this->_getResource()->addCommitCallback(array($this, 'afterCommitCallback'))
->commit();
$this->_hasDataChanges = false;
$dataCommited = true;
} catch (Exception $e) {
$this->_getResource()->rollBack();
$this->_hasDataChanges = true;
throw $e;
}
if ($dataCommited) {
$this->_afterSaveCommit();
}
return $this;
}

Resources