      1: <?php
      2:
      3: class Mailchimp_Campaigns {
      4:     public function __construct(Mailchimp $master) {
      5:         $this->master = $master;
      6:     }
      7:
      8:     /**
      9:      * Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content
     10:      * @param string $cid
     11:      * @param associative_array $options
     12:      *     - view string optional one of "archive" (default), "preview" (like our popup-preview) or "raw"
     13:      *     - email associative_array optional if provided, view is "archive" or "preview", the campaign's list still exists, and the requested record is subscribed to the list. the returned content will be populated with member data populated. a struct with one of the following keys - failing to provide anything will produce an error relating to the email address. Providing multiples and will use the first we see in this same order.
     14:      *         - email string an email address
     15:      *         - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
     16:      *         - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
     17:      * @return associative_array containing all content for the campaign
     18:      *     - html string The HTML content used for the campaign with merge tags intact
     19:      *     - text string The Text content used for the campaign with merge tags intact
     20:      */
     21:     public function content($cid, $options=array()) {
     22:         $_params = array("cid" => $cid, "options" => $options);
     23:         return $this->master->call('campaigns/content', $_params);
     24:     }
     25:
     26:     /**
     27:      * Create a new draft campaign to send. You <strong>can not</strong> have more than 32,000 campaigns in your account.
     28:      * @param string $type
     29:      * @param associative_array $options
     30:      *     - list_id string the list to send this campaign to- get lists using lists/list()
     31:      *     - subject string the subject line for your campaign message
     32:      *     - from_email string the From: email address for your campaign message
     33:      *     - from_name string the From: name for your campaign message (not an email address)
     34:      *     - to_name string the To: name recipients will see (not email address)
     35:      *     - template_id int optional - use this user-created template to generate the HTML content of the campaign (takes precendence over other template options)
     36:      *     - gallery_template_id int optional - use a template from the public gallery to generate the HTML content of the campaign (takes precendence over base template options)
     37:      *     - base_template_id int optional - use this a base/start-from-scratch template to generate the HTML content of the campaign
     38:      *     - folder_id int optional - automatically file the new campaign in the folder_id passed. Get using folders/list() - note that Campaigns and Autoresponders have separate folder setups
     39:      *     - tracking associative_array optional - set which recipient actions will be tracked. Click tracking can not be disabled for Free accounts.
     40:      *         - opens bool whether to track opens, defaults to true
     41:      *         - html_clicks bool whether to track clicks in HTML content, defaults to true
     42:      *         - text_clicks bool whether to track clicks in Text content, defaults to false
     43:      *     - title string optional - an internal name to use for this campaign.  By default, the campaign subject will be used.
     44:      *     - authenticate boolean optional - set to true to enable SenderID, DomainKeys, and DKIM authentication, defaults to false.
     45:      *     - analytics associative_array optional - one or more of these keys set to the tag to use - that can be any custom text (up to 50 bytes)
     46:      *         - google string for Google Analytics  tracking
     47:      *         - clicktale string for ClickTale  tracking
     48:      *         - gooal string for Goo.al tracking
     49:      *     - auto_footer boolean optional Whether or not we should auto-generate the footer for your content. Mostly useful for content from URLs or Imports
     50:      *     - inline_css boolean optional Whether or not css should be automatically inlined when this campaign is sent, defaults to false.
     51:      *     - generate_text boolean optional Whether of not to auto-generate your Text content from the HTML content. Note that this will be ignored if the Text part of the content passed is not empty, defaults to false.
     52:      *     - auto_tweet boolean optional If set, this campaign will be auto-tweeted when it is sent - defaults to false. Note that if a Twitter account isn't linked, this will be silently ignored.
     53:      *     - auto_fb_post array optional If set, this campaign will be auto-posted to the page_ids contained in the array. If a Facebook account isn't linked or the account does not have permission to post to the page_ids requested, those failures will be silently ignored.
     54:      *     - fb_comments boolean optional If true, the Facebook comments (and thus the <a href="http://kb.mailchimp.com/article/i-dont-want-an-archiave-of-my-campaign-can-i-turn-it-off/" target="_blank">archive bar</a> will be displayed. If false, Facebook comments will not be enabled (does not imply no archive bar, see previous link). Defaults to "true".
     55:      *     - timewarp boolean optional If set, this campaign must be scheduled 24 hours in advance of sending - default to false. Only valid for "regular" campaigns and "absplit" campaigns that split on schedule_time.
     56:      *     - ecomm360 boolean optional If set, our <a href="http://www.mailchimp.com/blog/ecommerce-tracking-plugin/" target="_blank">Ecommerce360 tracking</a> will be enabled for links in the campaign
     57:      *     - crm_tracking array optional If set, an array of structs to enable CRM tracking for:
     58:      *         - salesforce associative_array optional Enable SalesForce push back
     59:      *             - campaign bool optional - if true, create a Campaign object and update it with aggregate stats
     60:      *             - notes bool optional - if true, attempt to update Contact notes based on email address
     61:      *         - highrise associative_array optional Enable Highrise push back
     62:      *             - campaign bool optional - if true, create a Kase object and update it with aggregate stats
     63:      *             - notes bool optional - if true, attempt to update Contact notes based on email address
     64:      *         - capsule associative_array optional Enable Capsule push back (only notes are supported)
     65:      *             - notes bool optional - if true, attempt to update Contact notes based on email address
     66:      * @param associative_array $content
     67:      *     - html string for raw/pasted HTML content
     68:      *     - sections associative_array when using a template instead of raw HTML, each key should be the unique mc:edit area name from the template.
     69:      *     - text string for the plain-text version
     70:      *     - url string to have us pull in content from a URL. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
     71:      *     - archive string to send a Base64 encoded archive file for us to import all media from. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
     72:      *     - archive_type string optional - only necessary for the "archive" option. Supported formats are: zip, tar.gz, tar.bz2, tar, tgz, tbz . If not included, we will default to zip
     73:      * @param associative_array $segment_opts
     74:      * @param associative_array $type_opts
     75:      *     - rss associative_array For RSS Campaigns this, struct should contain:
     76:      *         - url string the URL to pull RSS content from - it will be verified and must exist
     77:      *         - schedule string optional one of "daily", "weekly", "monthly" - defaults to "daily"
     78:      *         - schedule_hour string optional an hour between 0 and 24 - default to 4 (4am <em>local time</em>) - applies to all schedule types
     79:      *         - schedule_weekday string optional for "weekly" only, a number specifying the day of the week to send: 0 (Sunday) - 6 (Saturday) - defaults to 1 (Monday)
     80:      *         - schedule_monthday string optional for "monthly" only, a number specifying the day of the month to send (1 - 28) or "last" for the last day of a given month. Defaults to the 1st day of the month
     81:      *         - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on
     82:      *             - 1 bool optional Monday, defaults to true
     83:      *             - 2 bool optional Tuesday, defaults to true
     84:      *             - 3 bool optional Wednesday, defaults to true
     85:      *             - 4 bool optional Thursday, defaults to true
     86:      *             - 5 bool optional Friday, defaults to true
     87:      *             - 6 bool optional Saturday, defaults to true
     88:      *             - 7 bool optional Sunday, defaults to true
     89:      *     - absplit associative_array For A/B Split campaigns, this struct should contain:
     90:      *         - split_test string The values to segment based on. Currently, one of: "subject", "from_name", "schedule". NOTE, for "schedule", you will need to call campaigns/schedule() separately!
     91:      *         - pick_winner string How the winner will be picked, one of: "opens" (by the open_rate), "clicks" (by the click rate), "manual" (you pick manually)
     92:      *         - wait_units int optional the default time unit to wait before auto-selecting a winner - use "3600" for hours, "86400" for days. Defaults to 86400.
     93:      *         - wait_time int optional the number of units to wait before auto-selecting a winner - defaults to 1, so if not set, a winner will be selected after 1 Day.
     94:      *         - split_size int optional this is a percentage of what size the Campaign's List plus any segmentation options results in. "schedule" type forces 50%, all others default to 10%
     95:      *         - from_name_a string optional sort of, required when split_test is "from_name"
     96:      *         - from_name_b string optional sort of, required when split_test is "from_name"
     97:      *         - from_email_a string optional sort of, required when split_test is "from_name"
     98:      *         - from_email_b string optional sort of, required when split_test is "from_name"
     99:      *         - subject_a string optional sort of, required when split_test is "subject"
    100:      *         - subject_b string optional sort of, required when split_test is "subject"
    101:      *     - auto associative_array For AutoResponder campaigns, this struct should contain:
    102:      *         - offset-units string one of "hourly", "day", "week", "month", "year" - required
    103:      *         - offset-time string optional, sort of - the number of units must be a number greater than 0 for signup based autoresponders, ignored for "hourly"
    104:      *         - offset-dir string either "before" or "after", ignored for "hourly"
    105:      *         - event string optional "signup" (default) to base this members added to a list, "date", "annual", or "birthday" to base this on merge field in the list, "campaignOpen" or "campaignClicka" to base this on any activity for a campaign, "campaignClicko" to base this on clicks on a specific URL in a campaign, "mergeChanged" to base this on a specific merge field being changed to a specific value
    106:      *         - event-datemerge string optional sort of, this is required if the event is "date", "annual", "birthday", or "mergeChanged"
    107:      *         - campaign_id string optional sort of, required for "campaignOpen", "campaignClicka", or "campaignClicko"
    108:      *         - campaign_url string optional sort of, required for "campaignClicko"
    109:      *         - schedule_hour int The hour of the day - 24 hour format in GMT - the autoresponder should be triggered, ignored for "hourly"
    110:      *         - use_import_time boolean whether or not imported subscribers (ie, <em>any</em> non-double optin subscribers) will receive
    111:      *         - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on<
    112:      *             - 1 bool optional Monday, defaults to true
    113:      *             - 2 bool optional Tuesday, defaults to true
    114:      *             - 3 bool optional Wednesday, defaults to true
    115:      *             - 4 bool optional Thursday, defaults to true
    116:      *             - 5 bool optional Friday, defaults to true
    117:      *             - 6 bool optional Saturday, defaults to true
    118:      *             - 7 bool optional Sunday, defaults to true
    119:      * @return associative_array the new campaign's details - will return same data as single campaign from campaigns/list()
    120:      */
    121:     public function create($type, $options, $content, $segment_opts=null, $type_opts=null) {
    122:         $_params = array("type" => $type, "options" => $options, "content" => $content, "segment_opts" => $segment_opts, "type_opts" => $type_opts);
    123:         return $this->master->call('campaigns/create', $_params);
    124:     }
    125:
    126:     /**
    127:      * Delete a campaign. Seriously, "poof, gone!" - be careful! Seriously, no one can undelete these.
    128:      * @param string $cid
    129:      * @return associative_array with a single entry:
    130:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    131:      */
    132:     public function delete($cid) {
    133:         $_params = array("cid" => $cid);
    134:         return $this->master->call('campaigns/delete', $_params);
    135:     }
    136:
    137:     /**
    138:      * Get the list of campaigns and their details matching the specified filters
    139:      * @param associative_array $filters
    140:      *     - campaign_id string optional - return the campaign using a know campaign_id.  Accepts multiples separated by commas when not using exact matching.
    141:      *     - parent_id string optional - return the child campaigns using a known parent campaign_id.  Accepts multiples separated by commas when not using exact matching.
    142:      *     - list_id string optional - the list to send this campaign to - get lists using lists/list(). Accepts multiples separated by commas when not using exact matching.
    143:      *     - folder_id int optional - only show campaigns from this folder id - get folders using folders/list(). Accepts multiples separated by commas when not using exact matching.
    144:      *     - template_id int optional - only show campaigns using this template id - get templates using templates/list(). Accepts multiples separated by commas when not using exact matching.
    145:      *     - status string optional - return campaigns of a specific status - one of "sent", "save", "paused", "schedule", "sending". Accepts multiples separated by commas when not using exact matching.
    146:      *     - type string optional - return campaigns of a specific type - one of "regular", "plaintext", "absplit", "rss", "auto". Accepts multiples separated by commas when not using exact matching.
    147:      *     - from_name string optional - only show campaigns that have this "From Name"
    148:      *     - from_email string optional - only show campaigns that have this "Reply-to Email"
    149:      *     - title string optional - only show campaigns that have this title
    150:      *     - subject string optional - only show campaigns that have this subject
    151:      *     - sendtime_start string optional - only show campaigns that have been sent since this date/time (in GMT) -  - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
    152:      *     - sendtime_end string optional - only show campaigns that have been sent before this date/time (in GMT) -  - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
    153:      *     - uses_segment boolean - whether to return just campaigns with or without segments
    154:      *     - exact boolean optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true. Using this disables the use of any filters that accept multiples.
    155:      * @param int $start
    156:      * @param int $limit
    157:      * @param string $sort_field
    158:      * @param string $sort_dir
    159:      * @return associative_array containing a count of all matching campaigns, the specific ones for the current page, and any errors from the filters provided
    160:      *     - total int the total number of campaigns matching the filters passed in
    161:      *     - data array structs for each campaign being returned
    162:      *         - id string Campaign Id (used for all other campaign functions)
    163:      *         - web_id int The Campaign id used in our web app, allows you to create a link directly to it
    164:      *         - list_id string The List used for this campaign
    165:      *         - folder_id int The Folder this campaign is in
    166:      *         - template_id int The Template this campaign uses
    167:      *         - content_type string How the campaign's content is put together - one of 'template', 'html', 'url'
    168:      *         - title string Title of the campaign
    169:      *         - type string The type of campaign this is (regular,plaintext,absplit,rss,inspection,auto)
    170:      *         - create_time string Creation time for the campaign
    171:      *         - send_time string Send time for the campaign - also the scheduled time for scheduled campaigns.
    172:      *         - emails_sent int Number of emails email was sent to
    173:      *         - status string Status of the given campaign (save,paused,schedule,sending,sent)
    174:      *         - from_name string From name of the given campaign
    175:      *         - from_email string Reply-to email of the given campaign
    176:      *         - subject string Subject of the given campaign
    177:      *         - to_name string Custom "To:" email string using merge variables
    178:      *         - archive_url string Archive link for the given campaign
    179:      *         - inline_css boolean Whether or not the campaign content's css was auto-inlined
    180:      *         - analytics string Either "google" if enabled or "N" if disabled
    181:      *         - analytics_tag string The name/tag the campaign's links were tagged with if analytics were enabled.
    182:      *         - authenticate boolean Whether or not the campaign was authenticated
    183:      *         - ecomm360 boolean Whether or not ecomm360 tracking was appended to links
    184:      *         - auto_tweet boolean Whether or not the campaign was auto tweeted after sending
    185:      *         - auto_fb_post string A comma delimited list of Facebook Profile/Page Ids the campaign was posted to after sending. If not used, blank.
    186:      *         - auto_footer boolean Whether or not the auto_footer was manually turned on
    187:      *         - timewarp boolean Whether or not the campaign used Timewarp
    188:      *         - timewarp_schedule string The time, in GMT, that the Timewarp campaign is being sent. For A/B Split campaigns, this is blank and is instead in their schedule_a and schedule_b in the type_opts array
    189:      *         - parent_id string the unique id of the parent campaign (currently only valid for rss children)
    190:      *         - tests_sent string tests sent
    191:      *         - tests_remain string test sends remaining
    192:      *         - tracking associative_array the various tracking options used
    193:      *             - html_clicks boolean whether or not tracking for html clicks was enabled.
    194:      *             - text_clicks boolean whether or not tracking for text clicks was enabled.
    195:      *             - opens boolean whether or not opens tracking was enabled.
    196:      *         - segment_text string a string marked-up with HTML explaining the segment used for the campaign in plain English
    197:      *         - segment_opts array the segment used for the campaign - can be passed to campaigns/segment-test or campaigns/create()
    198:      *         - saved_segment associative_array if a saved segment was used (match+conditions returned above):
    199:      *             - id associative_array the saved segment id
    200:      *             - type associative_array the saved segment type
    201:      *             - name associative_array the saved segment name
    202:      *         - type_opts associative_array the type-specific options for the campaign - can be passed to campaigns/create()
    203:      *         - comments_total int total number of comments left on this campaign
    204:      *         - comments_unread int total number of unread comments for this campaign based on the login the apikey belongs to
    205:      *         - summary associative_array if available, the basic aggregate stats returned by reports/summary
    206:      *     - errors array structs of any errors found while loading lists - usually just from providing invalid list ids
    207:      *         - filter string the filter that caused the failure
    208:      *         - value string the filter value that caused the failure
    209:      *         - code int the error code
    210:      *         - error int the error message
    211:      */
    212:     public function getList($filters=array(), $start=0, $limit=25, $sort_field='create_time', $sort_dir='DESC') {
    213:         $_params = array("filters" => $filters, "start" => $start, "limit" => $limit, "sort_field" => $sort_field, "sort_dir" => $sort_dir);
    214:         return $this->master->call('campaigns/list', $_params);
    215:     }
    216:
    217:     /**
    218:      * Pause an AutoResponder or RSS campaign from sending
    219:      * @param string $cid
    220:      * @return associative_array with a single entry:
    221:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    222:      */
    223:     public function pause($cid) {
    224:         $_params = array("cid" => $cid);
    225:         return $this->master->call('campaigns/pause', $_params);
    226:     }
    227:
    228:     /**
    229:      * Returns information on whether a campaign is ready to send and possible issues we may have detected with it - very similar to the confirmation step in the app.
    230:      * @param string $cid
    231:      * @return associative_array containing:
    232:      *     - is_ready bool whether or not you're going to be able to send this campaign
    233:      *     - items array an array of structs explaining basically what the app's confirmation step would
    234:      *         - type string the item type - generally success, warning, or error
    235:      *         - heading string the item's heading in the app
    236:      *         - details string the item's details from the app, sans any html tags/links
    237:      */
    238:     public function ready($cid) {
    239:         $_params = array("cid" => $cid);
    240:         return $this->master->call('campaigns/ready', $_params);
    241:     }
    242:
    243:     /**
    244:      * Replicate a campaign.
    245:      * @param string $cid
    246:      * @return associative_array the matching campaign's details - will return same data as single campaign from campaigns/list()
    247:      */
    248:     public function replicate($cid) {
    249:         $_params = array("cid" => $cid);
    250:         return $this->master->call('campaigns/replicate', $_params);
    251:     }
    252:
    253:     /**
    254:      * Resume sending an AutoResponder or RSS campaign
    255:      * @param string $cid
    256:      * @return associative_array with a single entry:
    257:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    258:      */
    259:     public function resume($cid) {
    260:         $_params = array("cid" => $cid);
    261:         return $this->master->call('campaigns/resume', $_params);
    262:     }
    263:
    264:     /**
    265:      * Schedule a campaign to be sent in the future
    266:      * @param string $cid
    267:      * @param string $schedule_time
    268:      * @param string $schedule_time_b
    269:      * @return associative_array with a single entry:
    270:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    271:      */
    272:     public function schedule($cid, $schedule_time, $schedule_time_b=null) {
    273:         $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "schedule_time_b" => $schedule_time_b);
    274:         return $this->master->call('campaigns/schedule', $_params);
    275:     }
    276:
    277:     /**
    278:      * Schedule a campaign to be sent in batches sometime in the future. Only valid for "regular" campaigns
    279:      * @param string $cid
    280:      * @param string $schedule_time
    281:      * @param int $num_batches
    282:      * @param int $stagger_mins
    283:      * @return associative_array with a single entry:
    284:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    285:      */
    286:     public function scheduleBatch($cid, $schedule_time, $num_batches=2, $stagger_mins=5) {
    287:         $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "num_batches" => $num_batches, "stagger_mins" => $stagger_mins);
    288:         return $this->master->call('campaigns/schedule-batch', $_params);
    289:     }
    290:
    291:     /**
    292:      * Allows one to test their segmentation rules before creating a campaign using them
    293:      * @param string $list_id
    294:      * @param associative_array $options
    295:      *     - saved_segment_id string a saved segment id from lists/segments() - this will take precendence, otherwise the match+conditions are required.
    296:      *     - match string controls whether to use AND or OR when applying your options - expects "<strong>any</strong>" (for OR) or "<strong>all</strong>" (for AND)
    297:      *     - conditions array of up to 5 structs for different criteria to apply while segmenting. Each criteria row must contain 3 keys - "<strong>field</strong>", "<strong>op</strong>", and "<strong>value</strong>" - and possibly a fourth, "<strong>extra</strong>", based on these definitions:
    298:      * @return associative_array with a single entry:
    299:      *     - total int The total number of subscribers matching your segmentation options
    300:      */
    301:     public function segmentTest($list_id, $options) {
    302:         $_params = array("list_id" => $list_id, "options" => $options);
    303:         return $this->master->call('campaigns/segment-test', $_params);
    304:     }
    305:
    306:     /**
    307:      * Send a given campaign immediately. For RSS campaigns, this will "start" them.
    308:      * @param string $cid
    309:      * @return associative_array with a single entry:
    310:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    311:      */
    312:     public function send($cid) {
    313:         $_params = array("cid" => $cid);
    314:         return $this->master->call('campaigns/send', $_params);
    315:     }
    316:
    317:     /**
    318:      * Send a test of this campaign to the provided email addresses
    319:      * @param string $cid
    320:      * @param array $test_emails
    321:      * @param string $send_type
    322:      * @return associative_array with a single entry:
    323:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    324:      */
    325:     public function sendTest($cid, $test_emails=array(), $send_type='html') {
    326:         $_params = array("cid" => $cid, "test_emails" => $test_emails, "send_type" => $send_type);
    327:         return $this->master->call('campaigns/send-test', $_params);
    328:     }
    329:
    330:     /**
    331:      * Get the HTML template content sections for a campaign. Note that this <strong>will</strong> return very jagged, non-standard results based on the template
    332: a campaign is using. You only want to use this if you want to allow editing template sections in your application.
    333:      * @param string $cid
    334:      * @return associative_array content containing all content section for the campaign - section name are dependent upon the template used and thus can't be documented
    335:      */
    336:     public function templateContent($cid) {
    337:         $_params = array("cid" => $cid);
    338:         return $this->master->call('campaigns/template-content', $_params);
    339:     }
    340:
    341:     /**
    342:      * Unschedule a campaign that is scheduled to be sent in the future
    343:      * @param string $cid
    344:      * @return associative_array with a single entry:
    345:      *     - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
    346:      */
    347:     public function unschedule($cid) {
    348:         $_params = array("cid" => $cid);
    349:         return $this->master->call('campaigns/unschedule', $_params);
    350:     }
    351:
    352:     /**
    353:      * Update just about any setting besides type for a campaign that has <em>not</em> been sent. See campaigns/create() for details.
    354: Caveats:<br/><ul class='bullets'>
    355: <li>If you set a new list_id, all segmentation options will be deleted and must be re-added.</li>
    356: <li>If you set template_id, you need to follow that up by setting it's 'content'</li>
    357: <li>If you set segment_opts, you should have tested your options against campaigns/segment-test().</li>
    358: <li>To clear/unset segment_opts, pass an empty string or array as the value. Various wrappers may require one or the other.</li>
    359: </ul>
    360:      * @param string $cid
    361:      * @param string $name
    362:      * @param array $value
    363:      * @return associative_array updated campaign details and any errors
    364:      *     - data associative_array the update campaign details - will return same data as single campaign from campaigns/list()
    365:      *     - errors array for "options" only - structs containing:
    366:      *         - code int the error code
    367:      *         - message string the full error message
    368:      *         - name string the parameter name that failed
    369:      */
    370:     public function update($cid, $name, $value) {
    371:         $_params = array("cid" => $cid, "name" => $name, "value" => $value);
    372:         return $this->master->call('campaigns/update', $_params);
    373:     }
    374:
    375: }
    376:
    377:
    378: