Discount amount reflect properly into Order review page but added discount not taken over to Final order placed - magento-1.7

I am trying to apply custom discount for an order through my custom extension. I am showing custom textbox for adding coupon code and after that I fetch discount amount for that code from API and trying to apply for respective order.
Error : Using below code my discount show on order review page but it not taken over to Final order placed.Final order shows no discount.
I put below function in my controller .
require_once 'Mage/Checkout/controllers/CartController.php';
class Company_ModuleName_IndexController extends Mage_Checkout_CartController {
public function customcouponPostAction() {
$quote = $this->_getQuote();
$quoteid = $quote->getId();
$discountAmount = 20;
if ($quoteid) {
if ($discountAmount > 0) {
$total = $quote->getBaseSubtotal();
$quote->setSubtotal(0);
$quote->setBaseSubtotal(0);
$quote->setSubtotalWithDiscount(0);
$quote->setBaseSubtotalWithDiscount(0);
$quote->setGrandTotal(0);
$quote->setBaseGrandTotal(0);
$canAddItems = $quote->isVirtual() ? ('billing') : ('shipping');
foreach ($quote->getAllAddresses() as $address) {
$address->setSubtotal(0);
$address->setBaseSubtotal(0);
$address->setGrandTotal(0);
$address->setBaseGrandTotal(0);
$address->collectTotals();
$quote->setSubtotal((float) $quote->getSubtotal() + $address->getSubtotal());
$quote->setBaseSubtotal((float) $quote->getBaseSubtotal() + $address->getBaseSubtotal());
$quote->setSubtotalWithDiscount(
(float) $quote->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount()
);
$quote->setBaseSubtotalWithDiscount(
(float) $quote->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount()
);
$quote->setGrandTotal((float) $quote->getGrandTotal() + $address->getGrandTotal());
$quote->setBaseGrandTotal((float) $quote->getBaseGrandTotal() + $address->getBaseGrandTotal());
$quote->save();
$quote->setGrandTotal($quote->getBaseSubtotal() - $discountAmount)
->setBaseGrandTotal($quote->getBaseSubtotal() - $discountAmount)
->setSubtotalWithDiscount($quote->getBaseSubtotal() - $discountAmount)
->setBaseSubtotalWithDiscount($quote->getBaseSubtotal() - $discountAmount)
->save();
if ($address->getAddressType() == $canAddItems) {
//echo $address->setDiscountAmount; exit;
$address->setSubtotalWithDiscount((float) $address->getSubtotalWithDiscount() - $discountAmount);
$address->setGrandTotal((float) $address->getGrandTotal() - $discountAmount);
$address->setBaseSubtotalWithDiscount((float) $address->getBaseSubtotalWithDiscount() - $discountAmount);
$address->setBaseGrandTotal((float) $address->getBaseGrandTotal() - $discountAmount);
if ($address->getDiscountDescription()) {
$address->setDiscountAmount(-($address->getDiscountAmount() - $discountAmount));
$address->setDiscountDescription($address->getDiscountDescription() . ', Custom Discount');
$address->setBaseDiscountAmount(-($address->getBaseDiscountAmount() - $discountAmount));
} else {
$address->setDiscountAmount(-($discountAmount));
$address->setDiscountDescription('Custom Discount');
$address->setBaseDiscountAmount(-($discountAmount));
}
$address->save();
}//end: if
} //end: foreach
//echo $quote->getGrandTotal();
foreach ($quote->getAllItems() as $item) {
//We apply discount amount based on the ratio between the GrandTotal and the RowTotal
$rat = $item->getPriceInclTax() / $total;
$ratdisc = $discountAmount * $rat;
$item->setDiscountAmount(($item->getDiscountAmount() + $ratdisc) * $item->getQty());
$item->setBaseDiscountAmount(($item->getBaseDiscountAmount() + $ratdisc) * $item->getQty())->save();
}
}
}
$this->loadLayout(false);
$review = $this->getLayout()->getBlock('roots')->toHtml();
$response['review'] = $review;
//$this->_goBack();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
}
}
Thanks,

Try adding a $quote->save(); just after the foreach ($quote->getAllItems() as $item) { loop.

Related

TYPO3 Extbase - Paginate through a large table (100000 records)

I have a fairly large table with about 100000 records. If I don't set the limit in the repository
Repository:
public function paginateRequest() {
$query = $this->createQuery();
$result = $query->setLimit(1000)->execute();
//$result = $query->execute();
return $result;
}
/**
* action list
*
* #return void
*/
public function listAction() {
$this->view->assign('records', $this->leiRepository->paginateRequest());
//$this->view->assign('records', $this->leiRepository->findAll());
}
... the query and the page breaks although I'm using f:widget.paginate . As per the docs https://fluidtypo3.org/viewhelpers/fluid/master/Widget/PaginateViewHelper.html I was hoping that I can render only the itemsPerPage and 'parginate' through the records ...
List.hmtl
<f:if condition="{records}">
<f:widget.paginate objects="{records}" as="paginatedRecords" configuration="{itemsPerPage: 100, insertAbove: 0, insertBelow: 1, maximumNumberOfLinks: 10}">
<f:for each="{paginatedRecords}" as="record">
<tr>
<td><f:link.action action="show" pageUid="43" arguments="{record:record}"> {record.name}</f:link.action></td>
<td><f:link.action action="show" pageUid="43" arguments="{record:record}"> {record.lei}</f:link.action></td>
</tr>
</f:for>
</f:widget.paginate>
Model:
class Lei extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
...
/**
* abc
*
* #lazy
* #var string
*/
protected $abc = '';
...
I use in TYPO3 9.5. The next function in repository:
public function paginated($page = 1, $size = 9){
$query = $this->createQuery();
$begin = ($page-1) * $size;
$query->setOffset($begin);
$query->setLimit($size);
return $query->execute();
}
And in the controller I am using arguments as parameter to send the page to load in a Rest action.
public function listRestAction()
{
$arguments = $this->request->getArguments();
$totalElements = $this->repository->total();
$pages = ceil($totalElements/9);
$next_page = '';
$prev_page = '';
#GET Page to load
if($arguments['page'] AND $arguments['page'] != ''){
$page_to_load = $arguments['page'];
} else {
$page_to_load = 1;
}
#Configuration of pagination
if($page_to_load == $pages){
$prev = $page_to_load - 1;
$prev_page = "http://example.com/rest/news/page/$prev";
} elseif($page_to_load == 1){
$next = $page_to_load + 1;
$next_page = "http://example.com/rest/news/page/$next";
} else {
$prev = $page_to_load - 1;
$prev_page = "http://example.com/rest/news/page/$prev";
$next = $page_to_load + 1;
$next_page = "http://example.com/rest/news/page/$next";
}
$jsonPreparedElements = array();
$jsonPreparedElements['info']['count'] = $totalElements;
$jsonPreparedElements['info']['pages'] = $pages;
$jsonPreparedElements['info']['next'] = $next_page;
$jsonPreparedElements['info']['prev'] = $prev_page;
$result = $this->repository->paginated($page_to_load);
$collection_parsed_results = array();
foreach ($result as $news) {
array_push($collection_parsed_results, $news->parsedArray());
}
$jsonPreparedElements['results'] = $collection_parsed_results;
$this->view->assign('value', $jsonPreparedElements);
}
The result of this, is a JSON like this:
{
"info": {
"count": 25,
"pages": 3,
"next": "",
"prev": "http://example.com/rest/news/page/2"
},
"results": [
{ ....}
] }
How large / complex are the objects you want to paginate through? If they have subobjects that you dont need in the list view, add #lazy annotation to those relations inside the model.
Due to this large amount of records, you should keep them as simple as possible in the list view. You can try to only give the result as array to the list view using $this->leiRepository->findAll()->toArray() or return only the raw result from your repository by adding true to execute(true).
You can also create an array of list items yourself in a foreach in the controller and only add the properties you really need inside the list.
If your problem is the performance, just use the default findAll()-Method.
The built-in defaultQuerySettings in \TYPO3\CMS\Extbase\Persistence\Repository set their offset and limit based on the Pagination widget, if not set otherwise.
If the performance issue persists, you may have to consider writing a custom query for your database request, that only requests the data your view actually displays. The process is described in the documentation: https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/3-implement-individual-database-queries.html

Filter information and custom repository with Symfony2?

From GET parameters, I want to get information from my entities.
In my view I created a form with 3 selects (not multiple ones), like this:
http://pix.toile-libre.org/upload/original/1393414663.png
If I filter only by user I got this in the url: ?category=0&user=6&status=0
I'll have to handle the 0 values...
This form used to filter my tasks.
This is a part of my action in my controller:
if($request->query->has('user')) {
$category_id = $request->query->get('category');
$user_id = $request->query->get('user');
$status_id = $request->query->get('status');
// A little test to see if it works.
echo $category_id . '<br>' . $user_id . '<br>' . $status_id;
// I will pass these variables to a repository
$tasks = $em->getRepository('LanCrmBundle:Task')->findFiltered($category_id, $user_id, $status_id);
} else {
$tasks = $em->getRepository('LanCrmBundle:Task')->findAll();
}
I create a repository with this method:
public function findFiltered($category_id, $user_id, $status_id)
{
/**
* Get filtered tasks.
*
* Get only title, priority, created_at, category_id, user_id and status_id fields (optimization)
*
* Where field category_id = $category_id unless $category_id is smaller than 1 (not secure enough)
* Where field user_id = $user_id unless $user_id is smaller than 1 (not secure enough)
* Where field status_id = $status_id unless $status_id is smaller than 1 (not secure enough)
* Should I do these tests here or in the controller?
*/
}
How to do this query ? Do you have any other elegant suggestions to solve this problem?
You can try:
public function findFiltered($category_id, $user_id, $status_id)
{
$queryBuilder = $this->createQueryBuilder('t');
if(!empty($category_id) && is_numeric($category_id)) {
$queryBuilder->andWhere('t.category = :category')->setParameter('category', $category_id);
}
if(!empty($user_id) && is_numeric($user_id)) {
$queryBuilder->andWhere('t.user = :user')->setParameter('user', $user_id);
}
if(!empty($status_id) && is_numeric($status_id)) {
$queryBuilder->andWhere('t.status = :status')->setParameter('status', $status_id);
}
return $queryBuilder->getQuery()->getResult();
}

Jomsocial Extra Field

I am trying to create extra fields on the Jomsocial Groups Create New Group page, its suggested on the Jomsocial docs that the best way is to creat a plugin to do this.
As I have never created such a complex plugin do anyone have a working example to start with?
Here is the code that I have tried with
<?php
defined('_JEXEC') or die('Restricted access');
if (! class_exists ( 'plgSpbgrouppostcode' )) {
class plgSpbgrouppostcode extends JPlugin {
/**
* Method construct
*/
function plgSystemExample($subject, $config) {
parent::__construct($subject, $config);
// JPlugin::loadLanguage ( 'plg_system_example', JPATH_ADMINISTRATOR ); // only use if theres any language file
include_once( JPATH_ROOT .'/components/com_community/libraries/core.php' ); // loading the core library now
}
function onFormDisplay( $form_name )
{
/*
Add additional form elements at the bottom privacy page
*/
$elements = array();
if( $form_name == 'jsform-groups-forms' )
{
$obj = new CFormElement();
$obj->label = 'Labe1 1';
$obj->position = 'after';
$obj->html = '<input name="custom1" type="text">';
$elements[] = $obj;
$obj = new CFormElement();
$obj->label = 'Labe1 2';
$obj->position = 'after';
$obj->html = '<input name="custom2" type="text">';
$elements[] = $obj;
}
return $elements;

How to split Magento order for downloadable and physical product

How i can split an order into two different part (one for downloadable and second for physical) and authorize the total amount at once and capture the downloadable product amount at the time of order and for physical capture it manually from admin panel while product is ready for shipment.
Can anybody help me.............
Thanks in Advance :D
You need to create a custom event in OnePageController (if you are using Onepage checkout) under saveOrderAction() method.
and use the below code to remove the item from current cart and create a new order for physical product.
class CompanyName_ModuleName_Model_Order extends Mage_Core_Model_Abstract {
public function createOrder() {
$quoteID = Mage::getSingleton("checkout/session")->getQuote()->getId();
$quote = Mage::getModel("sales/quote")->load($quoteID);
foreach($quote->getAllItems() as $item){
$itemId = $item->getId();
$productId = $item->getProductId();
if(put your condition here){
/* remove the item fro which need to split the order */
$quote->removeItem($itemId)->save();
}
}
$id = Mage::getSingleton('customer/session')->getCustomer()->getId();
$customer = Mage::getModel('customer/customer')->load($id);
$transaction = Mage::getModel('core/resource_transaction');
$storeId = $customer->getStoreId();
$reservedOrderId = Mage::getSingleton('eav/config')->getEntityType('order')->fetchNewIncrementId($storeId);
$order = Mage::getModel('sales/order')
->setIncrementId($reservedOrderId)
->setStoreId($storeId)
->setQuoteId(0)
->setGlobal_currency_code('USD')
->setBase_currency_code('USD')
->setStore_currency_code('USD')
->setOrder_currency_code('USD');
/* set Customer data */
$order->setCustomer_email($customer->getEmail())
->setCustomerFirstname($customer->getFirstname())
->setCustomerLastname($customer->getLastname())
->setCustomerGroupId($customer->getGroupId())
->setCustomer_is_guest(0)
->setCustomer($customer);
/* set Billing Address */
$billing = $customer->getDefaultBillingAddress();
$billingAddress = Mage::getModel('sales/order_address')
->setStoreId($storeId)
->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING)
->setCustomerId($customer->getId())
->setCustomerAddressId($customer->getDefaultBilling())
->setCustomer_address_id($billing->getEntityId())
->setPrefix($billing->getPrefix())
->setFirstname($billing->getFirstname())
->setMiddlename($billing->getMiddlename())
->setLastname($billing->getLastname())
->setSuffix($billing->getSuffix())
->setCompany($billing->getCompany())
->setStreet($billing->getStreet())
->setCity($billing->getCity())
->setCountry_id($billing->getCountryId())
->setRegion($billing->getRegion())
->setRegion_id($billing->getRegionId())
->setPostcode($billing->getPostcode())
->setTelephone($billing->getTelephone())
->setFax($billing->getFax());
$order->setBillingAddress($billingAddress);
$shipping = $customer->getDefaultShippingAddress();
$shippingAddress = Mage::getModel('sales/order_address')
->setStoreId($storeId)
->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
->setCustomerId($customer->getId())
->setCustomerAddressId($customer->getDefaultShipping())
->setCustomer_address_id($shipping->getEntityId())
->setPrefix($shipping->getPrefix())
->setFirstname($shipping->getFirstname())
->setMiddlename($shipping->getMiddlename())
->setLastname($shipping->getLastname())
->setSuffix($shipping->getSuffix())
->setCompany($shipping->getCompany())
->setStreet($shipping->getStreet())
->setCity($shipping->getCity())
->setCountry_id($shipping->getCountryId())
->setRegion($shipping->getRegion())
->setRegion_id($shipping->getRegionId())
->setPostcode($shipping->getPostcode())
->setTelephone($shipping->getTelephone())
->setFax($shipping->getFax());
$order->setShippingAddress($shippingAddress)
->setShipping_method('freeshipping')
->setShippingDescription('Free Shipping - Free');
/*set payment details here for example */
$orderPayment = Mage::getModel('sales/order_payment')
->setStoreId($storeId)
->setCustomerPaymentId(0)
->setMethod('cybersource_soap')
->setCcType('VI')
->setCcNumber('4111111111111111')
->setCcLast4('1111')
->setCcExpMonth('2')
->setCcExpYear('2013')
->setCcCid('123');
$order->setPayment($orderPayment);
/* let say, we have 2 products */
$subTotal = 0;
/* pass the product id and quantity here e.g. */
$products = array(
'2' => array(
'qty' => 1
)
);
foreach ($products as $productId => $product) {
$_product = Mage::getModel('catalog/product')->load($productId);
$rowTotal = $_product->getPrice() * $product['qty'];
$orderItem = Mage::getModel('sales/order_item')
->setStoreId($storeId)
->setQuoteItemId(0)
->setQuoteParentItemId(NULL)
->setProductId($productId)
->setProductType($_product->getTypeId())
->setQtyBackordered(NULL)
->setTotalQtyOrdered($product['qty'])
->setQtyOrdered($product['qty'])
->setName($_product->getName())
->setSku($_product->getSku())
->setPrice($_product->getPrice())
->setBasePrice($_product->getPrice())
->setOriginalPrice($_product->getPrice())
->setRowTotal($rowTotal)
->setBaseRowTotal($rowTotal);
$subTotal += $rowTotal;
$order->addItem($orderItem);
}
$order->setSubtotal($subTotal)
->setBaseSubtotal($subTotal)
->setGrandTotal($subTotal)
->setBaseGrandTotal($subTotal);
$transaction->addObject($order);
$transaction->addCommitCallback(array($order, 'place'));
$transaction->addCommitCallback(array($order, 'save'));
$transaction->save();
}
}
and don't forget to modify this code according your configuration etc.

tt_news: Modify image src

In order to be able to use lazy loading, I need to modify the src attribute of tt_news' image output like so:
<img src="/foo/bar/baz.png" … /> // <-- before
<img data-original="/foo/bar/baz.png" … /> // <-- after, no src!
I have tried:
plugin.tt_news.displayList.content_stdWrap {
parseFunc < lib.parseFunc_RTE
HTMLparser = 1
HTMLparser.keepNonMatchedTags = 1
HTMLparser.tags.img.fixAttrib.src.unset = 1
}
but to no avail, since
The image in question is not being inserted via RTE, but the "normal" media integration.
That wouldn't copy the src attribute over to data-original before unsetting.
So, what should I do aside from pulling my hair out?
This cannot be solved via typoscript, because the src attribute is hard coded in the cImage function:
$theValue = '<img src="' . htmlspecialchars($GLOBALS['TSFE']->absRefPrefix .
t3lib_div::rawUrlEncodeFP($info[3])) . '" width="' . $info[0] . '" height="' . $info[1] . '"' .
$this->getBorderAttr(' border="' . intval($conf['border']) . '"') .
$params .
($altParam) . ' />';
The only way I see to modify the src attribute is through a user function. tt_news provides a hook for a user function that allows the custom processing of images (see line 2150 of class.tx_ttnews.php).
Example:
Insert the following typoscript:
includeLibs.user_ttnewsImageMarkerFunc = fileadmin/templates/php/user_ttnewsImageMarkerFunc.php
plugin.tt_news.imageMarkerFunc = user_ttnewsImageMarkerFunc->ttnewsImageMarkerFunc
Whereas the file user_ttnewsImageMarkerFunc.php contains:
<?php
class user_ttnewsImageMarkerFunc {
/**
* Fills the image markers with data.
*
* #param array $paramArray: $markerArray and $config of the current news item in an array
* #param [type] $conf: ...
* #return array the processed markerArray
*/
function ttnewsImageMarkerFunc($paramArray, $conf) {
$markerArray = $paramArray[0];
$lConf = $paramArray[1];
$pObj = &$conf['parentObj'];
$row = $pObj->local_cObj->data;
$imageNum = isset($lConf['imageCount']) ? $lConf['imageCount'] : 1;
$imageNum = t3lib_div::intInRange($imageNum, 0, 100);
$theImgCode = '';
$imgs = t3lib_div::trimExplode(',', $row['image'], 1);
$imgsCaptions = explode(chr(10), $row['imagecaption']);
$imgsAltTexts = explode(chr(10), $row['imagealttext']);
$imgsTitleTexts = explode(chr(10), $row['imagetitletext']);
reset($imgs);
if ($pObj->config['code'] == 'SINGLE') {
$markerArray = $this->getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $markerArray, $pObj);
} else {
$imageMode = (strpos($textRenderObj, 'LATEST') ? $lConf['latestImageMode'] : $lConf['listImageMode']);
$suf = '';
if (is_numeric(substr($lConf['image.']['file.']['maxW'], - 1))) { // 'm' or 'c' not set by TS
if ($imageMode) {
switch ($imageMode) {
case 'resize2max' :
$suf = 'm';
break;
case 'crop' :
$suf = 'c';
break;
case 'resize' :
$suf = '';
break;
}
}
}
// only insert width/height if it is not given by TS and width/height is empty
if ($lConf['image.']['file.']['maxW'] && ! $lConf['image.']['file.']['width']) {
$lConf['image.']['file.']['width'] = $lConf['image.']['file.']['maxW'] . $suf;
unset($lConf['image.']['file.']['maxW']);
}
if ($lConf['image.']['file.']['maxH'] && ! $lConf['image.']['file.']['height']) {
$lConf['image.']['file.']['height'] = $lConf['image.']['file.']['maxH'] . $suf;
unset($lConf['image.']['file.']['maxH']);
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$theImgCode .= str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.'])) . $pObj->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
}
$cc++;
}
if ($cc) {
$markerArray['###NEWS_IMAGE###'] = $pObj->local_cObj->wrap($theImgCode, $lConf['imageWrapIfAny']);
} else {
$markerArray['###NEWS_IMAGE###'] = $pObj->local_cObj->stdWrap($markerArray['###NEWS_IMAGE###'], $lConf['image.']['noImage_stdWrap.']);
}
}
if ($pObj->debugTimes) {
$pObj->hObj->getParsetime(__METHOD__);
}
// debug($markerArray, '$$markerArray ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 2);
return $markerArray;
}
/**
* Fills the image markers for the SINGLE view with data. Supports Optionssplit for some parameters
*
* #param [type] $lConf: ...
* #param [type] $imgs: ...
* #param [type] $imgsCaptions: ...
* #param [type] $imgsAltTexts: ...
* #param [type] $imgsTitleTexts: ...
* #param [type] $imageNum: ...
* #return array $markerArray: filled markerarray
*/
function getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $markerArray, $pObj) {
$marker = 'NEWS_IMAGE';
$sViewSplitLConf = array();
$tmpMarkers = array();
$iC = count($imgs);
// remove first img from image array in single view if the TSvar firstImageIsPreview is set
if (($iC > 1 && $pObj->config['firstImageIsPreview']) || ($iC >= 1 && $pObj->config['forceFirstImageIsPreview'])) {
array_shift($imgs);
array_shift($imgsCaptions);
array_shift($imgsAltTexts);
array_shift($imgsTitleTexts);
$iC--;
}
if ($iC > $imageNum) {
$iC = $imageNum;
}
// get img array parts for single view pages
if ($pObj->piVars[$pObj->config['singleViewPointerName']]) {
/**
* TODO
* does this work with optionsplit ?
*/
$spage = $pObj->piVars[$pObj->config['singleViewPointerName']];
$astart = $imageNum * $spage;
$imgs = array_slice($imgs, $astart, $imageNum);
$imgsCaptions = array_slice($imgsCaptions, $astart, $imageNum);
$imgsAltTexts = array_slice($imgsAltTexts, $astart, $imageNum);
$imgsTitleTexts = array_slice($imgsTitleTexts, $astart, $imageNum);
}
if ($pObj->conf['enableOptionSplit']) {
if ($lConf['imageMarkerOptionSplit']) {
$ostmp = explode('|*|', $lConf['imageMarkerOptionSplit']);
$osCount = count($ostmp);
}
$sViewSplitLConf = $pObj->processOptionSplit($lConf, $iC);
}
// reset markers for optionSplitted images
for ($m = 1; $m <= $imageNum; $m++) {
$markerArray['###' . $marker . '_' . $m . '###'] = '';
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
if (! empty($sViewSplitLConf[$cc])) {
$lConf = $sViewSplitLConf[$cc];
}
// if (1) {
// $lConf['image.']['imgList.'] = '';
// $lConf['image.']['imgList'] = $val;
// $lConf['image.']['imgPath'] = 'uploads/pics/';
// debug($lConf['image.'], ' ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 3);
//
// $imgHtml = $pObj->local_cObj->IMGTEXT($lConf['image.']);
//
// } else {
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$imgHtml = str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.'])) . $pObj->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
// }
//debug($imgHtml, '$imgHtml ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 3);
if ($osCount) {
if ($iC > 1) {
$mName = '###' . $marker . '_' . $lConf['imageMarkerOptionSplit'] . '###';
} else { // fall back to the first image marker if only one image has been found
$mName = '###' . $marker . '_1###';
}
$tmpMarkers[$mName]['html'] .= $imgHtml;
$tmpMarkers[$mName]['wrap'] = $lConf['imageWrapIfAny'];
} else {
$theImgCode .= $imgHtml;
}
}
$cc++;
}
if ($cc) {
if ($osCount) {
foreach ($tmpMarkers as $mName => $res) {
$markerArray[$mName] = $pObj->local_cObj->wrap($res['html'], $res['wrap']);
}
} else {
$markerArray['###' . $marker . '###'] = $pObj->local_cObj->wrap($theImgCode, $lConf['imageWrapIfAny']);
}
} else {
if ($lConf['imageMarkerOptionSplit']) {
$m = '_1';
}
$markerArray['###' . $marker . $m . '###'] = $pObj->local_cObj->stdWrap($markerArray['###' . $marker . $m . '###'], $lConf['image.']['noImage_stdWrap.']);
}
// debug($sViewSplitLConf, '$sViewSplitLConf ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 2);
return $markerArray;
}
}
?>
Most of this code is copied from class.tx_ttnews.php. The important line is the following (in each of the two functions):
str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.']))
Then you'll get the following image tags:
<img class="lazy" data-original="uploads/pics/myimage.jpg" width="110" height="70" border="0" alt="" />
In 2019 tt_news is still around. I use it with TYPO3 8 LTS, the version from github as its not anymore in the official extension repository. (For new Projects use "news")
So I think, because tt_news has to be updated in TYPO3 9, its legit to just hack the code directly, by changing tt_news/Classes/Plugin/TtNews.php like this:
--- a/Classes/Plugin/TtNews.php
+++ b/Classes/Plugin/TtNews.php
## -2621,6 +2621,7 ## class TtNews extends AbstractPlugin
$markerArray['###NEWS_IMAGE###'] = $this->local_cObj->stdWrap($markerArray['###NEWS_IMAGE###'],
$lConf['image.']['noImage_stdWrap.']);
}
+ $markerArray['###NEWS_IMAGE###'] = $this->LazyLoading($markerArray['###NEWS_IMAGE###']);
}
}
## -2632,6 +2633,13 ## class TtNews extends AbstractPlugin
}
+ function LazyLoading($html){
+ $html = str_replace('src="', 'class="lazy" data-original="', $html);
+ return $html;
+ }
+
+
/**
* Fills the image markers for the SINGLE view with data. Supports Optionssplit for some parameters
*