<commit_before><?php

namespace Wrep\Notificato\Apns;

/**
 * An APNS Message representation.
 * Note: All strings given to this class must be in UTF-8 to create a valid message
 */
class Message
{
	// Attributes that go into the binary APNS comminucation
	private $deviceToken;
	private $certificate;
	private $expiresAt;

	// Attributes that go into the payload
	private $alert;
	private $badge;
	private $sound;
	private $payload;
	private $contentAvailable;

	/**
	 * Construct Message
	 *
	 * @param string Receiver of this message
	 * @param Certificate The certificate that must be used for the APNS connection this message is send over
	 * @param array|null The alert to display or null to set no alert
	 * @param int|null The badge number to display
	 * @param string|null String of the sound to play, null for no sound sound
	 * @param array|json|null The payload to send as array or JSON string
	 * @param boolean True when new newsstand content is available, false when not
	 * @param \DateTime|null Date until the message should be stored for delivery
	 * @throws \InvalidArgumentException On invalid or missing arguments
	 * @throws \LengthException On too long message
	 */
	public function __construct($deviceToken, Certificate $certificate, $alert, $badge, $sound, $payload, $contentAvailable, \DateTime $expiresAt = null)
	{
		// Set the devicetoken
		$this->setDeviceToken($deviceToken);
		$this->certificate = $certificate;
		$this->expiresAt = (null == $expiresAt) ? 0 : $expiresAt->format('U');

		// Set the defaults
		$this->setAlert($alert);
		$this->setBadge($badge);
		$this->sound = (null == $sound) ? null : (string)$sound;
		$this->setPayload($payload);
		$this->contentAvailable = (bool)$contentAvailable;

		// Validate the length of the message
		if (strlen($this->getJson()) > 256) {
			throw new \LengthException('Length of the message exceeds the maximum of 256 characters.');
		}
	}

	/**
	 * Get the device token of the receiving device
	 *
	 * @return string
	 */
	public function getDeviceToken()
	{
		return $this->deviceToken;
	}

	/**
	 * Get the certificate that should be used for this message
	 *
	 * @return Certificate
	 */
	public function getCertificate()
	{
		return $this->certificate;
	}

	/**
	 * Get the moment this message expires
	 *
	 * @return int Unix timestamp of expiry moment or zero if no specific expiry moment is set
	 */
	public function getExpiresAt()
	{
		return $this->expiresAt;
	}

	/**
	 * Get the current alert
	 *
	 * @return string|array
	 */
	public function getAlert()
	{
		return $this->alert;
	}

	/**
	 * Get the value of the badge as set in this message
	 *
	 * @return int|null
	 */
	public function getBadge()
	{
		return $this->badge;
	}

	/**
	 * Get the sound that will be played when this message is received
	 *
	 * @return string|null
	 */
	public function getSound()
	{
		return $this->sound;
	}

	/**
	 * Get newsstand content availability flag that will trigger the newsstand item to download new content
	 *
	 * @return boolean True when new content is available, false when not
	 */
	public function getContentAvailable()
	{
		return $this->contentAvailable;
	}

	/**
	 * Get the current payload
	 *
	 * @return array|null
	 */
	public function getPayload()
	{
		return $this->payload;
	}

	/**
	 * Get the JSON payload that should be send to the APNS
	 *
	 * @return string
	 * @throws \RuntimeException When unable to create JSON, for example because of non-UTF-8 characters
	 */
	public function getJson()
	{
		// Get message and aps array to create JSON from
		$message = array();
		$aps = array();

		// If we have a payload replace the message object by the payload
		if (null !== $this->payload) {
			$message = $this->payload;
		}

		// Add the alert if any
		if (null !== $this->alert) {
			$aps['alert'] = $this->alert;
		}

		// Add the badge if any
		if (null !== $this->badge) {
			$aps['badge'] = $this->badge;
		}

		// Add the sound if any
		if (null !== $this->sound) {
			$aps['sound'] = $this->sound;
		}

		// Add the content-available flag if set
		if (true == $this->contentAvailable) {
			$aps['content-available'] = 1;
		}

		// Check if APS data is set
		if (count($aps) > 0) {
			$message['aps'] = $aps;
		}

		// Encode as JSON object
		$json = json_encode($message, JSON_FORCE_OBJECT);
		if (false == $json) {
			throw new \RuntimeException('Failed to convert APNS\Message to JSON, are all strings UTF-8?', json_last_error());
		}

		return $json;
	}

		/**
	 * Set the receiver of the message
	 *
	 * @param string Receiver of this message
	 * @throws \InvalidArgumentException On invalid or missing arguments
	 */
	private function setDeviceToken($deviceToken)
	{
		// Check if a devicetoken is given
		if (null == $deviceToken) {
			throw new \InvalidArgumentException('No device token given.');
		}<commit_msg>Added toString and Serialization to the Message<commit_after><?php

namespace Wrep\Notificato\Apns;

/**
 * An APNS Message representation.
 * Note: All strings given to this class must be in UTF-8 to create a valid message
 */
class Message implements \Serializable
{
	// Attributes that go into the binary APNS comminucation
	private $deviceToken;
	private $certificate;
	private $expiresAt;

	// Attributes that go into the payload
	private $alert;
	private $badge;
	private $sound;
	private $payload;
	private $contentAvailable;

	/**
	 * Construct Message
	 *
	 * @param string Receiver of this message
	 * @param Certificate The certificate that must be used for the APNS connection this message is send over
	 * @param array|null The alert to display or null to set no alert
	 * @param int|null The badge number to display
	 * @param string|null String of the sound to play, null for no sound sound
	 * @param array|json|null The payload to send as array or JSON string
	 * @param boolean True when new newsstand content is available, false when not
	 * @param \DateTime|null Date until the message should be stored for delivery
	 * @throws \InvalidArgumentException On invalid or missing arguments
	 * @throws \LengthException On too long message
	 */
	public function __construct($deviceToken, Certificate $certificate, $alert, $badge, $sound, $payload, $contentAvailable, \DateTime $expiresAt = null)
	{
		// Set the devicetoken
		$this->setDeviceToken($deviceToken);
		$this->certificate = $certificate;
		$this->expiresAt = (null == $expiresAt) ? 0 : $expiresAt->format('U');

		// Set the defaults
		$this->setAlert($alert);
		$this->setBadge($badge);
		$this->sound = (null == $sound) ? null : (string)$sound;
		$this->setPayload($payload);
		$this->contentAvailable = (bool)$contentAvailable;

		// Validate the length of the message
		if (strlen($this->getJson()) > 256) {
			throw new \LengthException('Length of the message exceeds the maximum of 256 characters.');
		}
	}

	/**
	 * Get the device token of the receiving device
	 *
	 * @return string
	 */
	public function getDeviceToken()
	{
		return $this->deviceToken;
	}

	/**
	 * Get the certificate that should be used for this message
	 *
	 * @return Certificate
	 */
	public function getCertificate()
	{
		return $this->certificate;
	}

	/**
	 * Get the moment this message expires
	 *
	 * @return int Unix timestamp of expiry moment or zero if no specific expiry moment is set
	 */
	public function getExpiresAt()
	{
		return $this->expiresAt;
	}

	/**
	 * Get the current alert
	 *
	 * @return string|array
	 */
	public function getAlert()
	{
		return $this->alert;
	}

	/**
	 * Get the value of the badge as set in this message
	 *
	 * @return int|null
	 */
	public function getBadge()
	{
		return $this->badge;
	}

	/**
	 * Get the sound that will be played when this message is received
	 *
	 * @return string|null
	 */
	public function getSound()
	{
		return $this->sound;
	}

	/**
	 * Get newsstand content availability flag that will trigger the newsstand item to download new content
	 *
	 * @return boolean True when new content is available, false when not
	 */
	public function getContentAvailable()
	{
		return $this->contentAvailable;
	}

	/**
	 * Get the current payload
	 *
	 * @return array|null
	 */
	public function getPayload()
	{
		return $this->payload;
	}

	/**
	 * Get the JSON payload that should be send to the APNS
	 *
	 * @return string
	 * @throws \RuntimeException When unable to create JSON, for example because of non-UTF-8 characters
	 */
	public function getJson()
	{
		// Get message and aps array to create JSON from
		$message = array();
		$aps = array();

		// If we have a payload replace the message object by the payload
		if (null !== $this->payload) {
			$message = $this->payload;
		}

		// Add the alert if any
		if (null !== $this->alert) {
			$aps['alert'] = $this->alert;
		}

		// Add the badge if any
		if (null !== $this->badge) {
			$aps['badge'] = $this->badge;
		}

		// Add the sound if any
		if (null !== $this->sound) {
			$aps['sound'] = $this->sound;
		}

		// Add the content-available flag if set
		if (true == $this->contentAvailable) {
			$aps['content-available'] = 1;
		}

		// Check if APS data is set
		if (count($aps) > 0) {
			$message['aps'] = $aps;
		}

		// Encode as JSON object
		$json = json_encode($message, JSON_FORCE_OBJECT);
		if (false == $json) {
			throw new \RuntimeException('Failed to convert APNS\Message to JSON, are all strings UTF-8?', json_last_error());
		}

		return $json;
	}

	/**
	 * String representation of object
	 *
	 * @return string
	 */
	public function serialize()
	{
		return serialize(array(	$this->deviceToken,
								array( $this->certificate->getPemFile(), $this->certificate->getPassphrase(), $this->certificate->isValidated(), $this->certificate->getEnvironment() ),
								$this->expiresAt,
								$this->alert,
								$this->badge,
								$this->sound,
								$this->payload,
								$this->contentAvailable));
	}

	/**
	 * Constructs the object from serialized data
	 *
	 * @param string Serialized data
	 */
	public function unserialize($serialized)
	{
		list(	$this->deviceToken,
				$certificateData,
				$this->expiresAt,
				$this->alert,
				$this->badge,
				$this->sound,
				$this->payload,
				$this->contentAvailable) = unserialize($serialized);

		// Re-create the certificate
		$this->certificate = new Certificate($certificateData[0], $certificateData[1], $certificateData[2], $certificateData[3]);
	}

	/**
	 * Get a string representation of this object
	 *
	 * @return string
	 */
	public function __toString()
	{
		return	'Wrep\Notificato\Apns\Message:' . PHP_EOL .
				' Device token: ' . $this->getDeviceToken() . PHP_EOL .
				' Certificate: ' . $this->getCertificate()->getPemFile() . PHP_EOL .
				' Expires timestamp: ' . $this->getExpiresAt() . PHP_EOL .
				' Badge: ' . $this->getBadge() . PHP_EOL .
				' Sound: ' . $this->getSound() . PHP_EOL .
				' Content avail.: ' . $this->getContentAvailable() . PHP_EOL .
				' Alert: ' . json_encode($this->getAlert()) . PHP_EOL .
				' Payload: ' . json_encode($this->getPayload()) . PHP_EOL;
	}

	/**
	 * Set the receiver of the message
	 *
	 * @param string Receiver of this message
	 * @throws \InvalidArgumentException On invalid or missing arguments
	 */
	private function setDeviceToken($deviceToken)
	{
		// Check if a devicetoken is given
		if (null == $deviceToken) {
			throw new \InvalidArgumentException('No device token given.');
		}
{'fraction_non_alphanumeric': 0.12204793796263659, 'fraction_numerical': 0.0024673951357067326, 'mean_word_length': 3.3217821782178216, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2631907', 'n_tokens_mistral': 3822, 'n_tokens_neox': 3372, 'n_words': 1183}