1 . Hide WooCommerce data from other admins in Wordpress?

Answer :

You could create a new role in code and add specific capabilities to it. But it's much easier to use a role editor plugin like User Role Editor

Just create a new role and assign the capabilities you want while leaving out those of Woocommerce.

Leave a Comment

1 . What are the ways to lower the spam score of the email message?

Answer :

Using the AlternateView class, you can specify a text/plain body and provide an alternate html body for the marketing boys. Even if the text part only says that you should have an html enable reader, the spam filter will drop 1.8 points.

Then if you start the HTML message with a proper tag (just take a full html page), you will drop 2.8 poins.

You can also include LinkedResources so you can send the image without showing attachments.

2 . Why did Safari autofill populates any field with a placeholder attribute containing the word “email” with the user's email address?

Answer :

The solution to this is to either:

  1. Remove the word "email" from the placeholder altogether
  2. Do some crazy javascript and/or CSS workaround using hidden fields and offsets to hide the field outside the viewport
  3. Be "sneaky" and use similar Unicode letters to replicate the word "email" with alternatives.

I don't like option 1 because I shouldn't have to. Nobody should - in this instance Safari is just plain wrong to do what it's doing and give web devs no control over the autofill behaviour.

Secondly, removing the word "email" could influence the marketing attribution data that is genuinely typed by our users and so it isn't something that my company was willing to do.

The same goes for option 2 - implementing a load of JS and/or CSS to overcome this is bad practice and should only be used as an absolute last resort if nothing else works.

So I opted for the latter option. I found a very useful list of Unicode confusables here:

This list helped me find an alternative "e":


Unfortunately this didn't change the autofill behaviour, which is why I suspect that it might looking for the word "mail" as well as "email".

I was unable to find an adequate replacement for "m" but I did find one for "a":


Doing this did the trick and Safari no longer autofills my non-email field with the user's email address.

The final placeholder now looks like this:

placeholder="E.g. recommended, Google, ?m?il, Sunday Times"

3 . Comparison of two different SOQL queries?

Answer :

You're making a callout in a loop, there's governor limit of max 100 callouts. See Limits class to obtain current & max numbers programatically rather than hardcoding it.

Other than that it should be pretty simple change. First add your filter to the query and add a "subquery" (something like a JOIN) that pulls the related list of subscriptions

list<Account> conts = new list<Account> ([SELECT name, Email_FLP_com__c,
        (SELECT Id
        FROM Stripe_Subscriptions__r
        WHERE Start_Date__c= TODAY
            AND Status__c='active'
            AND Welcome_Email__C = false
        LIMIT 1)
    from account
    where ID IN (
        select Distributor__c
        from Stripe_Subscripton__c
        where Start_Date__c= TODAY
            AND Status__c='active'
            AND Welcome_Email__C = false)
    AND  Email_FLP_com__c != NULL
    LIMIT 100]);

Then it's just few lines more

List<Stripe_Subscription__c> subsToUpdate = new List<Stripe_Subscription__c>();

for(Account a : conts){
    // do your maropost code here

    a.Stripe_Subscriptions__r[0].Welcome_Email__c = true;
update subsToUpdate;

Of course you might want to set that checkbox to true only if callout went OK ;

4 . What is the best method to access a large database using MVC 4 and Entity Framework 6?

Answer :

Updating multiple database rows in EF is slow!

I assume there is a table called CampaignContacts containing the data from the n-to-n relationship of Campaign and Contacts. Luckily EF6 allows you to execute raw queries.

using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Text;

public class YourDbContext : DbContext
    public void DeleteBatchCampaignContacts(IList<int> ids)
        if (ids == null) return;
        if (ids.Count == 0) return;         

        //ONLY because the parameter comes from a list of Int, else you might risk injection
        Database.ExecuteSqlCommand(string.Format("DELETE FROM CampainContacts WHERE CampaignId in ({0})", string.Join(",", ids)));

    public void UpdateBatchCampaignContacts(int campaignId, IList<int> ids)
        if (ids == null) return;
        if (ids.Count == 0) return;

        Database.ExecuteSqlCommand(string.Format("UPDATE CampaignContacts SET CampaignId = @campaignId WHERE EmailContactId in ({0})", string.Join(",", ids),
            new SqlParameter("@campaignId", campaignId)));

Notice the code duplication. You can refractor these functions, but this would be quicker than your current solution. You can add features like executing the query in batches of 50 IDs in order to handle thousands of IDs updates. This is a start.

5 . Accented words in email subject break spacing - how do I stop this?

Answer :

You need to encode the space in between as well (see RFC 2047):

(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)     (ab)

White space between adjacent 'encoded-word's is not displayed.


(=?ISO-8859-1?Q?a_b?=)                      (a b)

In order to cause a SPACE to be displayed within a portion of encoded text, the SPACE MUST be encoded as part of the 'encoded-word'.

(=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=)    (a b)

In order to cause a SPACE to be displayed between two strings of encoded text, the SPACE MAY be encoded as part of one of the 'encoded-word's.

So this should do it:

Subject: =?ISO-8859-1?Q?=C1ngel=20R=EDos?= escucha y sorprende

Edit     this function:

function _encodeHeader($str, $charset='ISO-8859-1')
    $words = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    $func = create_function('$match', 'return $match[0] === " " ? "_" : sprintf("=%02X", ord($match[0]));');
    $encoded = false;
    foreach ($words as $key => &$word) {
        if (!ctype_space($word)) {
            $tmp = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $word);
            if ($tmp !== $word) {
                if (!$encoded) {
                    $word = '=?'.$charset.'?Q?'.$tmp;
                } else {
                    $word = $tmp;
                    if ($key > 0) {
                        $words[$key-1] = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $words[$key-1]);
                $encoded = true;
            } else {
                if ($encoded) {
                    $words[$key-2] .= '?=';
                $encoded = false;
    if ($encoded) {
        $words[$key] .= '?=';
    return implode('', $words);

6 . Best practices for sending automated daily emails from web service?

Answer :

With regard to your first question, yes, you should set up your own mail server. Using gmail to do this might work for a while, but they are likely to shut you down in short order when they see this kind of activity. You could sign up for a business account and use app engine to send messages. Here's a link with information about mail quotas for that service.

Regarding your second and third questions, It would be a good idea to have messages queued by the web app and sent out by a centralized service rather than having the app send out the messages on its own.

Usually I would just use a database table as a queue - the web app inserts rows for each message it wants to send. A service/scheduled task app would grab new messages out of the table and send them off. This gives you lots of flexibility if you want to switch mail servers later, better reliability if the mail server is down, easier diagnostics if there are problems with recipients not getting messages, and the ability to resend messages. As for using JMS/MQ to do this - probably not necessary. IMO a database table used as a queue would give you more flexibility here than an actualy JMS-based queue system.

As for opt outs, YES - you should give people a way to opt out. I don't think you need to flag the messages as bulk though.

7 . Adding and removing jobs dynamically to Quartz.NET Windows Service?

Answer :

You can install Quartz.Net as a windows service and configure it to use AdoJobStore.
Your WinForm application will be the interface where you can add, suspend and remove jobs and triggers.

You do not have to stop your windows services while you're doing that.

You do not need to read your database to figure out what's happening in Quartz but you must use the APIs provided.

I've done something similar long time ago; my quartz.net "manager" was a web application.

You can read my answer here.

I guess the steps to do what you're looking for a pretty much the same.

Reference to Quartz.net samples and a free book can be found here and here.

8 . Delete after insert inside transaction?

Answer :

Yes, you can insert records, and delete same, to a table within the transaction.

Try this sample for proof of concept:

declare @foo table (id int)
begin tran

    insert into @foo 
        values (1),(2),(3)

    delete @foo where id = 2

    select * from @foo --will result in 2 rows: 1 and 3

commit tran

9 . Looking for assistance in creating similar functionality for importing and mapping a CSV, similar to Mailchimp?

Answer :

Based on what you've provided for me, I've put the following PHP class together which should hopefully provide you with the functionality you need. The bottom of the code demonstrates the usage of the small class.

class CSVtoSQL {
    private $filePath, $csvData;

    public function __construct($filePath) {
        $this->filePath = $filePath;

    public function readDataIn() {
        $file = fopen($this->filePath, 'r');
        $data = fread($file, filesize($this->filePath));

        // Split CSV line by line.
        $lines = explode("\n", $data);

        // Split each line by commas to extract each value.
        for ($i = 0; $i < sizeof($lines); $i++) {
            $this->csvData[$i] = explode(',', $lines[$i]);


        // Returns true if we managed to read data, false if we didn't.
        return (sizeof($this->csvData) > 0);

    public function getHeadings() {
        if (sizeof($this->csvData) > 0) {
            // The first index of csvData has all the headings.
            return $this->csvData[0];
        else {
            return null;

    public function pushToDatabase($con, $tableName, $columns) {
        $createColumnQuery = '';
        $insertQuery = 'INSERT INTO ' . $tableName . ' (';

        // Build column section of query.
        foreach ($columns as $column) {
            $createColumnQuery .= $column['name'] . ' ' . $column['type'] . ',';

        // Remove trailing comma.
        $createColumnQuery = rtrim($createColumnQuery, ',');

        // Create table.
        $con->query('CREATE TABLE ' . $tableName . ' (' . $createColumnQuery . ')');

        // Create insert query template.
        foreach ($columns as $column) {
            $insertQuery .= $column['name'] . ',';

        // Remove trailing comma.
        $insertQuery = rtrim($insertQuery, ',');

        // Insert values using our insertQuery string which looks like: "INSERT INTO <<table name>> (<<column 1>>, <<column 2>>"
        // Also skip the first line as that has the headings.
        for ($i = 1; $i < sizeof($this->csvData); $i++) {
            $values = '';

            foreach($this->csvData[$i] as $value) {
                $values .= '\'' . $value . '\',';

            // Remove trailing comma.
            $values = rtrim($values, ',');
            $con->query($insertQuery . ') VALUES (' . $values . ')');

$csv = new CSVtoSQL('test.csv');
$con = new mysqli('', 'root', '', 'testdb');
$columns = array(array('name'=>'col1', 'type'=>'VARCHAR(256)'),
                array('name'=>'col2', 'type'=>'VARCHAR(256)'),
                array('name'=>'col3', 'type'=>'VARCHAR(256)'));
$csv->pushToDatabase($con, 'test_table', $columns);

When creating a new object of the class CSVtoSQL, pass through the path to the CSV file (this can be relative or absolute). Then call the readDataIn() procedure to open the CSV, pull out the lines and store them in the object. Then you can optionally fetch an array of headings found in the CSV by calling getHeadings(). This will be useful for you when you wish to prompt the user for what database columns they wish to map each CSV heading to. Lastly, call pushToDatabase() and provide a MySQLi connection object, a table name and column data, as demonstrated.

10 . Filtering Objects in Database by Keyword?

Answer :

Replace total_campaigns_<day_of_week> statements and for loop with

total_campaigns = {}
for day in days:
    total_campaigns[day] = Email.objects.filter(day_of_week=day).count()

In templates you can use {{ total_campaigns.Monday }} or {{ total_campaigns.Sunday }} or something similar.

11 . Trouble targeting elements on website (selenium webdriver)?

Answer :

The key problem here is that the search results are loaded in an iframe.

You need to switch to iframe before searching for properties.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()

# wait for frame to appear and switch
frame = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div#buildout iframe")))

for property in driver.find_elements_by_class_name('propertyList'):
    info = property.find_element_by_class_name('addressInfo')
    email = property.find_element_by_partial_link_text('Email')

    print info.text
    print print email.get_attribute('href')

I've also applied two fixes:

  • replaced find_elements_by_class_namme with find_elements_by_class_name
  • replaced property.find_elements_by_partial_link_text('.com') with property.find_element_by_partial_link_text('Email')

It prints:

Engelberg Antik's
Salem, OR
Outstanding downtown Salem opportunity, right next door to the newly renovated Roth and McGilchri...

12 . Is direct mail marketing effective than email marketing?

Answer :

Yes buddy, the direct mail marketing is more effective than email marketing. The direct mail marketing inclusive of colored flat mailed post is much more effective than email marketing. May be for a few marketeers, the direct marketing might be a dead one. But, it is making a great comeback with new and advanced marketing strategy. The colored envelopes are much more effective than sending emails to your customers.

13 . How Email marketing serve as one of the most effective marketing tool for marketers?

Answer :

First and foremost, for your email marketing campaign to be super effective, every email address in your list must be opt-in. Meaning, they must have given you permission to email them. Your list should also be very up to date. List that are older than 3 years or more should be updated. This is the biggest misconception of every email marketer out there whom are confused as to why their marketing campaign doesn't work or why they're being reported as spam or why they're ban from their ESP. 

Secondly, email marketing is probably the most effective marketing method still.. for every dollar spent, you're yielding an ROI of over 200%. Why so high? It's rather simple; email is still a personal way of communicating. It's almost like a phone call. If somebody calls me out of the blue and I can't remember giving my number to them or they're a telemarketer, the possibility of me listening to you or having any interest at all to what you're saying is almost at 0%. But obviously, if I do remember you and that I had given you my number to call me, I am more than willing to talk to you over the phone and with open arms. Email marketing and spam works the same way. 

Third, show some respect. Don't send me through unnecessary loops to get me off your list if I so choose. The harder you try to make it harder for me, the better the chances are that your email will be reported as spam. It's easier to just click the "Report as Spam" button than to try and find the "remove" or "unsubscribe" button.

14 . Do you think email marketing strategy will work for Indian market..? if yes, then please give some reasons.?

Answer :

As of December 31, 2009, Internet World Stats reported ~81 million internet users in India. It is safe to assume that this number has grown and will continue to do so. While that's not anywhere close to a majority of India's population, it's still a lot of people out there for you to talk to via email. 

How well email marketing will work for you also depends on the nature of your business. If you're a physical storefront in a rural area with less internet access, it may be more difficult to use email marketing to drum up business. On the other hand, if you are selling easily shippable products and/or digital products, like e-books, newsletters, or the like, you don't even have to restrict yourself to India. 

The nice thing about an email marketing campaign is its low cost compared to postal mail, radio, or television promotions, so it is a good fit for many businesses around the world, and I'm sure that email campaigns are in use in India as well. 

15 . What is email marketing ?

Answer :

 Email marketing is directly marketing a commercial message to a group of people using email. In its broadest sense, every email sent to a potential or current customer could be considered email marketing. It usually involves using email to send ads, request business, or solicit sales or donations, and is meant to build loyalty, trust, or brand awareness. Email marketing can be done to either cold lists or current customer database. Broadly, the term is usually used to refer to: 

Sending email messages with the purpose of enhancing the relationship of a merchant with its current or previous customers, to encourage customer loyalty and repeat business, 

Sending email messages with the purpose of acquiring new customers or convincing current customers to purchase something immediately, 

Adding advertisements to email messages sent by other companies to their customers.