Commit 275c15b1bc2837772fd7f3fb5653d3dc86d232d1
1 parent
22609c36
Exists in
master
and in
81 other branches
Concurrent access to guests.xml file
Showing
1 changed file
with
129 additions
and
90 deletions
Show diff stats
php/classes/Guest.php
... | ... | @@ -7,117 +7,156 @@ |
7 | 7 | |
8 | 8 | class Guest { |
9 | 9 | |
10 | - private $guestXml, $guestXmlFile, $xp, $root; | |
10 | + private $guestXmlFile; | |
11 | 11 | public $Id, $Start, $Ip, $email; |
12 | 12 | |
13 | 13 | function __construct($Ip_, $email_ = null){ |
14 | - | |
15 | 14 | if($email_) { |
16 | - $this->Start = getdate(); | |
17 | - $this->Ip = $Ip_; | |
18 | - $this->email = $email_; | |
19 | - } | |
20 | - else { | |
21 | - $this->Id = substr($Ip_,strlen("guest")); | |
22 | - } | |
23 | - | |
24 | - $this->guestXmlFile = DATAPATH."guests.xml"; | |
25 | - $this->guestXml = new DomDocument("1.0"); | |
26 | - | |
27 | - if (!file_exists($this->guestXmlFile)){ | |
28 | - $status = $this->generateXML(); | |
29 | - } | |
30 | - else { | |
31 | - $this->guestXml->load($this->guestXmlFile); | |
32 | - $this->root = $this->guestXml->getElementsByTagName("guests")->item(0); | |
15 | + $this->Start = getdate(); | |
16 | + $this->Ip = $Ip_; | |
17 | + $this->email = $email_; | |
33 | 18 | } |
34 | - $this->xp = new domxpath($this->guestXml); | |
19 | + else { | |
20 | + $this->Id = substr($Ip_,strlen("guest")); | |
21 | + } | |
22 | + | |
23 | + $this->guestXmlFile = DATAPATH."guests.xml"; | |
24 | + } | |
25 | + | |
26 | + public function checkGuestTimes() { | |
27 | + return $this->concurrentAccessGuestFile(array($this,'_checkGuestTimes')); | |
28 | + } | |
29 | + | |
30 | + public function deleteGuest() { | |
31 | + return $this->concurrentAccessGuestFile(array($this,'_deleteGuest')); | |
32 | + } | |
33 | + | |
34 | + public function addGuest(){ | |
35 | + return $this->concurrentAccessGuestFile(array($this,'_addGuest')); | |
35 | 36 | } |
36 | 37 | |
37 | - private function generateXML() { | |
38 | - $this->root = $this->guestXml->createElement('guests'); | |
39 | - $this->guestXml->appendChild($this->root); | |
38 | + public function registerGuest(){ | |
39 | + return $this->concurrentAccessGuestFile(array($this,'_registerGuest')); | |
40 | + } | |
41 | + | |
42 | + private function concurrentAccessGuestFile($callback) { | |
43 | + $lockFile = $this->guestXmlFile.".lockfile"; | |
44 | + | |
45 | + $fp = fopen($lockFile, "w+"); | |
46 | + | |
47 | + if ($fp === false) { | |
48 | + return false; | |
49 | + } | |
40 | 50 | |
41 | - $status = $this->guestXml->save($this->guestXmlFile); | |
51 | + $res = true; | |
42 | 52 | |
43 | - return $status; | |
53 | + if (flock($fp, LOCK_EX)) | |
54 | + { | |
55 | + if (!file_exists($this->guestXmlFile)) { | |
56 | + $res = $this->_generateXML(); | |
57 | + } | |
58 | + | |
59 | + if ($res) { | |
60 | + $dom = new DomDocument("1.0","UTF-8"); | |
61 | + $dom->preserveWhiteSpace = false; | |
62 | + $dom->formatOutput = true; | |
63 | + $res = $dom->load($this->guestXmlFile); | |
64 | + if ($res) { | |
65 | + $func_res = call_user_func($callback,$dom); | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + else | |
70 | + $res = false; | |
71 | + | |
72 | + fclose($fp); | |
73 | + | |
74 | + if ($res) | |
75 | + return $func_res; | |
76 | + | |
77 | + return false; | |
78 | + } | |
79 | + | |
80 | + private function _generateXML() { | |
81 | + $dom = new DOMDocument("1.0","UTF-8"); | |
82 | + $dom->preserveWhiteSpace = false; | |
83 | + $dom->formatOutput = true; | |
84 | + $rootNode = $dom->createElement('guests'); | |
85 | + $dom->appendChild($rootNode); | |
86 | + return $dom->save($this->guestXmlFile); | |
44 | 87 | } |
45 | 88 | |
46 | - public function GetId(){ | |
47 | - | |
48 | - $elements = $this->xp->query("//@xml:id"); | |
89 | + private function _getId($dom){ | |
90 | + $xp = new DOMXpath($dom); | |
91 | + $elements = $xp->query("//@xml:id"); | |
49 | 92 | // Now find New Valid ID |
50 | - if ($elements->length > 0) { | |
51 | - $idList = array(); | |
52 | - for ($i = 0; $i < $elements->length; $i++) | |
53 | - $idList[$i] = $elements->item($i)->nodeValue; | |
93 | + if ($elements->length > 0) { | |
94 | + $idList = array(); | |
95 | + for ($i = 0; $i < $elements->length; $i++) | |
96 | + $idList[$i] = $elements->item($i)->nodeValue; | |
54 | 97 | |
55 | - sort($idList); | |
56 | - for ($i = 0; $i < $elements->length; $i++) { | |
57 | - if ($idList[$i] > $i) { | |
58 | - $newID = $i; | |
59 | - break; | |
60 | - } | |
61 | - $newID = $i+1; | |
62 | - } | |
63 | - } else { $newID = 0;} | |
64 | - | |
65 | - return $newID; | |
66 | - } | |
67 | - | |
68 | - public function checkGuestTimes(){ | |
69 | - | |
70 | - $Start_0 = time() - GuestSessionDuration*60; // in secs | |
71 | - $startTimes = $this->xp->query("//guest[@start<".$Start_0."]/@xml:id"); | |
72 | - | |
73 | - if ($startTimes->length > 0) { | |
98 | + sort($idList); | |
99 | + for ($i = 0; $i < $elements->length; $i++) { | |
100 | + if ($idList[$i] > $i) { | |
101 | + $newID = $i; | |
102 | + break; | |
103 | + } | |
104 | + $newID = $i+1; | |
105 | + } | |
106 | + } else { $newID = 0;} | |
107 | + | |
108 | + return $newID; | |
109 | + } | |
110 | + | |
111 | + private function _checkGuestTimes($dom){ | |
112 | + $xp = new DOMXpath($dom); | |
113 | + $Start_0 = time() - GuestSessionDuration*60; // in secs | |
114 | + $startTimes = $xp->query("//guest[@start<".$Start_0."]/@xml:id"); | |
115 | + | |
116 | + if ($startTimes->length > 0) { | |
74 | 117 | for ($i = 0; $i < $startTimes->length; $i++) { |
75 | - $user = "guest".$startTimes->item($i)->value; | |
76 | - $this->deltree(USERPATH.$user); | |
77 | - $this->root->removeChild($startTimes->item($i)->parentNode); | |
118 | + $user = "guest".$startTimes->item($i)->value; | |
119 | + $this->_deltree(USERPATH.$user); | |
120 | + $dom->documentElement->removeChild($startTimes->item($i)->parentNode); | |
78 | 121 | } |
79 | - $this->xp = new domxpath($this->guestXml); | |
80 | - } | |
81 | 122 | |
123 | + return $dom->save($this->guestXmlFile); | |
124 | + } | |
125 | + return true; | |
82 | 126 | } |
83 | 127 | |
84 | - public function deleteGuest(){ | |
85 | - | |
86 | - $user = "guest".$this->Id; | |
87 | - $this->deltree(USERPATH.$user); | |
88 | - $theGuest = $this->guestXml->getElementById($this->Id); | |
89 | - $this->root->removeChild($theGuest); | |
90 | - $this->guestXml->save($this->guestXmlFile); | |
91 | - | |
92 | - } | |
128 | + private function _deleteGuest($dom){ | |
129 | + $user = "guest".$this->Id; | |
130 | + $this->_deltree(USERPATH.$user); | |
131 | + $theGuest = $dom->getElementById($this->Id); | |
132 | + $dom->documentElement->removeChild($theGuest); | |
133 | + return $dom->save($this->guestXmlFile); | |
134 | + } | |
93 | 135 | |
94 | - public function addGuest(){ | |
95 | - | |
96 | - if (($this->Id = $this->GetId()) < MaxGuests) { | |
97 | - $guest = $this->guestXml->createElement("guest"); | |
98 | - $guest->setAttribute('xml:id',$this->Id ); | |
99 | - $guest->setAttribute('start',time()); | |
100 | - $guest->appendChild($this->guestXml->createElement("IP", $this->Ip)); | |
101 | - $guest->appendChild($this->guestXml->createElement("email", $this->email)); | |
102 | - $this->root->appendChild($guest); | |
103 | - $this->guestXml->save($this->guestXmlFile); | |
104 | - | |
105 | - return "guest".$this->Id; | |
106 | - } | |
107 | - else { | |
108 | - return "allGuestLoginsInUse"; | |
109 | - } | |
110 | - } | |
111 | - | |
112 | - public function registerGuest(){ | |
113 | - | |
114 | - $guest_file = fopen(DATAPATH.'guest.login','a'); | |
115 | - fwrite($guest_file, $this->email." ".$this->Ip." ".$this->Start['mday']."/".$this->Start['mon']."/".$this->Start['year']."\n"); | |
116 | - fclose($guest_file); | |
136 | + private function _addGuest($dom){ | |
137 | + if (($this->Id = $this->_getId($dom)) < MaxGuests) { | |
138 | + $guest = $dom->createElement("guest"); | |
139 | + $guest->setAttribute('xml:id',$this->Id ); | |
140 | + $guest->setAttribute('start',time()); | |
141 | + $guest->appendChild($dom->createElement("IP", $this->Ip)); | |
142 | + $guest->appendChild($dom->createElement("email", $this->email)); | |
143 | + $dom->documentElement->appendChild($guest); | |
144 | + $dom->save($this->guestXmlFile); | |
145 | + return "guest".$this->Id; | |
146 | + } | |
147 | + else { | |
148 | + return "allGuestLoginsInUse"; | |
149 | + } | |
150 | + } | |
117 | 151 | |
152 | + private function _registerGuest($dom){ | |
153 | + $guest_file = fopen(DATAPATH.'guest.login','a'); | |
154 | + fwrite($guest_file, $this->email." ".$this->Ip." ".$this->Start['mday']."/".$this->Start['mon']."/".$this->Start['year']."\n"); | |
155 | + fclose($guest_file); | |
156 | + return true; | |
118 | 157 | } |
119 | 158 | |
120 | - public function deltree($f) { | |
159 | + private function _deltree($f) { | |
121 | 160 | |
122 | 161 | if (is_dir($f)) { |
123 | 162 | |
... | ... | @@ -125,7 +164,7 @@ class Guest { |
125 | 164 | |
126 | 165 | foreach($files as $sf) { |
127 | 166 | if (is_dir("$f/$sf") && !is_link("$f/$sf")) { |
128 | - $this->deltree("$f/$sf"); | |
167 | + $this->_deltree("$f/$sf"); | |
129 | 168 | } else { |
130 | 169 | unlink("$f/$sf"); |
131 | 170 | } | ... | ... |