How can I implement log4php in order to log multiple classes separately?
I have the following example for classes A and B:
class A{
private $log;
private static $instance;
public static function getInstance(): Db3
{
if (!self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
function __construct()
{
Logger::configure('path/to/log4php.xml');
$this->log = Logger::getLogger(__CLASS__);
}
}
and also class B:
class B{
private $log;
private static $instance;
public static function getInstance(): Db3
{
if (!self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
function __construct()
{
Logger::configure('path/to/log4php.xml');
$this->log = Logger::getLogger(__CLASS__);
}
}
This is the log4php.xml config:
<configuration xmlns="http://logging.apache.org/log4php/">
<appender name="A" class="LoggerAppenderDailyFile">
<param name="file" value="/path/to/logs/%s.A.log" />
<param name="datePattern" value="Y-m-d" />
<layout class="LoggerLayoutPattern">
<param name="conversionPattern" value="%date{Y-m-d H:i:s,u} %-15logger %-5level %msg%n" />
</layout>
</appender>
<appender name="B" class="LoggerAppenderDailyFile">
<param name="file" value="/path/to/logs/%s.B.log" />
<param name="datePattern" value="Y-m-d" />
<layout class="LoggerLayoutPattern">
<param name="conversionPattern" value="%date{Y-m-d H:i:s,u} %-15logger %-5level %msg%n" />
</layout>
</appender>
<logger name="A"><level value="DEBUG" /><appender_ref ref="A" /></logger>
<logger name="B"><level value="DEBUG" /><appender_ref ref="B" /></logger>
</configuration>
I need log4php to log class A and class B separately but for some reason it is not working if I do this:
$a=A::getInstance();
$a->test();
$b=B::getInstance();
$b->test();
Everything gets logged in the same file, not in yyyy-mm-dd.A.log and B.log
test() only has this line: $this->log->info('this is a test') in both classes.
Related
I am learning OOP in PHP and in an exercise, I don't know how to send form data to objects and enter the objects in an array. I was going through a lot of Youtube tutorials and forums but I couldn't find or understand much.
The exercise first asks for a class to manage the products of a supermarket whose attributes are the numeric key, the description, the price and the stock. It also asks me to define a constructor with parameters as methods.
<?php
class Product{
private $key;
private $description;
private $price;
private $stock;
public function __construct($key, $description, $price, $stock){
$this->key = $key;
$this->description = $description;
$this->price = $price;
$this->stock = $stock;
}
public function setKey($key){
$this->key = $key;
}
public function getKey(){
return $this->key;
}
public function setDescription($description){
$this->description = $description;
}
public function getDescription(){
return $this->description;
}
public function setPrice($price){
$this->price = $price;
}
public function getPrice(){
return $this->price;
}
public function setStock($stock){
$this->stock = $stock;
}
public function getStock(){
return $this->stock;
}
}
Then it asks me to use that class to declare an array of objects and control an inventory of up to 50 products using the POST method. In addition this program must have a menu with the next items: Add product, Remove product, List product, Sort product by key number and Exit.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<form method="post">
<label for="key">Enter product key</label></br>
<input type="number" name="key" id="key" required></br>
<label for="description">Enter product description</label></br>
<input type="text" name="description" id="description" required></br>
<label for="price">Enter product price</label></br>
<input type="text" name="price" id="price" required></br>
<label for="stock">Enter the stock of the product</label></br>
<input type="number" name="stock" id="stock" required></br>
<button type="submit" name="add" id="add">Add product</button>
<button type="submit" name="baja" id="baja">Remove product</button>
<button type="submit" name="list" id="list">List product</button>
<button type="submit" name="Sort" id="Sort">Sort product</button>
<button type="submit" name="exit" id="exit">Exit</button>
</form>
</body>
</html>
Here is the problem: I don't know how to insert the object in the array without deleting the previous ones and I don't know how to print all the entered objects.
<?php
if (strlen(session_id()) < 1) {
session_start();
}
include_once("product.php");
if(isset($_POST["add"])){
$_SESSION["quantity"] = $_SESSION["quantity"] +1;
$quantity = $_SESSION["quantity"];
if($quantity<=50){
$oproduct = new Product($_POST["key"], $_POST["description"], $_POST["price"],
$_POST["stock"]);
$oproduct->setKey($_POST["key"]);
$oproduct->setDescription($_POST["description"]);
$oproduct->setPrice($_POST["price"]);
$oproduct->setStock($_POST["stock"]);
$_SESSION["prod"]= $oproduct;
print_r($_SESSION["prod"]);
}
}
Dynamically append [] a new product to the array:
$_SESSION["prod"][] = $oproduct;
Or you could use key if it is unique:
$_SESSION["prod"][$_POST["key"]] = $oproduct;
Also, it looks like you have already added the info here:
$oproduct = new Product($_POST["key"], $_POST["description"], $_POST["price"], $_POST["stock"]);
So why are you doing this?
$oproduct->setKey($_POST["key"]);
$oproduct->setDescription($_POST["description"]);
$oproduct->setPrice($_POST["price"]);
$oproduct->setStock($_POST["stock"]);
I have a radio group that filters my table to show whether items are active, inactive or both. There is also a button that I am using to export an excel document of the table. My current button downloads all the records. What I want is to export the document based on the filter so if active is selected and showing and the download button is pressed, only active records will be exported
My code:
Controller:
public function filter()
{
$energy = Energy::where('isredundant', 0)->paginate(10);
return view('admin.staff', ['staff1' => $staff1]);
}
public function filtered()
{
$energy = Energy::where('isredundant', 1)->paginate(10);
return view('admin.staff', ['staff1' => $staff1]);
}
public function export()
{
return Excel::download(new UsersExport, 'allrecords.xlsx');
}
public function export()
{
return Excel::download(new UsersExport, 'AllReport.xlsx');
}
public function exportactive()
{
return Excel::download(new UsersExportactive, 'ActiveRecords.xlsx');
}
public function exportredundant()
{
return Excel::download(new UsersExportredundant, 'RedundantRecords.xlsx');
}
my button:
<div> <a class="btn btn-warning" href="/export_excel/excel">Generate Report</a></div>
I tried to use 3 different buttons but that just looks messy. I'm sure there's an easier method
you can try this way
in controller
public function exportactive(Request $request)
{
return Excel::download(new UsersExportactive($request->ids), 'ActiveRecords.xlsx');
}
in UsersExportactive() class
private $ids;
public function __construct($ids)
{
$this->ids = $ids;
}
and do a query for that for like that in UsersExportactive() class
Model::whereIn('id',$ids)->get();
and in view use your export button as a submit button like below
<form>
<input type="checkbox" name="ids[]" id="1"/>active
<input type="checkbox" name="ids[]" id="2"/>inactive
<input type="submit" id="download" value="download Excel"/>
</form>
<input type="radio" name="download" id="x86"/>active<br />
<input type="radio" name="download" id="x64"/>inactive<br />
<input type="button" id="download" value="download"/>
var radio_x86 = document.getElementById('x86');
var radio_x64 = document.getElementById('x64');
var button = document.getElementById('download');
button.onclick = downloadFile;
function downloadFile() {
if (radio_x86.checked) {
window.open("/app/test");
} else if (radio_x64.checked) {
window.open("/app/test1");
} else {
alert("Please check one of the options first.");
}
}
I am trying to enable my custom module only for a single store view but the functionality is still working for all store views.
I have the following configuration:
Main Website > (Default store view, B2B Store view)
I want to enable my module only for the B2B Store view.
I tried to did this using system.xml: Code is:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="customrfq" translate="label" sortOrder="1000">
<label>Request For Quote</label>
</tab>
<section id="customrfq" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>RFQ</label>
<tab>customrfq</tab>
<resource>CustomB2BRFQ_Module::rfq</resource>
<group id="department" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>RFQ configuration</label>
<field id="view_list" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Show Quotes</label>
<comment>Show request for quotes</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
</config>
Config.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<customrfq>
<department>
<view_list>1</view_list>
</department>
</customrfq>
</default>
</config>
Layout file:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="CustomB2BRFQ\Module\Block\RequestForQuoteForm" name="custom_module_form"
template="CustomB2BRFQ_Module::rfq.phtml" ifconifg="customrfq/department/view_list" cacheable="false"/>
<arguments>
<argument name="path" xsi:type="helper" helper="CustomB2BRFQ\Module\Helper\Data::getPath" translate="true" />
</arguments>
</referenceContainer>
</body>
</page>
Helper File:
<?php
/**
* Created By : Rashi Goyal
*/
namespace CustomB2BRFQ\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
const PATH_FIELD = 'customrfq/department/view_list';
/**
* #var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfig;
/**
* #param \Magento\Framework\App\Helper\Context $context
* #param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
){
$this->scopeConfig = $scopeConfig;
parent::__construct($context);
}
public function getPath()
{
return $this->scopeConfig->getValue(self::PATH_FIELD,\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
}
}
Please specify what's wrong with the code?
I think you have set wrong values for following properties (system.xml):
showInDefault
showInWebsite
showInStore
According to your requirement, you want functionality by store. So you have to set these properties like this:
showInDefault="0"
showInWebsite="0"
showInStore="1"
Using this, your configuration setting display only on store view.
Also You have assigned default value = 1 (config.xml)
You should use by default this:
<view_list>0</view_list>
I have a view views/detailedforms/view.html.php
defined('_JEXEC') or die;
jimport('joomla.application.component.view');
class Detailed_formViewDetailedforms extends JViewLegacy {
protected $items;
protected $pagination;
protected $state;
protected $params;
protected $form;
/**
* Display the view
*/
public function display($tpl = null) {
$app = JFactory::getApplication();
$this->state = $this->get('State');
$this->form = $this->get('Form');
var_dump($this->form);
}
and model models/forms/detailedforms.xml
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset name="contact" label="Detail_FORM">
<field name="name"
type="text"
id="tailor-made-name"
size="30"
description="FORM_NAME_DESC"
label="FORM_NAME_LABEL"
filter="string"
required="true"
/>
<field name="email"
type="email"
id="email"
size="30"
description="EMAIL_DESC"
label="EMAIL_LABEL"
filter="string"
validate="tailoremail"
required="true"
/>
</fieldset>
$this->form returns null. Please help, how to fix the issue.
Due to this issue, fatal error occurs in the template file.
I'd created a template file for admin form tab as:
class Excellence_Designer_Block_Adminhtml_Designer_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
protected function _beforeToHtml() {
$this->addTab('images', array(
'label' => Mage::helper('designer')->__('Images'),
'title' => Mage::helper('designer')->__('Images'),
'content' => $this->getLayout()->createBlock('designer/adminhtml_designer_edit_tab_images')->toHtml(),
));
return parent::_beforeToHtml();
}
}
class Excellence_Designer_Block_Adminhtml_Designer_Edit_Tab_Images extends
Mage_Adminhtml_Block_Template implements
Mage_Adminhtml_Block_Widget_Tab_Interface {
public function _construct() {
parent::_construct();
$this->setTemplate('designer/edit/tab/images.phtml');
}
public function getTabLabel() {
return $this->__('Images');
}
public function getTabTitle() {
return $this->__('Images');
}
public function canShowTab() {
return true;
}
public function isHidden() {
return false;
}
}
images.phtml
<div class="input-field">
<label for="image">Custom Field</label>
<input type="text" class="input-text" name="image" id="image" />
</div>
but there's no value in there if I do want to edit the form
even the value is saved in database. The other tab was created with Mage_Adminhtml_Block_Widget_Form and showing the values in fields but for this how could I get the value?
Your EditAction() has to be in the way. Check it out.
public function editAction()
{
$newsId = $this->getRequest()->getParam('id');
$newsModel = Mage::getModel('news/news')->load($newsId);
if ($newsModel->getId() || $newsId == 0) {
$data = Mage::getSingleton('adminhtml/session')->getFormData(true);
if (!empty($data)) {
$model->setData($data);
}
Mage::register('news_data', $newsModel);
$this->loadLayout();
$this->_setActiveMenu('news/items');
$this->_addBreadCrumb(Mage::helper('adminhtml')->__('Item Manager'), Mage::helper('adminhtml')->__('Item Manager'));
$this->_addBreadCrumb(Mage::helper('adminhtml')->__('Item News'), Mage::helper('adminhtml')->__('Item News'));
$this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
$this->_addContent($this->getLayout()->createBlock('news/adminhtml_news_edit'))
->_addLeft($this->getLayout()->createBlock('news/adminhtml_news_edit_tabs'));
$this->renderLayout();
}
else
{
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('news')->__('Item does not exist'));
$this->_redirect('*/*/');
}
}
I'd come to a solution don't know is it the right approach but works in my case. If you have a better solution then let me know.
I'd made a change in images.phtml
<div class="input-field">
<label for="image">Custom Field</label>
<input type="text" value="<?php echo $this->getValue(); ?>" class="input-text" name="image" id="image" />
</div>
and added a method in the respective block file
public function getValue() {
return Mage::registry('designer_data')->getImage();
}