aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs/Lib/DReport.php
blob: 1292e7488d3e1c3d29b0767cf2509450d57df09e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace Zotlabs\Lib;

class DReport {

	private $location;
	private $sender;
	private $recipient;
	private $message_id;
	private $status;
	private $date;

	function __construct($location,$sender,$recipient,$message_id,$status = 'deliver') {
		$this->location   = $location;
		$this->sender     = $sender;
		$this->recipient  = $recipient;
		$this->name       = EMPTY_STR;
		$this->message_id = $message_id;
		$this->status     = $status;
		$this->date       = datetime_convert();
	}

	function update($status) {
		$this->status     = $status;
		$this->date       = datetime_convert();
	}

	function set_name($name) {
		$this->name = $name;
	}

	function addto_update($status) {
		$this->status = $this->status . ' ' . $status;
	}


	function set($arr) {
		$this->location   = $arr['location'];
		$this->sender     = $arr['sender'];
		$this->recipient  = $arr['recipient'];
		$this->name       = $arr['name'];
		$this->message_id = $arr['message_id'];
		$this->status     = $arr['status'];
		$this->date       = $arr['date'];
	}

	function get() {
		return array(
			'location'   => $this->location,
			'sender'     => $this->sender,
			'recipient'  => $this->recipient,
			'name'       => $this->name,
			'message_id' => $this->message_id,
			'status'     => $this->status,
			'date'       => $this->date
		);
	}

	/**
	 * @brief decide whether to store a returned delivery report
	 *
	 * @param array $dr
	 * @return boolean
	 */

	static function is_storable($dr) {

		if(get_config('system', 'disable_dreport'))
			return false;

		/**
		 * @hooks dreport_is_storable
		 *   Called before storing a dreport record to determine whether to store it.
		 *   * \e array
		 */

		call_hooks('dreport_is_storable', $dr);

		// let plugins accept or reject - if neither, continue on
		if(array_key_exists('accept',$dr) && intval($dr['accept']))
			return true;
		if(array_key_exists('reject',$dr) && intval($dr['reject']))
			return false;

		if(! ($dr['sender']))
			return false;

		// Is the sender one of our channels?

		$c = q("select channel_id from channel where channel_hash = '%s' or channel_portable_id = '%s'limit 1",
			dbesc($dr['sender']),
			dbesc($dr['sender'])
		);

		if(! $c)
			return false;

		// legacy zot recipients add a space and their name to the xchan. remove it if true.

		$legacy_recipient = strpos($dr['recipient'], ' ');
		if($legacy_recipient !== false) {
			$legacy_recipient_parts = explode(' ', $dr['recipient'], 2);
			$rxchan = $legacy_recipient_parts[0];
		}
		else {
			$rxchan = $dr['recipient'];
		}



		// is the recipient one of our connections, or do we want to store every report?

		$pcf = get_pconfig($c[0]['channel_id'],'system','dreport_store_all');
		if($pcf)
			return true;

		// We always add ourself as a recipient to private and relayed posts
		// So if a remote site says they can't find us, that's no big surprise
		// and just creates a lot of extra report noise

		if(($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient_not_found'))
			return false;

		// If you have a private post with a recipient list, every single site is going to report
		// back a failed delivery for anybody on that list that isn't local to them. We're only
		// concerned about this if we have a local hubloc record which says we expected them to
		// have a channel on that site.

		$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'",
			dbesc($rxchan),
			dbesc($dr['location'])
		);
		if((! $r) && ($dr['status'] === 'recipient_not_found'))
			return false;

		$r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
			dbesc($rxchan),
			intval($c[0]['channel_id'])
		);
		if($r)
			return true;

		return false;
	}


}