/** * Get zone stats * * @param array Query parameters * @param int Tree level * @param string Expand GET parameter, used only when called from other get methods * @return Entities array */ function getZones($aParams, $level, $expand) { $aParams['exclude'] = array('ad_id'); $aParams['include'] = array('publisher_id'); $this->prepareData($aParams); $period_preset = MAX_getStoredValue('period_preset', 'today'); $aZones = $this->mergeData($aParams, 'zone_id'); MAX_sortArray($aZones, $this->listOrderField == 'id' ? 'zone_id' : $this->listOrderField, $this->listOrderDirection == 'up'); $aEntitiesData = array(); foreach ($aZones as $zoneId => $zone) { $zone['active'] = $this->_hasActiveStats($zone); if ($this->startLevel > $level || !$this->hideInactive || $zone['active']) { $this->_summarizeStats($zone); $zone['prefix'] = 'z'; $zone['id'] = $zoneId; $zone['linkparams'] = "affiliateid={$zone['publisher_id']}&zoneid={$zoneId}&"; if (is_array($aParams) && count($aParams) > 0) { foreach ($aParams as $key => $value) { if ($key != "include" && $key != "exclude") { $zone['linkparams'] .= $key . "=" . $value . "&"; } } } else { $zone['linkparams'] .= "&"; } $zone['linkparams'] .= "period_preset={$period_preset}&period_start=" . MAX_getStoredValue('period_start', date('Y-m-d')) . "&period_end=" . MAX_getStoredValue('period_end', date('Y-m-d')); $zone['expanded'] = MAX_isExpanded($zoneId, $expand, $this->aNodes, $zone['prefix']); $zone['icon'] = MAX_getEntityIcon('zone', $zone['active'], $zone['type']); if ($zone['type'] == MAX_ZoneMarketMigrated) { $zone['html-append'] = $this->getHtmlHelpLink('help-market-zone-migrated-from-pre-283'); $zone['name'] = $GLOBALS['strMarketZoneBeforeOpenX2.8.4']; } $aEntitiesData[] = $zone; } elseif ($this->startLevel == $level) { $this->hiddenEntities++; } } return $aEntitiesData; }
/** * A method to prepare targeting statistcs data for display by the * {@link OA_Admin_Statistics_Common::output()} method. * * @param array $aParams An array containing the "placement_id". * @param string $link Optional link file name for the LHC day breakdown link. */ function prepare($aParams, $link = '') { // Set the span requirements $this->oHistory->getSpan($this, $aParams, 'getTargetingSpan', 'getTargetingSpanParams'); // Set the current breakdown information, and get the required DAL method $method = $this->oHistory->setBreakdownInfo($this, 'targeting'); $oStartDate = new Date($this->aDates['day_begin']); $oEndDate = new Date($this->aDates['day_end']); $oDal = new OA_Dal_Statistics_Targeting(); $aStats = $oDal->{$method}($aParams['placement_id'], 'placement', $oStartDate, $oEndDate); if (count($aStats) == 0) { // There are no stats! $this->noStatsAvailable = true; $this->aStatsData = array(); return; } // Pad out any missing items in the stats array, // and ensure that links are correctly set $aDates = $this->oHistory->getDatesArray($this->aDates, $this->statsBreakdown, $oStartDate); $this->oHistory->fillGapsAndLink($aStats, $aDates, $this, $link); // Ensure the stats array for the range is filled foreach (array_keys($aStats) as $k) { $aStats[$k] += $this->aEmptyRow; } if (!in_array($this->listOrderField, array_merge(array($this->statsBreakdown), array_keys($this->aColumns)))) { $this->listOrderField = $this->statsBreakdown; $this->listOrderDirection = $this->statsBreakdown == 'hour' || $this->statsBreakdown == 'dow' ? 'up' : 'down'; } // If required, re-format the data in the weekly breakdown format if ($this->statsBreakdown == 'week') { $this->oHistory->prepareWeekBreakdown($aStats, $this); } // Summarise the values into a the totals array & format $this->_summariseTotalsAndFormat($aStats, true); MAX_sortArray($aStats, $this->listOrderField, $this->listOrderDirection == 'up'); // Format the rows appropriately for output if ($this->statsBreakdown == 'week') { $this->oHistory->formatWeekRows($aStats, $this); $this->oHistory->formatWeekRowsTotal($this->aTotal, $this); } else { $this->oHistory->formatRows($aStats, $this); } $this->aStatsData = $aStats; }
/** * Fetch the history stats using the specified parameters * * @param array $aParams Query parameters * @param string $link Optional link for the leftmost column content */ function getHistory($aParams, $link = '') { $oNow = new Date(); $aParams['tz'] = $oNow->tz->getID(); $method = $this->oHistory->setBreakdownInfo($this); // Add plugin aParams $pluginParams = array(); foreach ($this->aPlugins as $oPlugin) { $oPlugin->addQueryParams($pluginParams); } $aStats = Admin_DA::fromCache($method, $aParams + $this->aDates + $pluginParams); // Merge plugin additional $oPlugin foreach ($this->aPlugins as $oPlugin) { $oPlugin->mergeData($aStats, $method, $aParams + $this->aDates, $this->aEmptyRow); } if (count($aStats) == 0) { $this->noStatsAvailable = true; return $aStats; } // Fill unused plugins columns foreach (array_keys($aStats) as $k) { $aStats[$k] += $this->aEmptyRow; } // Set some of the variables that used to be set by getSpan if (!empty($aStats)) { $dates = array_keys($aStats); // assumes first row has earliest date $firstDate = new Date($dates[0]); // Convert to current TZ $firstDate->setTZbyID('UTC'); $firstDate->convertTZ($oNow->tz); $firstDate->setHour(0); $firstDate->setMinute(0); $firstDate->setSecond(0); if (empty($this->aDates)) { $this->aDates['day_begin'] = $firstDate->format('%Y-%m-%d'); $this->aDates['day_end'] = $oNow->format('%Y-%m-%d'); } $this->oStartDate = new Date($firstDate); } $aDates = $this->oHistory->getDatesArray($this->aDates, $this->statsBreakdown, $this->oStartDate); $this->oHistory->fillGapsAndLink($aStats, $aDates, $this, $link); if (!in_array($this->listOrderField, array_merge(array($this->statsBreakdown), array_keys($this->aColumns)))) { $this->listOrderField = $this->statsBreakdown; $this->listOrderDirection = $this->statsBreakdown == 'hour' || $this->statsBreakdown == 'dow' ? 'up' : 'down'; } // If required, re-format the data in the weekly breakdown format if ($this->statsBreakdown == 'week') { $this->oHistory->prepareWeekBreakdown($aStats, $this); } MAX_sortArray($aStats, $this->listOrderField, $this->listOrderDirection == 'up'); // Summarise the values into a the totals array, & format $this->_summariseTotalsAndFormat($aStats, true); return $aStats; }
/** * Add "blanks" stats to an entity array * * @param array Query parameters * @param array Entities array */ function addBlanks($aParams, &$aEntitiesData) { $aParams['exclude'] = array('zone_id'); $aParams['ad_id'] = 0; // Get plugin aParams $pluginParams = array(); foreach ($this->aPlugins as $oPlugin) { $oPlugin->addQueryParams($pluginParams); } $aBlanks = Admin_DA::fromCache('getEntitiesStats', $aParams + $this->aDates, 1); // Merge plugin additional data foreach ($this->aPlugins as $oPlugin) { $oPlugin->mergeData($aBlanks, 'getEntitiesStats', $aParams + $this->aDates, $this->aEmptyRow); } if (count($aBlanks)) { $zone = current($aBlanks) + $this->aEmptyRow; $zone['active'] = $this->_hasActiveStats($zone); if ($zone['active']) { $this->_summarizeStats($zone); $zone['name'] = 'Blank impressions'; $zone['prefix'] = 'x'; $zone['id'] = '-'; $zone['icon'] = OX::assetPath() . '/images/icon-banner-disabled.png'; $zone['htmlclass'] = 'last'; if ($this->listOrderField != 'name' && $this->listOrderField != 'id') { $aEntitiesData[] = $zone; MAX_sortArray($aEntitiesData, $this->listOrderField, $this->listOrderDirection == 'up'); } elseif ($this->listOrderDirection == 'up') { array_push($aEntitiesData, $zone); } else { array_unshift($aEntitiesData, $zone); } } } }
$column1 = _getHtmlHeaderColumn($GLOBALS['strDateTime'], 'date_time', $pageName, $entityIds, $listorder, $orderdirection); $column2 = _getHtmlHeaderColumn($GLOBALS['strStatus'], 'connection_status', $pageName, $entityIds, $listorder, $orderdirection); $column3 = _getHtmlHeaderColumn($GLOBALS['strTrackerID'], 'tracker_id', $pageName, $entityIds, $listorder, $orderdirection); $column4 = _getHtmlHeaderColumn($GLOBALS['strTrackerName'], 'trackername', $pageName, $entityIds, $listorder, $orderdirection); $column5 = _getHtmlHeaderColumn($GLOBALS['strCampaignID'], 'campaignid', $pageName, $entityIds, $listorder, $orderdirection); $column6 = _getHtmlHeaderColumn($GLOBALS['strCampaignName'], 'campaignname', $pageName, $entityIds, $listorder, $orderdirection); echo "\n <tr height='1'>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='150' height='1' border='0' alt='' title=''></td>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='80' height='1' border='0' alt='' title=''></td>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='60' height='1' border='0' alt='' title=''></td>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='80' height='1' border='0' alt='' title=''></td>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='60' height='1' border='0' alt='' title=''></td>\n <td><img src='" . OX::assetPath() . "/images/spacer.gif' width='80' height='1' border='0' alt='' title=''></td>\n </tr>\n <tr height='25'>\n <td width='150' style='padding-left: 16px'> {$column1}</td>\n <td align='center' style='padding: 0 4px'>{$column2}</td>\n <td align='{$phpAds_TextAlignLeft}' style='padding: 0 4px'>{$column3}</td>\n <td align='{$phpAds_TextAlignLeft}' style='padding: 0 4px'>{$column4}</td>\n <td align='{$phpAds_TextAlignLeft}' style='padding: 0 4px'>{$column5}</td>\n <td align='{$phpAds_TextAlignLeft}' style='padding: 0 4px'>{$column6}</td>\n </tr>\n <tr height='1'><td colspan='6' bgcolor='#888888'><img src='" . OX::assetPath() . "/images/break.gif' height='1' width='100%'></td></tr>"; // Variable to determine if the row should be grey or white... $i = 0; $statusesColors = array(MAX_CONNECTION_STATUS_IGNORE => 'grey', MAX_CONNECTION_STATUS_PENDING => 'darkblue', MAX_CONNECTION_STATUS_ONHOLD => 'blue', MAX_CONNECTION_STATUS_APPROVED => 'green', MAX_CONNECTION_STATUS_DISAPPROVED => 'red', MAX_CONNECTION_STATUS_DUPLICATE => 'grey'); $totalRequests = 0; $totalViews = 0; $totalClicks = 0; $totalConversions = 0; // Loop through advertisers MAX_sortArray($aConversions, $listorder == 'id' ? 'date_time' : $listorder, $orderdirection == 'up'); foreach ($aConversions as $conversionId => $conversion) { $conversionExpanded = MAX_isExpanded($conversionId, $expand, $aNodes, 'a'); $bgcolor = $i++ % 2 == 0 ? " bgcolor='#F6F6F6'" : ''; $connectionStatus = $GLOBALS['_MAX']['STATUSES'][$conversion['connection_status']]; $translatedStatus = $GLOBALS[$connectionStatus]; echo "\n <tr height='25'{$bgcolor}>\n <td>"; if ($conversionExpanded) { echo " <a href='{$pageName}?collapse=a{$conversionId}&{$addUrl}'><img src='" . OX::assetPath() . "/images/triangle-d.gif' align='absmiddle' border='0'></a> "; } else { echo " <a href='{$pageName}?expand=a{$conversionId}&{$addUrl}'><img src='" . OX::assetPath() . "/images/{$phpAds_TextDirection}/triangle-l.gif' align='absmiddle' border='0'></a> "; } $aConversionStatuses = array(MAX_CONNECTION_STATUS_IGNORE, MAX_CONNECTION_STATUS_PENDING, MAX_CONNECTION_STATUS_ONHOLD, MAX_CONNECTION_STATUS_APPROVED, MAX_CONNECTION_STATUS_DISAPPROVED, MAX_CONNECTION_STATUS_DUPLICATE); echo "{$conversion['date_time']}</td>"; if ($editStatuses) { // Only managers can edit statuses. No constraint to the type of changes since OX-4138.
function MAX_displayZoneStats($aParams, $pageName, $anonymous, $aNodes, $expand, $listorder, $orderdirection, $hideinactive, $showPublisher, $entityIds) { global $phpAds_TextAlignLeft, $phpAds_TextAlignRight, $phpAds_TextDirection; // Get the icons for all levels (publisher/zone) $entity = _getEntityString($entityIds); $publishersHidden = 0; $aZones = Admin_DA::fromCache('getZonesStats', $aParams); if (!empty($aZones)) { echo "\n <br /><br />\n <table border='0' width='100%' cellpadding='0' cellspacing='0'>"; MAX_displayStatsHeader($pageName, $listorder, $orderdirection, $entityIds, $anonymous); // Variable to determine if the row should be grey or white... $i = 0; $totalRequests = 0; $totalViews = 0; $totalClicks = 0; $totalConversions = 0; // Loop through publishers MAX_sortArray($aZones, $listorder == 'id' ? 'zone_id' : $listorder, $orderdirection == 'up'); foreach ($aZones as $zoneId => $zone) { $zoneRequests = phpAds_formatNumber($zone['sum_requests']); $zoneViews = phpAds_formatNumber($zone['sum_views']); $zoneClicks = phpAds_formatNumber($zone['sum_clicks']); $zoneConversions = phpAds_formatNumber($zone['sum_conversions']); $zoneCtr = phpAds_buildRatioPercentage($zone['sum_clicks'], $zone['sum_views']); $zoneSr = phpAds_buildRatioPercentage($zone['sum_conversions'], $zone['sum_clicks']); $zoneActive = true; $zoneIcon = MAX_getEntityIcon('zone', $zoneActive, $zone['type']); if (!$hideinactive || $zoneActive) { $bgcolor = $i++ % 2 == 0 ? " bgcolor='#F6F6F6'" : ''; echo "\n <tr height='25'{$bgcolor}>\n <td> <img src='" . OX::assetPath() . "/images/spacer.gif' height='16' width='16'> \n <img src='{$zoneIcon}' align='absmiddle'> "; if ($anonymous) { echo "\n Hidden zone {$zone['id']}"; } else { echo "\n <a href='stats.php?entity=zone&breakdown=history&affiliateid={$zone['publisher_id']}'>{$zone['name']}</a>"; } echo "\n </td>"; if ($anonymous) { echo "\n <td align='{$phpAds_TextAlignRight}'> </td>"; } else { echo "\n <td align='{$phpAds_TextAlignRight}'>{$zoneId}</td>"; } echo "\n <td align='{$phpAds_TextAlignRight}'>{$zoneRequests}</td>\n <td align='{$phpAds_TextAlignRight}'>{$zoneViews}</td>\n <td align='{$phpAds_TextAlignRight}'>{$zoneClicks}</td>\n <td align='{$phpAds_TextAlignRight}'>{$zoneCtr}</td>\n <td align='{$phpAds_TextAlignRight}'>{$zoneConversions}</td>\n <td align='{$phpAds_TextAlignRight}'>{$zoneSr}</td>\n </tr>\n <tr height='1'><td colspan='8' bgcolor='#888888'><img src='" . OX::assetPath() . "/images/break.gif' height='1' width='100%'></td></tr>"; } else { $publishersHidden++; } $totalRequests += $zone['sum_requests']; $totalViews += $zone['sum_views']; $totalClicks += $zone['sum_clicks']; $totalConversions += $zone['sum_conversions']; } // Total echo "\n <tr height='25'{$bgcolor}>\n <td> <b>{$GLOBALS['strTotal']}</b></td>\n <td> </td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_formatNumber($totalRequests) . "</td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_formatNumber($totalViews) . "</td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_formatNumber($totalClicks) . "</td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_buildCTR($totalViews, $totalClicks) . "</td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_formatNumber($totalConversions) . "</td>\n <td align='{$phpAds_TextAlignRight}'>" . phpAds_buildCTR($totalClicks, $totalConversions) . "</td>\n </tr>\n <tr height='1'>\n <td colspan='8' bgcolor='#888888'><img src='" . OX::assetPath() . "/images/break.gif' height='1' width='100%'></td>\n </tr>"; if (!$anonymous) { echo "\n <tr>\n <td colspan='4' align='{$phpAds_TextAlignLeft}' nowrap>"; if ($hideinactive == true) { echo " <img src='" . OX::assetPath() . "/images/icon-activate.gif' align='absmiddle' border='0'> <a href='{$pageName}?{$entity}hideinactive=0'>{$GLOBALS['strShowAll']}</a> | {$publishersHidden} {$GLOBALS['strInactivePublishersHidden']}"; } else { echo " <img src='" . OX::assetPath() . "/images/icon-hideinactivate.gif' align='absmiddle' border='0'> <a href='{$pageName}?{$entity}hideinactive=1'>{$GLOBALS['strHideInactivePublishers']}</a>"; } echo "\n </td>\n <td colspan='4' align='{$phpAds_TextAlignRight}' nowrap><img src='" . OX::assetPath() . "/images/triangle-d.gif' align='absmiddle' border='0'> <a href='{$pageName}?{$entity}expand=all'>{$GLOBALS['strExpandAll']}</a> | <img src='" . OX::assetPath() . "/images/{$phpAds_TextDirection}/triangle-l.gif' align='absmiddle' border='0'> <a href='{$pageName}?{$entity}expand=none'>{$GLOBALS['strCollapseAll']}</a> </td>\n </tr>\n <tr height='25'>"; if ($showPublisher == 't') { echo "\n <td colspan='7' align='{$phpAds_TextAlignLeft}' nowrap> <img src='" . OX::assetPath() . "/images/icon-affiliate.gif' align='absmiddle'><a href='{$pageName}?{$entity}showpublisher=f'> Hide parent publisher</a></td>"; } else { echo "\n <td colspan='7' align='{$phpAds_TextAlignLeft}' nowrap> <img src='" . OX::assetPath() . "/images/icon-affiliate.gif' align='absmiddle'><a href='{$pageName}?{$entity}showpublisher=t'> Show parent publisher</a></td>"; } echo "\n </tr>"; } echo "\n </table>\n <br /><br />"; } else { MAX_displayNoStatsMessage(); } }
/** * Add direct selection stats to an entity array * * @param array Query parameters * @param array Entities array */ function addDirectSelection($aParams, &$aEntitiesData) { $aParams['exclude'] = array('ad_id'); $aParams['zone_id'] = 0; // Get plugin aParams $pluginParams = array(); foreach ($this->aPlugins as $oPlugin) { $oPlugin->addQueryParams($pluginParams); } $aDirectSelection = Admin_DA::fromCache('getEntitiesStats', $aParams + $this->aDates); // Merge plugin additional data foreach ($this->aPlugins as $oPlugin) { $oPlugin->mergeData($aDirectSelection, $this->aEmptyRow, 'getEntitiesStats', $aParams + $this->aDates); } if (count($aDirectSelection)) { $zone = current($aDirectSelection) + $this->aEmptyRow; $zone['active'] = $this->_hasActiveStats($zone); if ($zone['active']) { $this->_summarizeStats($zone); $zone['name'] = $GLOBALS['strGenerateBannercode']; $zone['prefix'] = 'x'; $zone['id'] = '-'; $zone['icon'] = OX::assetPath() . '/images/icon-generatecode.gif'; $zone['htmlclass'] = 'last'; if ($this->listOrderField != 'name' && $this->listOrderField != 'id') { $aEntitiesData[] = $zone; MAX_sortArray($aEntitiesData, $this->listOrderField, $this->listOrderDirection == 'up'); } elseif ($this->listOrderDirection == 'up') { array_push($aEntitiesData, $zone); } else { array_unshift($aEntitiesData, $zone); } } } }
/** * Fetch the history stats using the specified parameters * * @param array $aParams Query parameters * @param string $link Optional link for the leftmost column content */ function getHistory($aParams, $link = '') { $oNow = new Date(); $aParams['tz'] = $oNow->tz->getID(); $method = $this->oHistory->setBreakdownInfo($this); // Add plugin aParams $pluginParams = array(); foreach ($this->aPlugins as $oPlugin) { $oPlugin->addQueryParams($pluginParams); } $aStats = Admin_DA::fromCache($method, $aParams + $this->aDates + $pluginParams); // Merge plugin additional $oPlugin foreach ($this->aPlugins as $oPlugin) { $oPlugin->mergeData($aStats, $this->aEmptyRow, $method, $aParams + $this->aDates); } if (count($aStats) == 0) { $this->noStatsAvailable = true; return $aStats; } // Fill unused plugins columns foreach (array_keys($aStats) as $k) { $aStats[$k] += $this->aEmptyRow; } $aDates = $this->oHistory->getDatesArray($this->aDates, $this->statsBreakdown, $this->oStartDate); $this->oHistory->fillGapsAndLink($aStats, $aDates, $this, $link); if (!in_array($this->listOrderField, array_merge(array($this->statsBreakdown), array_keys($this->aColumns)))) { $this->listOrderField = $this->statsBreakdown; $this->listOrderDirection = $this->statsBreakdown == 'hour' || $this->statsBreakdown == 'dow' ? 'up' : 'down'; } // If required, re-format the data in the weekly breakdown format if ($this->statsBreakdown == 'week') { $this->oHistory->prepareWeekBreakdown($aStats, $this); } MAX_sortArray($aStats, $this->listOrderField, $this->listOrderDirection == 'up'); // Summarise the values into a the totals array, & format $this->_summariseTotalsAndFormat($aStats, true); return $aStats; }
$bgcolorSave = $bgcolor; $allchecked = true; foreach ($aZones as $zoneId => $aZone) { if (!isset($aLinkedZones[$zoneId])) { $allchecked = false; break; } } $checked = $allchecked ? ' checked' : ''; if ($i > 0) { echo "\n<tr height='1'>\n <td colspan='3' bgcolor='#888888'><img src='" . OX::assetPath() . "/images/break.gif' height='1' width='100%'></td>\n</tr>"; } echo "\n<tr height='25'{$bgcolor}>\n <td>\n <table>\n <tr>\n <td> </td>\n <td valign='top'><input id='affiliate{$publisherId}' name='affiliate[{$publisherId}]' type='checkbox' value='t'{$checked} onClick='toggleZones({$publisherId});' tabindex='{$tabindex}'> </td>\n <td valign='top'><img src='" . OX::assetPath() . "/images/icon-affiliate.gif' align='absmiddle'> </td>\n <td><a href='affiliate-edit.php?affiliateid={$publisherId}'>" . htmlspecialchars($publisherName) . "</a> </td>\n </tr>\n </table>\n </td>\n <td>{$publisherId}</td>\n <td height='25'> </td>\n</tr>"; $tabindex++; if (!empty($aZones)) { MAX_sortArray($aZones, $listorder == 'id' ? 'zone_id' : $listorder, $orderdirection == 'up'); foreach ($aZones as $zoneId => $aZone) { $zoneName = $aZone['name']; $zoneDescription = $aZone['description']; $zoneIsActive = isset($aZone['active']) && $aZone['active'] == 't' ? true : false; $zoneIcon = MAX_getEntityIcon('zone', $zoneIsActive, $aZone['type']); $checked = isset($aLinkedZones[$zoneId]) ? ' checked' : ''; $bgcolor = $checked == ' checked' ? " bgcolor='#d8d8ff'" : $bgcolorSave; echo "\n<tr height='25'{$bgcolor}>\n <td>\n <table>\n <tr>\n <td width='28'> </td>\n <td valign='top'><input name='includezone[{$zoneId}]' id='a{$publisherId}' type='checkbox' value='t'{$checked} onClick='toggleAffiliate({$publisherId});' tabindex='{$tabindex}'> </td>\n <td valign='top'><img src='{$zoneIcon}' align='absmiddle'> </td>\n <td><a href='zone-edit.php?affiliateid={$publisherId}&zoneid={$zoneId}'>" . htmlspecialchars($zoneName) . "</a> </td>\n </tr>\n </table>\n </td>\n <td>{$zoneId}</td>\n <td>" . htmlspecialchars($zoneDescription) . "</td>\n</tr>"; } } $i++; } } echo "\n<tr height='1'><td colspan='3' bgcolor='#888888'><img src='" . OX::assetPath() . "/images/break.gif' height='1' width='100%'></td></tr>"; }