Get Customer Session without using cacheable="false" in Magento2 - magento2

I am trying to get customer session data (private data) from session and show on frontend on one of the block. Due to personalization, i am not getting the data when the cache is enabled. I looked for solutions to this and found that with cacheable="false" one can achieve to get customers private data from session with Cache enabled. But i realized that the whole page is kept out of cache because of this. Can anyone help me to get data in a particular block without using cacheable="false" ?

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\SessionFactory')->create();
By this way you can use the customer session without using the cachable="false"

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');
$customer = $objectManager->get('Magento\Customer\Model\Customer')->load($customerSession->getId());
$cust_name = '';
$cust_email ='';
$cust_telephone ='';
if($customerSession->isLoggedIn()) {
$cust_name = $customerSession->getCustomer()->getName();
$cust_email = $customerSession->getCustomer()->getEmail();
if(!empty($customer->getPrimaryBillingAddress())){
$cust_telephone = $customer->getPrimaryBillingAddress()->getTelephone();
}
}

Related

Shopware 6 : How to get dynamic url in custom plugin controller?

Shopware 6
I am new to shopware. I want base url in controller ( custom plugin ).
I tried this but it's not working for me.
$salesChannel->getDomains()->first()->getUrl();
Thanks in advance
If you just need the current host and base url in your controller:
use Shopware\Storefront\Framework\Routing\RequestTransformer;
use Symfony\Component\HttpFoundation\Request;
// ...
/**
* #Route(...)
*/
public function myAction(Request $request): Response
{
$host = $request->attributes->get(RequestTransformer::SALES_CHANNEL_ABSOLUTE_BASE_URL)
. $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
// ...
}
First : Add this namespace
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
Second : here you can get base url.
$urls = [];
$salesChannelRepository = $this->container->get('sales_channel.repository');
$criteria = new Criteria();
$criteria->addAssociation('domains');
$salesChannelIds = $salesChannelRepository->search($criteria, Context::createDefaultContext());
foreach($salesChannelIds->getEntities()->getElements() as $key => $salesChannel){
foreach($salesChannel->getDomains()->getElements() as $element){
array_push($urls, $element->getUrl());
}
}
you will get your url in $urls variable.
If you have access to the request object which you should have in a controller, you have access to an request attribute called sw-storefront-url. This will give you exactly what you need: the base-url of the current request.
See also How to get the current saleschannel domain in Shopware 6 storefront/TWIG?

Is It Normal to Directly Access the Codeigniter Controller?

I saw it in a friend's project, for example, the controller that guests can access has defined a route and it can only be accessed by route.
For example, when I said default_controller/index it wouldn't open.
Do you have a resource that you know how to do this?
He even made the route changeable from the database.
For example, you made the constant "home-page" variable "new-home-page".
Even when you call home-page, it was not reachable. it sounded very professional to me
/** About Us Page Uploads */
public function about_us()
{
$data["site_settings"] = $this->site_settings_model->getSite_settings('1');
$data['title'] = "xxxx";
$data['description'] = "xxxx";
$data['keywords'] = "xxxx";
$data['author'] = "xxxx";
$this->load->view('partials/header', $data);
$this->load->view('fixed_pages/about_us', $data);
$this->load->view('partials/footer', $data);
}
My route is registered as about us but,
Turns out I had both xxxx.com/about-us and xxxx.com/default_controller/about_us open in the browser as well.

In a REST API, to GET a resource, should I include the resource ID in the url?

I am trying to create an REST API for creating and retrieving files in my database. The tutorial I was following uses the following method to retrive a single file:
$app->get('/file/:file_id', 'authenticate', function($file_id) {
global $user_id;
$response = array();
$db = new DbHandler();
// fetch file
$result = $db->getFile($file_id, $user_id);
if ($result != NULL) {
$response["error"] = false;
$response["id"] = $result["id"];
$response["file"] = $result["fileLocation"];
$response["status"] = $result["status"];
$response["createdAt"] = $result["created_at"];
echoRespnse(200, $response);
} else {
$response["error"] = true;
$response["message"] = "The requested resource doesn't exist";
echoRespnse(404, $response);
}
});
Here they are using the HTTP GET method and are specifying the file ID in the URL, is it OK to do this, safety wise? Would it not be safer to use POST and hide the file ID in the body of the request, or should they not be putting the file ID in a header with the GET request? or is it not something I should be worried about?
In REST post method is used to create a new resource not to get it. Get method is used for fetching the resource and you need to specify the ID to determine particular resource. Passing it via URL is a common practice. You can randomly generate such ID to make it harder to guess.
As Opal said above, the ID is used to identify a resource. If you are unsure have a read of this - http://blog.teamtreehouse.com/the-definitive-guide-to-get-vs-post

Silverstripe - Restful Server Caching

for a web application (an Image Database) I am using the Restful Server Module. The Data is requested by another web application (a shop). The generation of the XML takes up to 1 second. the shop has to wait for the API to answer to display for example a Product Page. Is it possible to activate some caching for the Restful Server API?
I tried already with the Static Publisher but it seems to work just with cms pages.
Many thanks,
Florian
RestfulService does the caching for you. It accepts 2 paramaters. A serviceURL and also a cache time. The default is 3600 (1 hour). This is only going to work if the shop is built with silverstripe.
$serviceURL = 'http://www.imagedatabase.com/api/v1/Product?ID=1';
$service = new RestfulService($serviceURL, 7200); //2 hours expiry
$xml = $service->request()->getBody();
//get fields values
$productName = $service->searchValue($xml, 'Name');
$productPrice = $service->searchValue($xml, 'Price');
You also need to make a modification to Product assuming Product is a dataobject.
class Product extends DataObject {
...
static $api_access = true;
...
function canView($member = null) {
return true;
}
}
RestfulService docs
http://doc.silverstripe.org/framework/en/reference/restfulservice
well, I personally would cache on the client (so in the shop)
but if you have to, I don't think there is any built in way for this.
you could subclass the restful server and do some basic caching yourself (just the way the default SS RestfulClient does it, save it into a file)
class MyServer extends RestfulServer {
public $cache_expire;
function __construct($cache_expire = 3600) {
$this->cache_expire = $cache_expire;
}
protected function getHandler($className, $id, $relationName) {
$cache_path = Director::getAbsFile("assets/rest-cache/$className-$id-$relationName.{$this->request->getExtension()}");
if ($this->cache_expire > 0 && !isset($_GET['flush'])
&& #file_exists($cache_path) && #filemtime($cache_path) + $this->cache_expire > time()
) {
$store = file_get_contents($cache_path);
$response = unserialize($store);
} else {
$response = parent::getHandler($className, $id, $relationName);
$store = serialize($response);
file_put_contents($cache_path, $store);
}
return $response;
}
}
// NOTE, I have never tested this code, so you might run into minor spelling mistakes or something like that

Zend_Auth not working

In my model, "Users", I have the following authorization after validating the username/password
$db = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($db,'users','username','password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential(md5($password));
$auth_result = $authAdapter->authenticate();
if( $auth_result->isValid() )
{
$auth = Zend_Auth::getInstance();
$storage = $auth->getStorage();
$storage->write($authAdapter->getResultRowObject(array('id','username')));
return 'logged_in';
}
return 'auth_failed';
it keeps returning 'auth_failed'. I had the code running on a localhost, and everything works fine, but when I upload it online, it fails to authorize the user. What is going on?
Thanks
I can't tell what's wrong without checkin the logs, so perhaps you might want to use the method I use for storing auth data. Basically you validate manually and set the storageThis doesn't solve the problem, but its impossible to do so without accessing your code.
function login($userNameSupplied,$passwordSupplied){
$table= new Application_Model_Dbtable_Users();//Or Whatever Table you're using
$row=$table->fetchRow($table->select()->where('username=?',$userNameSupplied)->where('password=?',md5($passwordSupplied));
if($row){
Zend_Auth::getInstance()->getStorage()->write($row->toArray());
return 'logged_in';
}
else{return 'failed';}
}
//To check if the user is logged in, use
$userInfo=Zend_Auth::getInstance()->getStorage()->read();
if($userInfo)//user is logged in