<commit_before><?php

/**
 * @see https://github.com/barbushin/php-imap
 * @author <NAME> http://linkedin.com/in/barbushin
 *
 */
class ImapMailbox {

	protected $imapPath;
	protected $login;
	protected $password;
	protected $mbox;
	protected $serverEncoding;
	protected $attachmentsDir;

	public function __construct($imapPath, $login, $password, $attachmentsDir = false, $serverEncoding = 'utf-8') {
		$this->imapPath = $imapPath;
		$this->login = $login;
		$this->password = $password;
		$this->serverEncoding = $serverEncoding;
		if ($attachmentsDir) {
			if (!is_dir($attachmentsDir)) {
				throw new Exception('Directory "' . $attachmentsDir . '" not found');
			}
			$this->attachmentsDir = realpath($attachmentsDir);
		}

		$this->connect();
	}

	/*
	 * Connect to IMAP mailbox
	 */
	public function connect() {
		$this->mbox = @imap_open($this->imapPath, $this->login, $this->password);
		if (!$this->mbox) {
			throw new ImapMailboxException('Connection error: ' . imap_last_error());
		}
		return true;
	}

	/*
	 * CLose IMAP connection
	 */
	public function disconnect() {
		if ($this->mbox) {
			$this->expungeDeletedMessages();
			$errors = imap_errors();
			if ($errors) {
				foreach ($errors as $error) {
					trigger_error($error);
				}
			}
			imap_close($this->mbox);
			$this->mbox = null;
		}
	}

	/*
	 * Pings the stream to see if it's still active. It may discover new mail;
	 * this is the preferred method for a periodic "new mail check" as well as a "keep alive"
	 * for servers which have inactivity timeout.
	 *
	 * Returns TRUE if the stream is still alive, attempts to reconnect otherwise.
	 */
	public function pingMailbox() {
		if (!imap_ping($this->mbox)) {
			return $this->reconnect();
		}
		return true;
	}

	/*
	 * Re-connect to IMAP mailbox
	 */
	public function reconnect() {
		$this->disconnect();
		return $this->connect();
	}

	/*
	 * object checkMailbox ( )
	 * 
	 * Checks information about the current mailbox.
	 *
	 * Returns the information in an object with following properties:
	 *	Date - current system time formatted according to  RFC2822
	 *	Driver - protocol used to access this mailbox: POP3, IMAP, NNTP
	 *	Mailbox - the mailbox name
	 *	Nmsgs - number of messages in the mailbox
	 *	Recent - number of recent messages in the mailbox
	 * Returns FALSE on failure.
	 */
	public function checkMailbox() {
		$this->pingMailbox();
		return imap_check($this->mbox);
	}

	/*
	 * array searchMailbox ( string $criteria  )
	 *
	 * This function performs a search on the mailbox currently opened in the given IMAP stream.
	 * For example, to match all unanswered messages sent by Mom, you'd use: "UNANSWERED FROM mom".
	 * Searches appear to be case insensitive. This list of criteria is from a reading of the UW
	 * c-client source code and may be incomplete or inaccurate (see also  RFC2060, section 6.4.4).
	 *
	 * criteria
	 *	A string, delimited by spaces, in which the following keywords are allowed. Any multi-word arguments (e.g. FROM "joey smith") must be quoted. Results will match all criteria entries.
	 *		ALL - return all messages matching the rest of the criteria
	 *		ANSWERED - match messages with the \\ANSWERED flag set
	 *		BCC "string" - match messages with "string" in the Bcc: field
	 *		BEFORE "date" - match messages with Date: before "date"
	 *		BODY "string" - match messages with "string" in the body of the message
	 *		CC "string" - match messages with "string" in the Cc: field
	 *		DELETED - match deleted messages
	 *		FLAGGED - match messages with the \\FLAGGED (sometimes referred to as Important or Urgent) flag set
	 *		FROM "string" - match messages with "string" in the From: field
	 *		KEYWORD "string" - match messages with "string" as a keyword
	 *		NEW - match new messages
	 *		OLD - match old messages
	 *		ON "date" - match messages with Date: matching "date"
	 *		RECENT - match messages with the \\RECENT flag set
	 *		SEEN - match messages that have been read (the \\SEEN flag is set)
	 *		SINCE "date" - match messages with Date: after "date"
	 *		SUBJECT "string" - match messages with "string" in the Subject:
	 *		TEXT "string" - match messages with text "string"
	 *		TO "string" - match messages with "string" in the To:
	 *		UNANSWERED - match messages that have not been answered
	 *		UNDELETED - match messages that are not deleted
	 *		UNFLAGGED - match messages that are not flagged
	 *		UNKEYWORD "string" - match messages that do not have the keyword "string"
	 *		UNSEEN - match messages which have not been read yet
	 *
	 * Returns an array of message numbers or UIDs.
	 .* Return FALSE if it does not understand the search criteria or no messages have been found.
	 */
	public function searchMailbox($criteria = 'ALL') {
		$this->pingMailbox();
		$mailsIds = imap_search($this->mbox, $criteria, SE_UID, $this->serverEncoding);
		return $mailsIds ? $mailsIds : array();
	}

	/*
	 * bool undeleteMessage (int $msg_number )
	 *
	 * Removes the deletion flag for a specified message, which is set by imap_delete() or imap_mail_move().
	 *
	 * msg_number
	 *	The message number
	 */
	public function undeleteMessage($msg_number) {
		$this->pingMailbox();
		return imap_delete($this->mbox, $msg_number, FT_UID);
	}

	/*
	 * bool deleteMessage (int $msg_number )
	 *
	 * Marks messages listed in msg_number for deletion.
	 *
	 * msg_number
	 *	The message number
	 */
	public function deleteMessage($msg_number, $purge_deleted = false) {
		$this->pingMailbox();
		return imap_delete($this->mbox, $msg_number, FT_UID);
	}

	/*
	 * bool expungeDeletedMessages ( )
	 *
	 * Deletes all the messages marked for deletion by imap_delete(), imap_mail_move(), or imap_setflag_full().
	 */
	public function expungeDeletedMessages() {
		$this->pingMailbox();
		return imap_expunge($this->mbox);
	}

	// Mark e-mail as seen
	public function markMessageAsRead($mId) {
		$this->pingMailbox();
		$this->setFlag($mId, '\\Seen');
	}

	// Mark e-mail as unseen
	public function markMessageAsUnread($mId) {
		$this->pingMailbox();
		$this->clearFlag($mId, '\\Seen');
	}

	// Mark e-mail as flagged
	public function markMessageAsImportant($mId) {
		$this->pingMailbox();
		$this->setFlag($mId, '\\Flagged');
	}

	/*
	 * bool setFlag ( string $sequence , string $flag )
	 * 
	 * Causes a store to add the specified flag to the flags set for the messages in the specified sequence.
	 * 
	 * sequence
	 *	A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
	 * flag
	 *	The flags which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by  RFC2060.
	 * 
	 * Returns TRUE on success or FALSE on failure.
	 */
	public function setFlag($sequence, $flag) {
		$this->pingMailbox();
		return imap_setflag_full($this->mbox, $mId, $flag, ST_UID);
	}

	/*
	 * bool clearFlag ( string $sequence , string $flag )
	 * 
	 * This function causes a store to delete the specified flag to the flags set for the messages in the specified sequence.
	 * 
	 * sequence
	 *  A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
	 * 
	 * flag
	 *  The flags which you can unset are "\\Seen", "\\Answered", "\\Flagged", "\\Deleted", and "\\Draft" (as defined by  RFC2060)
	 * 
	 * Returns TRUE on success or FALSE on failure.
	 */
	public function clearFlag($mId, $flag) {
		$this->pingMailbox();
		return imap_clearflag_full($this->mbox, $mId, $flag, ST_UID);
	}<commit_msg>Fixing a bug in set/clear flag functions<commit_after><?php

/**
 * @see https://github.com/barbushin/php-imap
 * @author <NAME> http://linkedin.com/in/barbushin
 *
 */
class ImapMailbox {

	protected $imapPath;
	protected $login;
	protected $password;
	protected $mbox;
	protected $serverEncoding;
	protected $attachmentsDir;

	public function __construct($imapPath, $login, $password, $attachmentsDir = false, $serverEncoding = 'utf-8') {
		$this->imapPath = $imapPath;
		$this->login = $login;
		$this->password = $password;
		$this->serverEncoding = $serverEncoding;
		if ($attachmentsDir) {
			if (!is_dir($attachmentsDir)) {
				throw new Exception('Directory "' . $attachmentsDir . '" not found');
			}
			$this->attachmentsDir = realpath($attachmentsDir);
		}

		$this->connect();
	}

	/*
	 * Connect to IMAP mailbox
	 */
	public function connect() {
		$this->mbox = @imap_open($this->imapPath, $this->login, $this->password);
		if (!$this->mbox) {
			throw new ImapMailboxException('Connection error: ' . imap_last_error());
		}
		return true;
	}

	/*
	 * CLose IMAP connection
	 */
	public function disconnect() {
		if ($this->mbox) {
			$this->expungeDeletedMessages();
			$errors = imap_errors();
			if ($errors) {
				foreach ($errors as $error) {
					trigger_error($error);
				}
			}
			imap_close($this->mbox);
			$this->mbox = null;
		}
	}

	/*
	 * Pings the stream to see if it's still active. It may discover new mail;
	 * this is the preferred method for a periodic "new mail check" as well as a "keep alive"
	 * for servers which have inactivity timeout.
	 *
	 * Returns TRUE if the stream is still alive, attempts to reconnect otherwise.
	 */
	public function pingMailbox() {
		if (!imap_ping($this->mbox)) {
			return $this->reconnect();
		}
		return true;
	}

	/*
	 * Re-connect to IMAP mailbox
	 */
	public function reconnect() {
		$this->disconnect();
		return $this->connect();
	}

	/*
	 * object checkMailbox ( )
	 * 
	 * Checks information about the current mailbox.
	 *
	 * Returns the information in an object with following properties:
	 *	Date - current system time formatted according to  RFC2822
	 *	Driver - protocol used to access this mailbox: POP3, IMAP, NNTP
	 *	Mailbox - the mailbox name
	 *	Nmsgs - number of messages in the mailbox
	 *	Recent - number of recent messages in the mailbox
	 * Returns FALSE on failure.
	 */
	public function checkMailbox() {
		$this->pingMailbox();
		return imap_check($this->mbox);
	}

	/*
	 * array searchMailbox ( string $criteria  )
	 *
	 * This function performs a search on the mailbox currently opened in the given IMAP stream.
	 * For example, to match all unanswered messages sent by Mom, you'd use: "UNANSWERED FROM mom".
	 * Searches appear to be case insensitive. This list of criteria is from a reading of the UW
	 * c-client source code and may be incomplete or inaccurate (see also  RFC2060, section 6.4.4).
	 *
	 * criteria
	 *	A string, delimited by spaces, in which the following keywords are allowed. Any multi-word arguments (e.g. FROM "<NAME>") must be quoted. Results will match all criteria entries.
	 *		ALL - return all messages matching the rest of the criteria
	 *		ANSWERED - match messages with the \\ANSWERED flag set
	 *		BCC "string" - match messages with "string" in the Bcc: field
	 *		BEFORE "date" - match messages with Date: before "date"
	 *		BODY "string" - match messages with "string" in the body of the message
	 *		CC "string" - match messages with "string" in the Cc: field
	 *		DELETED - match deleted messages
	 *		FLAGGED - match messages with the \\FLAGGED (sometimes referred to as Important or Urgent) flag set
	 *		FROM "string" - match messages with "string" in the From: field
	 *		KEYWORD "string" - match messages with "string" as a keyword
	 *		NEW - match new messages
	 *		OLD - match old messages
	 *		ON "date" - match messages with Date: matching "date"
	 *		RECENT - match messages with the \\RECENT flag set
	 *		SEEN - match messages that have been read (the \\SEEN flag is set)
	 *		SINCE "date" - match messages with Date: after "date"
	 *		SUBJECT "string" - match messages with "string" in the Subject:
	 *		TEXT "string" - match messages with text "string"
	 *		TO "string" - match messages with "string" in the To:
	 *		UNANSWERED - match messages that have not been answered
	 *		UNDELETED - match messages that are not deleted
	 *		UNFLAGGED - match messages that are not flagged
	 *		UNKEYWORD "string" - match messages that do not have the keyword "string"
	 *		UNSEEN - match messages which have not been read yet
	 *
	 * Returns an array of message numbers or UIDs.
	 .* Return FALSE if it does not understand the search criteria or no messages have been found.
	 */
	public function searchMailbox($criteria = 'ALL') {
		$this->pingMailbox();
		$mailsIds = imap_search($this->mbox, $criteria, SE_UID, $this->serverEncoding);
		return $mailsIds ? $mailsIds : array();
	}

	/*
	 * bool undeleteMessage (int $msg_number )
	 *
	 * Removes the deletion flag for a specified message, which is set by imap_delete() or imap_mail_move().
	 *
	 * msg_number
	 *	The message number
	 */
	public function undeleteMessage($msg_number) {
		$this->pingMailbox();
		return imap_delete($this->mbox, $msg_number, FT_UID);
	}

	/*
	 * bool deleteMessage (int $msg_number )
	 *
	 * Marks messages listed in msg_number for deletion.
	 *
	 * msg_number
	 *	The message number
	 */
	public function deleteMessage($msg_number, $purge_deleted = false) {
		$this->pingMailbox();
		return imap_delete($this->mbox, $msg_number, FT_UID);
	}

	/*
	 * bool expungeDeletedMessages ( )
	 *
	 * Deletes all the messages marked for deletion by imap_delete(), imap_mail_move(), or imap_setflag_full().
	 */
	public function expungeDeletedMessages() {
		$this->pingMailbox();
		return imap_expunge($this->mbox);
	}

	// Mark e-mail as seen
	public function markMessageAsRead($mId) {
		$this->pingMailbox();
		$this->setFlag($mId, '\\Seen');
	}

	// Mark e-mail as unseen
	public function markMessageAsUnread($mId) {
		$this->pingMailbox();
		$this->clearFlag($mId, '\\Seen');
	}

	// Mark e-mail as flagged
	public function markMessageAsImportant($mId) {
		$this->pingMailbox();
		$this->setFlag($mId, '\\Flagged');
	}

	/*
	 * bool setFlag ( string $sequence , string $flag )
	 * 
	 * Causes a store to add the specified flag to the flags set for the messages in the specified sequence.
	 * 
	 * sequence
	 *	A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
	 * flag
	 *	The flags which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by  RFC2060.
	 * 
	 * Returns TRUE on success or FALSE on failure.
	 */
	public function setFlag($sequence, $flag) {
		$this->pingMailbox();
		return imap_setflag_full($this->mbox, $sequence, $flag, ST_UID);
	}

	/*
	 * bool clearFlag ( string $sequence , string $flag )
	 * 
	 * This function causes a store to delete the specified flag to the flags set for the messages in the specified sequence.
	 * 
	 * sequence
	 *  A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
	 * 
	 * flag
	 *  The flags which you can unset are "\\Seen", "\\Answered", "\\Flagged", "\\Deleted", and "\\Draft" (as defined by  RFC2060)
	 * 
	 * Returns TRUE on success or FALSE on failure.
	 */
	public function clearFlag($sequence, $flag) {
		$this->pingMailbox();
		return imap_clearflag_full($this->mbox, $sequence, $flag, ST_UID);
	}
{'fraction_non_alphanumeric': 0.11290748317275967, 'fraction_numerical': 0.002771545466543487, 'mean_word_length': 3.463917525773196, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 86, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5725782', 'n_tokens_mistral': 5094, 'n_tokens_neox': 4623, 'n_words': 1693}