Skip to content

Commit

Permalink
Fixed help desk history id not being associated with correct post.
Browse files Browse the repository at this point in the history
Fixed some Zendesk comments not being imported properly. Awesome-Support#6
Added support for saving private notes in Zendesk.
  • Loading branch information
nmoinvaz committed Apr 25, 2018
1 parent 3985fd6 commit f2602b0
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 42 deletions.
51 changes: 44 additions & 7 deletions src/API/Provider/Zendesk/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ApiController extends ProviderController
******************************************/

/**
* Request the Tickets from Help Scout.
* Request the Tickets from Zendesk.
*
* @since 0.1.0
*
Expand All @@ -39,23 +39,59 @@ protected function request()
$this->dataMapper->mapJSON($json, $whichEndpoint);
}
}

// Process each of the items and request each comment.
foreach ($this->jsonResponses['tickets'] as $json) {
$packet = $this->fromJSON($json);
foreach ($packet->tickets as $ticket) {
echo '<pre>Getting '.$ticket->comment_count.' comments for ticket '.$ticket->id.'</pre>';
if ((int)$ticket->comment_count > 0 && $ticket->status != 'deleted') {
$this->requestComments($ticket->id);
}
}
}
}

protected function requestPackets($whichEndpoint)
{
$nextPage = '';
do {
$packet = $this->get(
$packet = $this->get(
$this->getEndpoint($whichEndpoint, $nextPage)
);
$this->jsonResponses[$whichEndpoint][] = $packet;

// Unpack to get the next page and count.
$packet = $this->fromJSON($packet);
$nextPage = $packet->next_page;
} while ($packet->count > self::MAX_PACKET_SIZE);
$packet = $this->fromJSON($packet);
if ($nextPage == urldecode($packet->next_page)) {
break;
}
$nextPage = urldecode($packet->next_page);
} while ($packet->count >= self::MAX_PACKET_SIZE);
}

/**
* Request and map the comments for the specific ticket ID from Zendesk.
*
* @since 0.1.0
*
* @param int|string $ticketId
*
* @return void
*/
protected function requestComments($ticketId)
{
$pattern = 'https://%s.zendesk.com/api/v2/tickets/%d/comments.json?include=users';
$url = sprintf(
$pattern,
$this->subdomain,
$ticketId
);

$packet = $this->get($url);

$this->dataMapper->mapJSON($packet, 'comments', $ticketId);
}
/**
* Get the endpoint for the selected task, i.e. tickets or ticket events.
*
Expand All @@ -78,12 +114,13 @@ protected function getEndpoint($whichEndpoint, $endpoint = '')
}
$pattern = 'https://%s.zendesk.com/api/v2/incremental/';
$pattern .= 'ticketEvents' === $whichEndpoint
? 'ticket_events.json?start_time=%s&include=comment_events'
? 'ticket_events.json?start_time=%s'
: 'tickets.json?start_time=%s&include=users,comment_count';
return sprintf(
$url = sprintf(
$pattern,
$this->subdomain,
$this->getStartTime()
);
return $url;
}
}
53 changes: 38 additions & 15 deletions src/API/Provider/Zendesk/DataMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DataMapper extends AbstractDataMapper
*
* @return void
*/
public function mapJSON($json, $key = '')
public function mapJSON($json, $key = '', $ticketId = null)
{
$packets = $this->fromJSON($json);

Expand All @@ -33,6 +33,11 @@ public function mapJSON($json, $key = '')
if ('ticketEvents' === $key) {
$this->mapEvents($packets->ticket_events);
}

if ('comments' === $key) {
$this->mapUsers($packets->users);
$this->mapComments($packets->comments, $ticketId);
}
}

/**
Expand Down Expand Up @@ -110,9 +115,7 @@ protected function mapEvents(array $ticketEvents)

// Psst...using a closure to pass $data byRef.
array_walk($ticketEvent->child_events, function ($childEvent) use (&$data) {
if (!isset($childEvent->public) || $childEvent->public) {
$this->mapChildEvent($childEvent, $data);
}
$this->mapChildEvent($childEvent, $data);
});

// If there's a reply, then let's process it.
Expand All @@ -138,17 +141,6 @@ protected function mapEvents(array $ticketEvents)
protected function mapChildEvent(\stdClass $event, array &$data)
{
if ('Comment' === $event->event_type) {
$data['date'] = $this->toFormattedDate($event->created_at);

$data['replyId'] = $event->id;
$data['reply'] = [
'userId' => $event->author_id,
'reply' => $event->body,
'timestamp' => $data['date'],
];
if ($this->hasAttachments($event)) {
$data['attachments'] = $event->attachments;
}
return;
}

Expand All @@ -172,6 +164,36 @@ protected function mapChildEvent(\stdClass $event, array &$data)
}
}

protected function mapComments(array $comments, $ticketId)
{
foreach ($comments as $comment) {
$data = [
'id' => $comment->id,
'ticketId' => $ticketId,
'date' => $this->toFormattedDate($comment->created_at),
'timestamp' => $this->toFormattedDate($comment->created_at),
'isOriginalTicket' => false,
'requesterId' => 0,
'reply' => null,
'replyId' => $comment->id,
'attachments' => $comment->attachments
];

$data['reply'] = [
'userId' => $comment->author_id,
'reply' => $comment->body,
'timestamp' => $data['date'],
'private' => false
];

if (isset($comment->public) && !$comment->public) {
$data['private'] = true;
}

$this->mapReplyOrTicket($data);
}
}

/**
* Map the reply/comment for this ticket.
*
Expand All @@ -197,6 +219,7 @@ protected function mapReplyOrTicket(array $data)
}

$this->replyRepository->create($data['ticketId'], $data['replyId'], $data['reply']);

if (isset($data['attachments'])) {
$this->mapAttachments($data['attachments'], $data['ticketId'], $data['replyId']);
}
Expand Down
8 changes: 6 additions & 2 deletions src/API/Repository/HistoryRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ class HistoryRepository extends Repository
*
* @return void
*/
public function create($ticketId, $userId, $status, $timestamp, $id = 0)
public function create($ticketId, $userId, $status, $timestamp, $historyId = 0)
{
if (!$this->has($ticketId)) {
$this->set($ticketId, []);
}

if ($historyId == 0) {
$historyId = sha1($userId.$timestamp.$status);
}

$this->items[$ticketId][] = [
'id' => $id,
'id' => $historyId,
'user' => (int)$userId,
'value' => $status,
'date' => $timestamp,
Expand Down
20 changes: 8 additions & 12 deletions src/Importer/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ protected function processReply(array $reply, $ticketId, $helpDeskReplyId)
{
$author = $this->processUser($reply['user']);

$replyId = $this->inserter->insertReply(
$replyId = $this->inserter->insertReply(
$ticketId,
$reply['reply'],
$author,
Expand Down Expand Up @@ -288,19 +288,15 @@ protected function processHistory(Ticket $ticket, $ticketId)
}
foreach ($ticket->getHistory() as $history) {
// If it exists in the db, no need to import.
if (!empty($history['id'])) {
$historyId = $this->locator->findHistoryByHelpDeskId($history['id']);
if ($this->validator->isValidHistoryId($historyId)) {
continue;
}
}
$historyId = $this->locator->findHistoryByHelpDeskId($history['id']);
if ($this->validator->isValidHistoryId($historyId)) {
continue;
}

$author = $this->processUser($history['user']);

$this->inserter->insertHistoryItem($ticketId, $author, $history['date'], $history['value']);
if (!empty($history['id'])) {
$this->inserter->setHelpDeskHistoryId($ticketId, $history['id']);
}
$historyId = $this->inserter->insertHistoryItem($ticketId, $author, $history['date'], $history['value']);
$this->inserter->setHelpDeskHistoryId($historyId, $history['id']);
}
}

Expand All @@ -315,7 +311,7 @@ protected function processHistory(Ticket $ticket, $ticketId)
*/
protected function processUser($userEntity)
{
if (!$userEntity instanceof User || empty($userEntity->getEmail())) {
if (!$userEntity instanceof User) {
return $this->currentUser;
}

Expand Down
21 changes: 15 additions & 6 deletions src/Importer/Inserter.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public function insertAttachment($postId, array $attachment)
* @return int|WP_Error
* @throws ImportException
*/
public function insertReply($ticketId, $reply, WP_User $author, $date, $read)
public function insertReply($ticketId, $reply, WP_User $author, $date, $read, $private = false)
{
wp_set_current_user($author->ID);

Expand All @@ -212,6 +212,13 @@ public function insertReply($ticketId, $reply, WP_User $author, $date, $read)
$ticketId
);

if ($private) {
$response = wp_update_post([
'ID' => $replyId,
'post_type' => 'ticket_note'
]);
}

wp_set_current_user($this->currentUserId);

if ($replyId instanceof WP_Error) {
Expand Down Expand Up @@ -263,9 +270,9 @@ public function insertHistoryItem($ticketId, WP_User $author, $date, $status)
wpas_update_ticket_status($ticketId, $status);
}

$postId = $this->locator->findPostByMetaId($this->wpdb->insert_id);
$historyId = $this->locator->findPostByMetaId($this->wpdb->insert_id);
$response = wp_update_post([
'ID' => $postId,
'ID' => $historyId,
'post_author' => $author->ID,
'post_date' => $date,
'post_date_gmt' => get_gmt_from_date($date),
Expand All @@ -292,22 +299,24 @@ public function insertHistoryItem($ticketId, WP_User $author, $date, $status)
],
__CLASS__
);

return $historyId;
}

/**
* Set the history ID in the post meta database table.
*
* @since 0.2.0
*
* @param int $replyId The history's post ID.
* @param int $historyId The history's post ID.
* @param string|int $helpDeskId The original ID.
*
* @return bool|int
*/

public function setHelpDeskHistoryId($replyId, $helpDeskId)
public function setHelpDeskHistoryId($historyId, $helpDeskId)
{
return update_post_meta($replyId, '_wpas_help_desk_history_id', sanitize_text_field($helpDeskId));
return update_post_meta($historyId, '_wpas_help_desk_history_id', sanitize_text_field($helpDeskId));
}

/**
Expand Down

0 comments on commit f2602b0

Please sign in to comment.