PHPExcel clear cell comments - comments

Is it possible to clear all cell comments in PHPExcel before adding a new one? I have working code that adds a comment but I would like to clear all existing comments in a particular cell first:
$pexr = PHPExcel_IOFactory::createReader('Excel2007');
try {
$pex = $pexr->load($fn);
} catch (Exception $e) {
//...
return;
}
}
// ...
sheet = $pex->getSheetByName($curMed);
...
$sheet->setCellValue($col . $row, $r[7]);
$sheet->getStyle($col . $row)->getNumberFormat()->setFormatCode('#,##0');
$sheet->getComment($col . $row)->getText()->createText("My lovely comment\r\n");
Unfortunately I could not find anything like "clear" in the documentation.

Comments are stored as an array, indexed by cell address in the worksheet object; and it provides methods to get and set the entire array; so it's perfectly possible to retrieve the array, unset comments for the cell that you want to clear, then put the array back again overwriting the original:
$comments = $sheet->getComments();
if (isset($comments[$col . $row])) {
unset($comments[$col . $row]);
$sheet->setComments($comments);
}

Related

Check if Config item exists

I would like to know if there is a way to check if a config item exists.
I have a case where I refer to some config items in the config/custom.php file, and others in a database table.
The concept is to make use of existing config items that exist in config/custom.php, and when they don't exist, I pull them from my database.
$config = Config::get($configtype . '.' . $configname);
if (!$config){
// if config not found, then get it from the database
$configrecord = Newconfigs::where(['name' => $configname])->get()->first();
if (!$configrecord){
$config = false;
} else{
$config = $configrecord->value;
}
}
return ($config);
As you can see, doing it this way will not cater for config values of NULL of FALSE.
I would like to do something like this in my very first line to check if the config "exists" in the file...
If(Config::exists($configtype . '.' . $configname)){ } else{ //get from database }
Is there such a thing?
After searching found a solution. Here is the solution that can help
if (config()->has('some.key')) {
// Get configuration value from config file
} else {
// Get configuration value from database
}

Modify the existing canonical link in header

I am using Joomla 2.5 and I want to change the canonical link in the header.
I do this in category view (components/com_content/category/tmpl/default.php)
$url = JURI::root();
$sch = parse_url($url, PHP_URL_SCHEME);
$server = parse_url($url, PHP_URL_HOST);
$canonical = $this->escape($_SERVER['REQUEST_URI']);
$document->addCustomTag('<link rel="canonical" href="'.$sch.'://'.$server.$canonical.'"/>');
It prints the right canonical, but it also leaves the old canonical link there so that I have 2 canonical links in the header.
How can I change or delete the old canonical link?
I have found the following to work for me with Joomla! 3.2.1. You can directly modify the
$_links
variable in the JHtmlDocument object.
I'm doing a subset of the following in a particular view of my component because the URL that Joomla! is coming up with is not correct.
Hope this helps.
$document = JFactory::getDocument();
foreach($document->_links as $key=> $value)
{
if(is_array($value))
{
if(array_key_exists('relation', $value))
{
if($value['relation'] == 'canonical')
{
// we found the document link that contains the canonical url
// change it!
$canonicalUrl = 'http://www.something.com/index.php/component/my-component-name-here/?view=viewNameHere&parameterNameHere=parameterValueUsedInTheViewRightNow
$document->_links[$canonicalUrl] = $value;
unset($document->_links[$key]);
break;
}
}
}
}
What you probably want to do instead is something like the following:
$doc_data = $document->getHeadData();
$url = JURI::root();
$sch = parse_url($url, PHP_URL_SCHEME);
$server = parse_url($url, PHP_URL_HOST);
$canonical = $this->escape($_SERVER['REQUEST_URI']);
$newtag = '<link rel="canonical" href="'.$sch.'://'.$server.$canonical.'"/>'
$replaced = false;
foreach ($doc_data['custom'] as $key=>$c) {
if (strpos($c, 'rel="canonical"')!==FALSE) {
$doc_data['custom'][$key] = $newtag;
$replaced = true;
}
}
if (!$replaced) {
$doc_data['custom'][] = $newtag;
}
$document->setHeadData($doc_data);
This will grab all of the current head data from the document, including the canonical link that you want to replace. It will search through the custom set (where I'm guessing this will be) and if it finds it, replace it with yours. If it doesn't find it, then it tacks it on at the end. Just in case.
Potential problems with this that I can see right away:
If the tag contained rel='canonical' with single quotes it would not be found, so you may have to adjust that.
The tag may have been placed in a different section of what I've termed $doc_data. You may want to do a var_dump($doc_data}; to confirm the location of the variable in this array.

Magento - get bundled products where a simple product belongs to

I want to show all bundles on a simple product's page and so need to retrieve the information. I searched and tried a lot. This post sounds promising, but is either not working or maybe not for my problem:
Magento - get a list of bundled product ids from a product id
I found a solution for grouped products but this can't be applied here.
$grouped_product_model = Mage::getModel('bundle/product_selection');
$groupedParentId = $grouped_product_model->getParentIdsByChild($product->getId());
I found the table catalog_product_bundle_selection to be the right place to search, but I wonder if there is a clean way and existing function to search this table by product_id than just to hack this.
I didn't find a solution in Mage_Bundle.
What did I miss?
After getting first aid from vrnet I wrote a new block class, so I can update the layout
class Thomaier_Catalog_Block_Product_View_BundledSelect extends Mage_Catalog_Block_Product_View
{
protected $_simpleProducts = array( '3' ); // just an example
public function getBundles() {
$bundleIds = array();
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundlesCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
...
}
}
I skipped some parts. As I mentioned in the comment, the SQL query works fine when I try it in phpmyadmin, but $bundleItem is not created and ->load() throws an exception.
Thanks for advice.
Below is a method I wrote for a client having the same request with an extra : the ability to shuffle the result.
Hope it helps.
protected $_simpleProducts = array(); // Array with IDs of simple products you want bundles from.
protected $_shuffle = false;
public function getBundles() {
$bundleIds = array();
/*Rather than using a collection model
and make operations with getSelect,
a more elegant way is to extend
Mage_Bundle_Model_Mysql4_Selection_Collection
with a method that would be something like
setProductIdsFilter($productIds)*/
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundleCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
if (count($bundleIds)) {
$allowBundles = Mage::getResourceModel('catalog/product_collection')
->addIdFilter($bundleIds)
->addFieldToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
if ($this->_shuffle) {
$allowBundles->getSelect()->order('rand()');
}
if ($allowBundles->count()) {
return $allowBundles;
}
}
return;
The following is the best way to work with these. This way you do not rely on a custom query but instead you can use the core methods:
$bundlesCollection = Mage::getResourceModel('bundle/selection')
->getParentIdsByChild($simple_product_ids_array_or_int);
foreach ($bundlesCollection as $bundleProdId) {
//do anything you want with the bundleProdId array elements
}

How can I addslashes() to elements of a multidimensional array? (php)

I have a multidim array from my $_POST but I have to serialize() then save to the database...
Normally, I can serialize but I got some problem with slashes (apostrophe and double quote).
My array seems like this: $array["hu"]["category"]["food"] = "string";
But when the "string" contains "" or '' theres's shit...
I need some short code for add slashes, but thres a lots of wrong solutions out there.
p.s.: I'm a CodeIgniter user.
// update:
function addslashesextended(&$arr_r) {
if (is_array($arr_r)) {
foreach ($arr_r as &$val){
if( is_array($val) ){
addslashesextended($val);
}else{
$val = addslashes($val);
}
}
unset($val);
} else {
$arr_r = addslashes($arr_r);
}
}
Thx!
I think the best solution would be to use the codeigniter input class and active record class . Addslasches/escapes, and most general sanitization will be taken care of for you.
http://codeigniter.com/user_guide/libraries/input.html
http://codeigniter.com/user_guide/database/active_record.html

linqToSql related table not delay loading properly. Not populating at all

I have a couple of tables with similar relationship structure to the standard Order, OrderLine tables.
When creating a data context, it gives the Order class an OrderLines property that should be populated with OrderLine objects for that particular Order object.
Sure, by default it will delay load the stuff in the OrderLine property but that should be fairly transparent right?
Ok, here is the problem I have: I'm getting an empty list when I go MyOrder.OrderLines but when I go myDataContext.OrderLines.Where(line => line.OrderId == 1) I get the right list.
public void B()
{
var dbContext = new Adis.CA.Repository.Database.CaDataContext(
"<connectionString>");
dbContext.Connection.Open();
dbContext.Transaction = dbContext.Connection.BeginTransaction();
try
{
//!!!Edit: Imortant to note that the order with orderID=1 already exists
//!!!in the database
//just add some new order lines to make sure there are some
var NewOrderLines = new List<OrderLines>()
{
new OrderLine() { OrderID=1, LineID=300 },
new OrderLine() { OrderID=1, LineID=301 },
new OrderLine() { OrderID=1, LineID=302 },
new OrderLine() { OrderID=1, LineID=303 }
};
dbContext.OrderLines.InsertAllOnSubmit(NewOrderLines);
dbContext.SubmitChanges();
//this will give me the 4 rows I just inserted
var orderLinesDirect = dbContext.OrderLines
.Where(orderLine => orderLine.OrderID == 1);
var order = dbContext.Orders.Where(order => order.OrderID == 1);
//this will be an empty list
var orderLinesThroughOrder = order.OrderLines;
}
catch (System.Data.SqlClient.SqlException e)
{
dbContext.Transaction.Rollback();
throw;
}
finally
{
dbContext.Transaction.Rollback();
dbContext.Dispose();
dbContext = null;
}
}
So as far as I can see, I'm not doing anything particularly strange but I would think that orderLinesDirect and orderLinesThroughOrder would give me the same result set.
Can anyone tell me why it doesn't?
You're just adding OrderLines; not any actual Orders. So the Where on dbContext.Orders returns an empty list.
How you can still find the property OrderLines on order I don't understand, so I may be goofing up here.
[Edit]
Could you update the example to show actual types, especially of the order variable? Imo, it shoud be an IQueryable<Order>, but it's strange that you can .OrderLines into that. Try adding a First() or FirstOrDefault() after the Where.

Resources