├── tests
├── Assets
│ ├── document.txt
│ ├── image.jpg
│ ├── voice.ogg
│ └── voice.wav
├── Telegram
│ ├── MessengerDoubler.php
│ ├── MessengerEventsTest.php
│ └── MessengerTest.php
├── HelpersTest.php
├── EventControllerTest.php
├── ScreenItems
│ ├── MessageTest.php
│ ├── VoiceTest.php
│ ├── ButtonTest.php
│ └── FileTest.php
├── RequestTest.php
├── MessengerUserTest.php
├── MessengerPoolTest.php
└── MessengerScreenTest.php
├── .bettercodehub.yml
├── src
├── Exceptions
│ ├── TargetUserException.php
│ ├── AccessTokenException.php
│ └── AttachmentNotFoundException.php
├── MessengerWithTokenInterface.php
├── MessengerEventsInterface.php
├── ScreenItems
│ ├── ScreenItemInterface.php
│ ├── Message.php
│ ├── Voice.php
│ ├── Button.php
│ └── File.php
├── Helpers.php
├── EventController.php
├── MessengerInterface.php
├── Request.php
├── MessengerUser.php
├── MessengerPool.php
├── Telegram
│ ├── MessengerEvents.php
│ └── Messenger.php
└── MessengerScreen.php
├── .gitignore
├── .travis.yml
├── phpunit.xml.dist
├── composer.json
├── LICENSE
└── README.md
/tests/Assets/document.txt:
--------------------------------------------------------------------------------
1 | Hello, world
--------------------------------------------------------------------------------
/.bettercodehub.yml:
--------------------------------------------------------------------------------
1 | component_depth: 2
2 | languages:
3 | - php
--------------------------------------------------------------------------------
/tests/Assets/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/he110/communication-tools/HEAD/tests/Assets/image.jpg
--------------------------------------------------------------------------------
/tests/Assets/voice.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/he110/communication-tools/HEAD/tests/Assets/voice.ogg
--------------------------------------------------------------------------------
/tests/Assets/voice.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/he110/communication-tools/HEAD/tests/Assets/voice.wav
--------------------------------------------------------------------------------
/src/Exceptions/TargetUserException.php:
--------------------------------------------------------------------------------
1 | ./cc-test-reporter'
8 | - 'chmod +x ./cc-test-reporter'
9 | - './cc-test-reporter before-build'
10 |
11 | after_script:
12 | - './cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT'
13 |
14 | after_success:
15 | - 'bash <(curl -s https://codecov.io/bash)'
--------------------------------------------------------------------------------
/src/MessengerWithTokenInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | tests/
7 |
8 |
9 |
10 |
11 |
12 | src/
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/Telegram/MessengerDoubler.php:
--------------------------------------------------------------------------------
1 | data = $data;
26 | return $this;
27 | }
28 |
29 | protected function getPhpInput(): string
30 | {
31 | return $this->data;
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/src/Helpers.php:
--------------------------------------------------------------------------------
1 | =7.1",
17 | "telegram-bot/api": "^2.3",
18 | "ext-curl": "*"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^8"
22 | },
23 | "autoload": {
24 | "psr-4": {"He110\\CommunicationTools\\": "src/"},
25 | "exclude-from-classmap": [
26 | "tests/"
27 | ]
28 | },
29 | "autoload-dev": {
30 | "psr-4": {"He110\\CommunicationToolsTests\\": "tests/"}
31 | },
32 | "scripts": {
33 | "test": [
34 | "phpunit"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ilya S. Zobenko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/HelpersTest.php:
--------------------------------------------------------------------------------
1 | assertCount(3, $array);
32 | $this->assertEquals($array[1], $insert);
33 |
34 | $array = [
35 | "first" => 1,
36 | "second" => 2
37 | ];
38 |
39 | Helpers::array_insert($array, "second", [$insert]);
40 |
41 | $this->assertCount(3, $array);
42 | $this->assertEquals([
43 | "first" => 1,
44 | 0 => $insert,
45 | "second" => 2
46 | ], $array);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/EventControllerTest.php:
--------------------------------------------------------------------------------
1 | addEvent("test", function () { echo "TEST"; });
23 | $another = EventController::getInstance();
24 | $this->assertEquals($eventController, $another);
25 | }
26 |
27 | /**
28 | * @covers \He110\CommunicationTools\EventController::addEvent()
29 | * @covers \He110\CommunicationTools\EventController::getEvent()
30 | */
31 | public function testAddEvent()
32 | {
33 | $controller = EventController::getInstance();
34 | $key = "telegram_onMessage";
35 | $controller->addEvent($key, function() {
36 | echo __METHOD__;
37 | });
38 |
39 | $closure = $controller->getEvent($key);
40 | $this->assertIsCallable($closure);
41 |
42 | $this->isNull($controller->getEvent("not_existed"));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/EventController.php:
--------------------------------------------------------------------------------
1 | events[$key] = $closure;
38 | }
39 |
40 | /**
41 | * @param string $key
42 | * @return \Closure|null
43 | */
44 | public function getEvent(string $key): ?\Closure
45 | {
46 | return isset($this->events[$key]) && is_callable($this->events[$key]) ? $this->events[$key] : null;
47 | }
48 |
49 | // @codeCoverageIgnoreStart
50 | private function __construct()
51 | {
52 | }
53 |
54 | private function __clone()
55 | {
56 | }
57 |
58 | private function __wakeup()
59 | {
60 | }
61 | // @codeCoverageIgnoreEnd
62 | }
--------------------------------------------------------------------------------
/src/ScreenItems/Message.php:
--------------------------------------------------------------------------------
1 | text ?? "";
23 | }
24 |
25 | /**
26 | * @param string $text
27 | * @return Message
28 | */
29 | public function setText(string $text): self
30 | {
31 | $this->text = $text;
32 | return $this;
33 | }
34 |
35 | /**
36 | * @return string
37 | */
38 | public function __toString(): string
39 | {
40 | return $this->getText();
41 | }
42 |
43 | /**
44 | * {@inheritdoc}
45 | */
46 | public function toArray(): array
47 | {
48 | return [
49 | "text" => $this->getText()
50 | ];
51 | }
52 |
53 | /**
54 | * {@inheritdoc}
55 | */
56 | public function fromArray(array $data)
57 | {
58 | foreach($data as $key=>$value) {
59 | $methodName = "set".ucfirst($key);
60 | if (method_exists($this, $methodName) && is_callable([$this, $methodName]))
61 | $this->{$methodName}($value);
62 | }
63 | return $this;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | static public function create(array $config)
70 | {
71 | $o = new Message();
72 | return $o->fromArray($config);
73 | }
74 |
75 |
76 | }
--------------------------------------------------------------------------------
/src/ScreenItems/Voice.php:
--------------------------------------------------------------------------------
1 | text ?? "";
25 | }
26 |
27 | /**
28 | * @param string $text
29 | * @return Voice
30 | */
31 | public function setText(string $text): self
32 | {
33 | $this->text = $text;
34 | return $this;
35 | }
36 |
37 | /**
38 | * @return string|null
39 | */
40 | public function getPath(): ?string
41 | {
42 | return $this->path ?? null;
43 | }
44 |
45 | /**
46 | * @param string $path
47 | * @return Voice
48 | */
49 | public function setPath(string $path): self
50 | {
51 | $this->path = $path;
52 | return $this;
53 | }
54 |
55 | /**
56 | * @return array
57 | */
58 | public function toArray(): array
59 | {
60 | return array(
61 | "path" => $this->getPath(),
62 | "text" => $this->getText()
63 | );
64 | }
65 |
66 | /**
67 | * @param array $data
68 | * @return $this
69 | */
70 | public function fromArray(array $data)
71 | {
72 | foreach($data as $key=>$value) {
73 | $methodName = "set".ucfirst($key);
74 | if (method_exists($this, $methodName) && is_callable([$this, $methodName]))
75 | $this->{$methodName}($value);
76 | }
77 | return $this;
78 | }
79 |
80 | /**
81 | * @param array $config
82 | * @return Voice
83 | */
84 | static public function create(array $config)
85 | {
86 | return (new Voice())->fromArray($config);
87 | }
88 |
89 | /**
90 | * @return string
91 | */
92 | public function __toString(): string
93 | {
94 | return $this->getText();
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/src/MessengerInterface.php:
--------------------------------------------------------------------------------
1 | assertEmpty($this->message->getText());
26 | $this->message->setText(__METHOD__);
27 | $this->assertEquals(__METHOD__, $this->message->getText());
28 | }
29 |
30 | /**
31 | * @covers \He110\CommunicationTools\ScreenItems\Message::fromArray()
32 | * @covers \He110\CommunicationTools\ScreenItems\Message::getText()
33 | */
34 | public function testFromArray()
35 | {
36 | $this->assertEmpty($this->message->getText());
37 | $this->message->fromArray(["text" => __METHOD__]);
38 | $this->assertEquals(__METHOD__, $this->message->getText());
39 | }
40 |
41 | /**
42 | * @covers \He110\CommunicationTools\ScreenItems\Message::create()
43 | */
44 | public function testCreate()
45 | {
46 | $ob = Message::create(["text" => __METHOD__]);
47 | $this->assertNotEquals($this->message, $ob);
48 | $this->assertEquals(Message::class, get_class($ob));
49 | $this->assertEquals(__METHOD__, $ob->getText());
50 | }
51 |
52 | /**
53 | * @covers \He110\CommunicationTools\ScreenItems\Message::__toString()
54 | */
55 | public function test__toString()
56 | {
57 | $this->assertEmpty((string)$this->message);
58 | $this->message->setText(__METHOD__);
59 | $this->assertEquals(__METHOD__, (string)$this->message);
60 | }
61 |
62 | /**
63 | * @covers \He110\CommunicationTools\ScreenItems\Message::toArray()
64 | */
65 | public function testToArray()
66 | {
67 | $this->message->setText(__METHOD__);
68 | $this->assertArrayHasKey("text", $this->message->toArray());
69 | $this->assertEquals(__METHOD__, $this->message->toArray()["text"]);
70 | }
71 |
72 | public function setUp(): void
73 | {
74 | $this->message = new Message();
75 | }
76 |
77 | public function tearDown(): void
78 | {
79 | $this->message = null;
80 | unset($this->message);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Request.php:
--------------------------------------------------------------------------------
1 | user;
39 | }
40 |
41 | /**
42 | * @param MessengerUser|null $user
43 | * @return Request
44 | */
45 | public function setUser(?MessengerUser $user): self
46 | {
47 | $this->user = $user;
48 | return $this;
49 | }
50 |
51 |
52 |
53 | /**
54 | * @return string|null
55 | */
56 | public function getType(): ?string
57 | {
58 | return $this->type;
59 | }
60 |
61 | /**
62 | * @param string $type
63 | * @return Request
64 | */
65 | public function setType(string $type): self
66 | {
67 | $this->type = $type;
68 | return $this;
69 | }
70 |
71 | /**
72 | * @return string
73 | */
74 | public function getMessage(): string
75 | {
76 | return $this->message ?? "";
77 | }
78 |
79 | /**
80 | * @param string $message
81 | * @return Request
82 | */
83 | public function setMessage(string $message): self
84 | {
85 | $this->message = $message;
86 | return $this;
87 | }
88 |
89 | /**
90 | * @return string|null
91 | */
92 | public function getPath(): ?string
93 | {
94 | return $this->path;
95 | }
96 |
97 | /**
98 | * @param string $path
99 | * @return Request
100 | */
101 | public function setPath(string $path): self
102 | {
103 | $this->path = $path;
104 | return $this;
105 | }
106 |
107 | /**
108 | * @return null|string
109 | */
110 | public function getPayload(): ?string
111 | {
112 | return $this->payload;
113 | }
114 |
115 | /**
116 | * @param null|string $payload
117 | * @return Request
118 | */
119 | public function setPayload(?string $payload): self
120 | {
121 | $this->payload = $payload;
122 | return $this;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/tests/RequestTest.php:
--------------------------------------------------------------------------------
1 | assertNull($this->request->getPath());
27 | $this->request->setPath(__METHOD__);
28 | $this->assertEquals(__METHOD__, $this->request->getPath());
29 | }
30 |
31 | /**
32 | * @covers \He110\CommunicationTools\Request::setUser()
33 | * @covers \He110\CommunicationTools\Request::getUser()
34 | */
35 | public function testSetUser()
36 | {
37 | $this->assertNull($this->request->getUser());
38 | $user = new MessengerUser();
39 | $user->setFirstName("Ivan");
40 | $user->setLastName("Ivanov");
41 | $this->request->setUser($user);
42 | $this->assertEquals($user, $this->request->getUser());
43 | $this->assertEquals("Ivan Ivanov", (string)$this->request->getUser());
44 | }
45 |
46 | /**
47 | * @covers \He110\CommunicationTools\Request::setType()
48 | * @covers \He110\CommunicationTools\Request::getType()
49 | */
50 | public function testSetType()
51 | {
52 | $this->assertNull($this->request->getType());
53 | $this->request->setType(__METHOD__);
54 | $this->assertEquals(__METHOD__, $this->request->getType());
55 | }
56 |
57 | /**
58 | * @covers \He110\CommunicationTools\Request::setMessage()
59 | * @covers \He110\CommunicationTools\Request::getMessage()
60 | */
61 | public function testSetMessage()
62 | {
63 | $this->assertEmpty($this->request->getMessage());
64 | $this->request->setMessage(__METHOD__);
65 | $this->assertEquals(__METHOD__, $this->request->getMessage());
66 | }
67 |
68 | /**
69 | * @covers \He110\CommunicationTools\Request::setPayload()
70 | * @covers \He110\CommunicationTools\Request::getPayload()
71 | */
72 | public function testSetPayload()
73 | {
74 | $this->assertEmpty($this->request->getPayload());
75 | $this->request->setPayload(__METHOD__);
76 | $this->assertEquals(__METHOD__, $this->request->getPayload());
77 | }
78 |
79 | public function setUp(): void
80 | {
81 | $this->request = new Request();
82 | }
83 |
84 | public function tearDown(): void
85 | {
86 | $this->request = null;
87 | unset($this->request);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/tests/ScreenItems/VoiceTest.php:
--------------------------------------------------------------------------------
1 | assertNull($this->voice->getPath());
33 | $this->voice->setPath(static::VOICE_OGG);
34 | $this->assertEquals(static::VOICE_OGG, $this->voice->getPath());
35 | }
36 |
37 | /**
38 | * @covers \He110\CommunicationTools\ScreenItems\Voice::toArray()
39 | * @covers \He110\CommunicationTools\ScreenItems\Voice::setPath()
40 | */
41 | public function testToArray()
42 | {
43 | $this->voice->setPath(static::VOICE_OGG);
44 | $this->assertCount(2, $this->voice->toArray());
45 | $this->assertArrayHasKey("path", $this->voice->toArray());
46 | $this->assertArrayHasKey("text", $this->voice->toArray());
47 | }
48 |
49 | /**
50 | * @covers \He110\CommunicationTools\ScreenItems\Voice::create()
51 | * @covers \He110\CommunicationTools\ScreenItems\Voice::fromArray()
52 | */
53 | public function testCreate()
54 | {
55 | $ob = Voice::create(["path" => static::VOICE_OGG]);
56 | $this->assertNotEquals($this->voice, $ob);
57 | $this->assertEquals(Voice::class, get_class($ob));
58 | $this->assertEquals(static::VOICE_OGG, $ob->getPath());
59 | }
60 |
61 | /**
62 | * @covers \He110\CommunicationTools\ScreenItems\Voice::__toString()
63 | * @covers \He110\CommunicationTools\ScreenItems\Voice::getText()
64 | * @covers \He110\CommunicationTools\ScreenItems\Voice::setText()
65 | */
66 | public function testGetText()
67 | {
68 | $this->assertEmpty($this->voice->getText());
69 | $this->voice->setPath("non_existed.file");
70 | try {
71 | $this->voice->getText();
72 | } catch (\Exception $e) {
73 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
74 | }
75 | $this->voice->setPath(static::VOICE_OGG);
76 | $this->voice->setText("Some text");
77 | $this->assertEquals((string)$this->voice, $this->voice->getText());
78 | }
79 |
80 | public function setUp(): void
81 | {
82 | $this->voice = new Voice();
83 | }
84 |
85 | public function tearDown(): void
86 | {
87 | $this->voice = null;
88 | unset($this->voice);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/MessengerUser.php:
--------------------------------------------------------------------------------
1 | userId;
35 | }
36 |
37 | /**
38 | * @param null|string $userId
39 | * @return MessengerUser
40 | */
41 | public function setUserId(?string $userId): self
42 | {
43 | $this->userId = $userId;
44 | return $this;
45 | }
46 |
47 | /**
48 | * @return null|string
49 | */
50 | public function getFirstName(): ?string
51 | {
52 | return $this->firstName;
53 | }
54 |
55 | /**
56 | * @param null|string $firstName
57 | * @return MessengerUser
58 | */
59 | public function setFirstName(?string $firstName): self
60 | {
61 | $this->firstName = $firstName;
62 | return $this;
63 | }
64 |
65 | /**
66 | * @return null|string
67 | */
68 | public function getLastName(): ?string
69 | {
70 | return $this->lastName;
71 | }
72 |
73 | /**
74 | * @param null|string $lastName
75 | * @return MessengerUser
76 | */
77 | public function setLastName(?string $lastName): self
78 | {
79 | $this->lastName = $lastName;
80 | return $this;
81 | }
82 |
83 | /**
84 | * @return null|string
85 | */
86 | public function getUsername(): ?string
87 | {
88 | return $this->username;
89 | }
90 |
91 | /**
92 | * @param null|string $username
93 | * @return MessengerUser
94 | */
95 | public function setUsername(?string $username): self
96 | {
97 | $this->username = $username;
98 | return $this;
99 | }
100 |
101 | /**
102 | * @return null|string
103 | */
104 | public function getLanguageCode(): ?string
105 | {
106 | return $this->languageCode;
107 | }
108 |
109 | /**
110 | * @param null|string $languageCode
111 | * @return MessengerUser
112 | */
113 | public function setLanguageCode(?string $languageCode): self
114 | {
115 | $this->languageCode = $languageCode;
116 | return $this;
117 | }
118 |
119 | /**
120 | * @return string
121 | */
122 | public function getFullName(): string
123 | {
124 | $firstName = $this->getFirstName() ?? "";
125 | $lastName = $this->getLastName() ?? "";
126 | $fullName = trim("$firstName $lastName");
127 | return str_replace(" ", " ", $fullName);
128 | }
129 |
130 | /**
131 | * @return string
132 | */
133 | public function __toString(): string
134 | {
135 | return $this->getFullName();
136 | }
137 |
138 | }
--------------------------------------------------------------------------------
/src/ScreenItems/Button.php:
--------------------------------------------------------------------------------
1 | label ?? "";
33 | }
34 |
35 | /**
36 | * @param string $label
37 | * @return Button
38 | */
39 | public function setLabel(string $label): self
40 | {
41 | $this->label = $label;
42 | return $this;
43 | }
44 |
45 | /**
46 | * @return string
47 | */
48 | public function getContent()
49 | {
50 | return $this->content;
51 | }
52 |
53 | /**
54 | * @param string $content
55 | * @return Button
56 | */
57 | public function setContent($content): self
58 | {
59 | $this->content = $content;
60 | return $this;
61 | }
62 |
63 | /**
64 | * @return string
65 | */
66 | public function getType(): string
67 | {
68 | return $this->type ?? static::BUTTON_TYPE_TEXT;
69 | }
70 |
71 | /**
72 | * @param string $type
73 | * @return Button
74 | */
75 | public function setType(string $type): self
76 | {
77 | $this->type = $type;
78 | return $this;
79 | }
80 |
81 | /**
82 | * {@inheritdoc}
83 | */
84 | public function toArray(): array
85 | {
86 | switch ($this->getType()) {
87 | case static::BUTTON_TYPE_CALLBACK:
88 | $key = "callback";
89 | break;
90 | case static::BUTTON_TYPE_URL:
91 | $key = "url";
92 | break;
93 | default:
94 | $key = null;
95 | break;
96 | }
97 | $result = [
98 | "type" => $this->getType(),
99 | "label" => $this->getLabel()
100 | ];
101 | if (!is_null($key))
102 | $result[$key] = $result["content"] = $this->getContent();
103 | return $result;
104 | }
105 |
106 | /**
107 | * {@inheritdoc}
108 | */
109 | public function fromArray(array $data)
110 | {
111 | foreach($data as $key=>$value) {
112 | $methodName = "set".ucfirst($key);
113 | if (method_exists($this, $methodName) && is_callable([$this, $methodName]))
114 | $this->{$methodName}($value);
115 | }
116 | return $this;
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | static public function create(array $config): self
123 | {
124 | $ob = new Button();
125 | return $ob->fromArray($config);
126 | }
127 |
128 | /**
129 | * @return string
130 | */
131 | public function __toString(): string
132 | {
133 | return $this->getLabel();
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/tests/MessengerUserTest.php:
--------------------------------------------------------------------------------
1 | assertNull($this->user->getUserId());
26 | $this->user->setUserId(__METHOD__);
27 | $this->assertEquals(__METHOD__, $this->user->getUserId());
28 | }
29 |
30 | /**
31 | * @covers \He110\CommunicationTools\MessengerUser::setLanguageCode()
32 | * @covers \He110\CommunicationTools\MessengerUser::getLanguageCode()
33 | */
34 | public function testSetLanguageCode()
35 | {
36 | $this->assertNull($this->user->getLanguageCode());
37 | $this->user->setLanguageCode("en");
38 | $this->assertEquals("en", $this->user->getLanguageCode());
39 | }
40 |
41 | /**
42 | * @covers \He110\CommunicationTools\MessengerUser::getFirstName()
43 | * @covers \He110\CommunicationTools\MessengerUser::setFirstName()
44 | */
45 | public function testSetFirstName()
46 | {
47 | $this->assertNull($this->user->getFirstName());
48 | $this->user->setFirstName(__METHOD__);
49 | $this->assertEquals(__METHOD__, $this->user->getFirstName());
50 | }
51 |
52 | /**
53 | * @covers \He110\CommunicationTools\MessengerUser::setLastName()
54 | * @covers \He110\CommunicationTools\MessengerUser::getLastName()
55 | */
56 | public function testSetLastName()
57 | {
58 | $this->assertNull($this->user->getLastName());
59 | $this->user->setLastName(__METHOD__);
60 | $this->assertEquals(__METHOD__, $this->user->getLastName());
61 | }
62 |
63 | /**
64 | * @covers \He110\CommunicationTools\MessengerUser::setUsername()
65 | * @covers \He110\CommunicationTools\MessengerUser::getUsername()
66 | */
67 | public function testSetUsername()
68 | {
69 | $this->assertNull($this->user->getUsername());
70 | $this->user->setUsername(__METHOD__);
71 | $this->assertEquals(__METHOD__, $this->user->getUsername());
72 | }
73 |
74 | /**
75 | * @covers \He110\CommunicationTools\MessengerUser::getFullName()
76 | * @covers \He110\CommunicationTools\MessengerUser::getFirstName()
77 | * @covers \He110\CommunicationTools\MessengerUser::getLastName()
78 | * @covers \He110\CommunicationTools\MessengerUser::setFirstName()
79 | * @covers \He110\CommunicationTools\MessengerUser::setLastName()
80 | * @covers \He110\CommunicationTools\MessengerUser::__toString()
81 | */
82 | public function testGetFullName()
83 | {
84 | $this->user->setFirstName("Ivan");
85 | $this->user->setLastName("Ivanov");
86 | $this->assertEquals("Ivan Ivanov", (string)$this->user);
87 | }
88 |
89 | public function setUp(): void
90 | {
91 | $this->user = new MessengerUser();
92 | }
93 |
94 | public function tearDown(): void
95 | {
96 | $this->user = null;
97 | unset($this->user);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Communication Tools [](https://travis-ci.com/he110/communication-tools)
2 |
3 | [](https://packagist.org/packages/he110/communication-tools) [](https://codecov.io/gh/he110/communication-tools) [](https://codeclimate.com/github/he110/communication-tools/maintainability)
4 |
5 | Tools set for messenger managing. Allows you to send any content via Telegram, Viber, WhatsApp, VK, Facebook Messenger and so on.
6 |
7 | ## Installation
8 |
9 | Install the latest version with
10 |
11 | ```bash
12 | $ composer require he110/communication-tools
13 | ```
14 |
15 | ## Basic Usage
16 |
17 | ### Messenger's clients
18 | ```php
19 | setAccessToken(YOUR_TOKEN_HERE);
27 |
28 | // If you want, to send simple text message
29 | $messenger->sendMessage("Your message text here");
30 |
31 | // To send image use method sendImage
32 | $messenger->sendImage("path/to/file", "(Optional) Your text description");
33 | // or, to send document...
34 | $messenger->sendDocument("path/to/file", "(Optional) Your text description");
35 | // you can also send voice files
36 | $messenger->sendVoice("path/to/file");
37 |
38 | // If you wanna use buttons, it's better way to use MessengerScreen
39 | $screen = new MessengerScreen();
40 | $screen->addMessage("Your message text here");
41 | $screen->addButtonText("Text button");
42 | $screen->addButtonLink("URL button", "https://google.com");
43 | $messenger->sendScreen($screen);
44 |
45 | ```
46 |
47 | ### Multiple messengers
48 | ```php
49 | setAccessToken(YOUR_TOKEN_HERE);
58 |
59 | // Pool allows you to use multiple messengers as one
60 | $pool = new MessengerPool();
61 | $pool->add($messenger);
62 |
63 | $pool->sendMessage("Your message text here");
64 |
65 | // If you wanna use buttons, it's better way to use MessengerScreen
66 | $screen = new MessengerScreen();
67 | $screen->addMessage("Your message text here");
68 | $screen->addButtonText("Text button");
69 | $screen->addButtonLink("URL button", "https://google.com");
70 | $pool->sendScreen($screen);
71 |
72 | ```
73 |
74 |
75 | ### Work with events
76 | ```php
77 | setAccessToken(YOUR_TOKEN_HERE);
86 |
87 | // Action for simple incoming messages
88 | $messenger->onMessage(function(Request $request) use ($messenger) {
89 | // Your code here...
90 | $text = $request->getMessage();
91 | /** @var MessengerUser $user $user */
92 | $user = $request->getUser();
93 | $messenger->setTargetUser($user->getUserId());
94 | $messenger->sendMessage("We've got your message: '$text'");
95 | });
96 |
97 | // Action for buttons click
98 | $messenger->onButtonClick(function(Request $request) use ($messenger) {
99 | // Your code here...
100 | $payload = $request->getPayload();
101 | });
102 |
103 | // Required!!! Run this method to check if events are triggered
104 | $messenger->checkEvents();
105 |
106 | ```
107 |
108 | ## About
109 |
110 | ### Requirements
111 |
112 | - Communication Tools works with PHP 7.2 or above.
113 |
114 | ### Submitting bugs and feature requests
115 |
116 | Bugs and feature request are tracked on [GitHub](https://github.com/he110/communication-tools/issues)
117 |
118 | ### Author
119 |
120 | Ilya S. Zobenko - -
121 |
122 | ### License
123 |
124 | "Communication Tools" is licensed under the MIT License - see the `LICENSE` file for detail
125 |
--------------------------------------------------------------------------------
/src/ScreenItems/File.php:
--------------------------------------------------------------------------------
1 | path ?? null;
38 | }
39 |
40 | /**
41 | * @param string $path
42 | * @return File
43 | */
44 | public function setPath(string $path): self
45 | {
46 | if (file_exists($path)) {
47 | $this->setSize(filesize($path));
48 | if (is_null($this->getName()))
49 | $this->setName(basename($path));
50 | if (is_null($this->getType()))
51 | $this->setType($this->isImage($path) ? static::FILE_TYPE_IMAGE : static::FILE_TYPE_DOCUMENT);
52 | }
53 | $this->path = $path;
54 | return $this;
55 | }
56 |
57 | /**
58 | * @return string|null
59 | */
60 | public function getName(): ?string
61 | {
62 | return $this->name ?? null;
63 | }
64 |
65 | /**
66 | * @param string $name
67 | */
68 | public function setName(string $name): void
69 | {
70 | $this->name = $name;
71 | }
72 |
73 | /**
74 | * @return string
75 | */
76 | public function getType(): ?string
77 | {
78 | return $this->type ?? null;
79 | }
80 |
81 | /**
82 | * @param string $type
83 | */
84 | public function setType(string $type): void
85 | {
86 | $this->type = $type;
87 | }
88 |
89 | /**
90 | * @return int
91 | */
92 | public function getSize(): int
93 | {
94 | return $this->size ?? 0;
95 | }
96 |
97 | /**
98 | * @param int $size
99 | */
100 | private function setSize(int $size): void
101 | {
102 | $this->size = $size;
103 | }
104 |
105 | /**
106 | * @return string
107 | */
108 | public function getDescription(): string
109 | {
110 | return $this->description ?? "";
111 | }
112 |
113 | /**
114 | * @param string $description
115 | * @return File
116 | */
117 | public function setDescription(string $description): self
118 | {
119 | $this->description = $description;
120 | return $this;
121 | }
122 |
123 |
124 | /**
125 | * {@inheritdoc}
126 | */
127 | public function toArray(): array
128 | {
129 | return array(
130 | "path" => $this->getPath(),
131 | "name" => $this->getName(),
132 | "size" => $this->getSize(),
133 | "type" => $this->getType(),
134 | "description" => $this->getDescription()
135 | );
136 | }
137 |
138 | /**
139 | * {@inheritdoc}
140 | */
141 | public function fromArray(array $data)
142 | {
143 | if (isset($data["path"]))
144 | $this->setPath($data["path"]);
145 | foreach($data as $key=>$value) {
146 | $methodName = "set".ucfirst($key);
147 | if (method_exists($this, $methodName) && is_callable([$this, $methodName]))
148 | $this->{$methodName}($value);
149 | }
150 | return $this;
151 | }
152 |
153 | /**
154 | * {@inheritdoc}
155 | */
156 | static public function create(array $config)
157 | {
158 | return (new File())->fromArray($config);
159 | }
160 |
161 | /**
162 | * @return null|string
163 | */
164 | public function __toString(): string
165 | {
166 | return $this->getName();
167 | }
168 |
169 | /**
170 | * @param $path
171 | * @return bool
172 | */
173 | private function isImage($path): bool
174 | {
175 | $a = getimagesize($path);
176 | $imageType = $a[2];
177 |
178 | if (in_array($imageType , array(IMAGETYPE_GIF , IMAGETYPE_JPEG ,IMAGETYPE_PNG , IMAGETYPE_BMP)))
179 | return true;
180 | return false;
181 | }
182 | }
--------------------------------------------------------------------------------
/src/MessengerPool.php:
--------------------------------------------------------------------------------
1 | getTargetUser();
27 | if (!in_array($messenger, $this->messengers))
28 | array_push($this->messengers, $messenger);
29 |
30 | if ($targetUserId !== "")
31 | $this->setTargetUser($targetUserId);
32 | elseif ($targetUserId === "" && !empty($messenger->getTargetUser()))
33 | $this->setTargetUser($messenger->getTargetUser());
34 |
35 | return $this;
36 | }
37 |
38 | /**
39 | * Find key of specific messenger
40 | *
41 | * @param MessengerInterface $messenger
42 | * @return int
43 | */
44 | public function indexOf(MessengerInterface $messenger): int
45 | {
46 | $key = array_search($messenger, $this->messengers);
47 | if ($key === false)
48 | $key = -1;
49 | return $key;
50 | }
51 |
52 | /**
53 | * Removes messenger from collection by it's Key
54 | *
55 | * @param int $key
56 | * @return MessengerPool
57 | */
58 | public function removeByKey(int $key): self
59 | {
60 | unset($this->messengers[$key]);
61 | return $this;
62 | }
63 |
64 | /**
65 | * Removes messenger from collection
66 | *
67 | * @param MessengerInterface $messenger
68 | * @return MessengerPool
69 | */
70 | public function remove(MessengerInterface $messenger): self
71 | {
72 | if (0 <= $key = $this->indexOf($messenger))
73 | $this->removeByKey($key);
74 | return $this;
75 | }
76 |
77 | /**
78 | * Returns all added messengers from collection
79 | *
80 | * @return MessengerInterface[]
81 | */
82 | public function getList(): array
83 | {
84 | return $this->messengers;
85 | }
86 |
87 | /**
88 | * {@inheritdoc}
89 | */
90 | public function setTargetUser(?string $userId)
91 | {
92 | foreach ($this->messengers as $messenger)
93 | $messenger->setTargetUser($userId);
94 | return $this;
95 | }
96 |
97 | /**
98 | * {@inheritdoc}
99 | */
100 | public function getTargetUser(): ?string
101 | {
102 | $messenger = reset($this->messengers);
103 | if ($messenger === false)
104 | return "";
105 | return $messenger->getTargetUser();
106 | }
107 |
108 | /**
109 | * {@inheritdoc}
110 | */
111 | public function sendMessage(string $text, array $buttons = []): bool
112 | {
113 | $result = true;
114 | foreach ($this->messengers as $messenger)
115 | $result = $messenger->sendMessage($text, $buttons) && $result;
116 | return $result;
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | public function sendImage(string $pathToFile, string $description = null, array $buttons = []): bool
123 | {
124 | $result = true;
125 | foreach ($this->messengers as $messenger)
126 | $result = $messenger->sendImage($pathToFile, $description, $buttons) && $result;
127 | return $result;
128 | }
129 |
130 | /**
131 | * {@inheritdoc}
132 | */
133 | public function sendDocument(string $pathToFile, string $description = null, array $buttons = []): bool
134 | {
135 | $result = true;
136 | foreach ($this->messengers as $messenger)
137 | $result = $messenger->sendDocument($pathToFile, $description, $buttons) && $result;
138 | return $result;
139 | }
140 |
141 | /**
142 | * {@inheritdoc}
143 | */
144 | public function sendVoice(string $pathToFile): bool
145 | {
146 | $result = true;
147 | foreach ($this->messengers as $messenger)
148 | $result = $messenger->sendVoice($pathToFile) && $result;
149 | return $result;
150 | }
151 |
152 | /**
153 | * {@inheritdoc}
154 | */
155 | public function sendScreen(MessengerScreen $screen): bool
156 | {
157 | $result = true;
158 | foreach ($this->messengers as $messenger)
159 | $result = $messenger->sendScreen($screen) && $result;
160 | return $result;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/tests/ScreenItems/ButtonTest.php:
--------------------------------------------------------------------------------
1 | assertEmpty($this->button->getLabel());
27 | $this->assertEmpty((string)$this->button);
28 | $this->button->setLabel(__METHOD__);
29 | $this->assertEquals(__METHOD__, $this->button->getLabel());
30 | $this->assertEquals((string)$this->button, $this->button->getLabel());
31 | }
32 |
33 | /**
34 | * @covers \He110\CommunicationTools\ScreenItems\Button::setContent()
35 | * @covers \He110\CommunicationTools\ScreenItems\Button::getContent()
36 | */
37 | public function testGetContent()
38 | {
39 | $this->assertEmpty($this->button->getContent());
40 | $this->button->setContent("empty one");
41 | $this->assertEquals("empty one", $this->button->getContent());
42 | }
43 |
44 | /**
45 | * @covers \He110\CommunicationTools\ScreenItems\Button::toArray()
46 | * @covers \He110\CommunicationTools\ScreenItems\Button::fromArray()
47 | */
48 | public function testToArray()
49 | {
50 | $this->button->fromArray([
51 | "label" => __METHOD__,
52 | "type" => Button::BUTTON_TYPE_URL,
53 | "content" => "https://ya.ru"
54 | ]);
55 |
56 | $result = $this->button->toArray();
57 | $this->assertArrayHasKey("label", $result);
58 | $this->assertArrayHasKey("type", $result);
59 | $this->assertArrayHasKey("content", $result);
60 | $this->assertArrayHasKey("url", $result);
61 |
62 | $this->button->setType(Button::BUTTON_TYPE_TEXT);
63 | $this->assertArrayNotHasKey("content", $this->button->toArray());
64 | $this->assertArrayNotHasKey("url", $this->button->toArray());
65 |
66 | $this->button->fromArray([
67 | "type" => Button::BUTTON_TYPE_CALLBACK,
68 | "content" => function($a) { echo __METHOD__; }
69 | ]);
70 |
71 | $this->assertArrayHasKey("content", $this->button->toArray());
72 | $this->assertArrayHasKey("callback", $this->button->toArray());
73 | $this->assertIsCallable($this->button->getContent());
74 | }
75 |
76 | /**
77 | * @dataProvider fromArrayProvider
78 | *
79 | * @covers \He110\CommunicationTools\ScreenItems\Button::fromArray()
80 | * @covers \He110\CommunicationTools\ScreenItems\Button::getLabel()
81 | * @covers \He110\CommunicationTools\ScreenItems\Button::getType()
82 | * @covers \He110\CommunicationTools\ScreenItems\Button::getContent()
83 | */
84 | public function testFromArray(string $type, $content)
85 | {
86 | $config = [
87 | "label" => __METHOD__,
88 | "type" => $type
89 | ];
90 | if ($type !== Button::BUTTON_TYPE_TEXT)
91 | $config["content"] = $content;
92 | $this->button->fromArray($config);
93 |
94 | $this->assertEquals(__METHOD__, $this->button->getLabel());
95 | $this->assertEquals($type, $this->button->getType());
96 | if ($type !== Button::BUTTON_TYPE_TEXT)
97 | $this->assertEquals($content, $this->button->getContent());
98 |
99 | if ($type === Button::BUTTON_TYPE_CALLBACK && is_callable($content))
100 | $this->assertIsCallable($this->button->getContent());
101 | }
102 |
103 | public function fromArrayProvider()
104 | {
105 | return array(
106 | array(Button::BUTTON_TYPE_TEXT, null),
107 | array(Button::BUTTON_TYPE_URL, "https://ya.ru"),
108 | array(Button::BUTTON_TYPE_CALLBACK, function($a) { echo __METHOD__; }),
109 | );
110 | }
111 |
112 | /**
113 | * @covers \He110\CommunicationTools\ScreenItems\Button::create()
114 | */
115 | public function testCreate()
116 | {
117 | $ob = Button::create(["label" => __METHOD__]);
118 | $this->assertNotEquals($this->button, $ob);
119 | $this->assertEquals(Button::class, get_class($ob));
120 | $this->assertEquals(__METHOD__, $ob->getLabel());
121 | }
122 |
123 | /**
124 | * @covers \He110\CommunicationTools\ScreenItems\Button::setType()
125 | * @covers \He110\CommunicationTools\ScreenItems\Button::getType()
126 | */
127 | public function testSetType()
128 | {
129 | $this->assertEquals(Button::BUTTON_TYPE_TEXT, $this->button->getType());
130 | $this->button->setType(Button::BUTTON_TYPE_URL);
131 | $this->assertEquals(Button::BUTTON_TYPE_URL, $this->button->getType());
132 | }
133 |
134 | public function setUp(): void
135 | {
136 | $this->button = new Button();
137 | }
138 |
139 | public function tearDown(): void
140 | {
141 | $this->button = null;
142 | unset($this->button);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/Telegram/MessengerEvents.php:
--------------------------------------------------------------------------------
1 | addEvent(Request::REQUEST_TYPE_MESSAGE, $closure);
26 | }
27 |
28 | /**
29 | * {@inheritdoc}
30 | *
31 | * @codeCoverageIgnoreStart
32 | */
33 | public function onMessageRead(\Closure $closure)
34 | {
35 |
36 | // TODO: Найти способ получить такой event
37 | $this->addEvent(Request::REQUEST_TYPE_MESSAGE_READ, $closure);
38 | }
39 | /** @codeCoverageIgnoreEnd */
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | public function onButtonClick(\Closure $closure)
45 | {
46 | $this->addEvent(Request::REQUEST_TYPE_BUTTON_CLICK, $closure);
47 | }
48 |
49 | /**
50 | * @param string $type
51 | * @param \Closure $closure
52 | */
53 | private function addEvent(string $type, \Closure $closure): void
54 | {
55 | $key = spl_object_hash($this)."_".$type;
56 | EventController::getInstance()->addEvent($key, $closure);
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | */
62 | public function checkEvents(): void
63 | {
64 | $request = $this->getRequest();
65 | if ($request->getType()) {
66 | $key = spl_object_hash($this) . "_" . $request->getType();
67 | if ($closure = EventController::getInstance()->getEvent($key))
68 | $closure($request);
69 | }
70 | }
71 |
72 | /**
73 | * {@inheritdoc}
74 | */
75 | public function getRequest(): Request
76 | {
77 | $request = new Request();
78 | if ($data = json_decode($this->getPhpInput(), true)) {
79 |
80 | if (isset($data["message"]))
81 | $request = $this->buildMessageRequest($request, $data["message"]);
82 |
83 | elseif (isset($data["callback_query"]))
84 | $request = $this->buildButtonClickRequest($request, $data["callback_query"]);
85 | }
86 | return $request;
87 | }
88 |
89 | /**
90 | * @param Request $request
91 | * @param array $data
92 | * @return Request
93 | */
94 | private function buildMessageRequest(Request &$request, array $data): Request
95 | {
96 | $data['from']['id'] = $data['chat']['id'];
97 | $this->setUserFromRequest($request, $data["from"]);
98 |
99 | if (isset($data["text"])) {
100 | $request->setType(Request::REQUEST_TYPE_MESSAGE);
101 | $request->setMessage($data["text"]);
102 | }
103 | return $request;
104 | }
105 |
106 | /**
107 | * @param Request $request
108 | * @param array $data
109 | * @return Request
110 | */
111 | private function buildButtonClickRequest(Request &$request, array $data): Request
112 | {
113 | $this->setUserFromRequest($request, $data["from"]);
114 | if (isset($data["data"])) {
115 | $request->setType(Request::REQUEST_TYPE_BUTTON_CLICK);
116 | $payload = "";
117 | $type = $this->detectPayloadType($data["data"],$payload);
118 | switch ($type) {
119 | case Button::BUTTON_TYPE_CALLBACK:
120 | $request->setPayload($payload);
121 | break;
122 | default:
123 | $request->setMessage($payload);
124 | break;
125 | }
126 | }
127 | return $request;
128 | }
129 |
130 | /**
131 | * @param string|null $payload
132 | * @param null $data
133 | * @return string
134 | */
135 | private function detectPayloadType(string $payload, &$data = null): ?string
136 | {
137 | if (substr($payload, 0, 4) === "clb=") {
138 | $data = substr($payload, 4);
139 | return Button::BUTTON_TYPE_CALLBACK;
140 | } elseif (substr($payload, 0, 5) === "text=") {
141 | $data = substr($payload, 5);
142 | return Button::BUTTON_TYPE_TEXT;
143 | } else {
144 | return null;
145 | }
146 | }
147 |
148 | /**
149 | * @param Request $request
150 | * @param array $from
151 | */
152 | private function setUserFromRequest(Request &$request, array $from): void
153 | {
154 | $user = new MessengerUser();
155 | $user->setFirstName($from["first_name"])
156 | ->setLastName($from["last_name"])
157 | ->setUsername($from["username"])
158 | ->setUserId($from['id'])
159 | ->setLanguageCode($from["language_code"]);
160 | $request->setUser($user);
161 | }
162 |
163 | /**
164 | * @return string
165 | *
166 | * @codeCoverageIgnoreStart
167 | */
168 | protected function getPhpInput(): string
169 | {
170 | return file_get_contents("php://input");
171 | }
172 |
173 | /** @codeCoverageIgnoreEnd */
174 | }
--------------------------------------------------------------------------------
/tests/ScreenItems/FileTest.php:
--------------------------------------------------------------------------------
1 | file->setPath(static::IMAGE_PATH);
37 | $this->assertEquals(static::IMAGE_PATH, $this->file->getPath());
38 | $this->assertEquals("image.jpg", $this->file->getName());
39 | $this->assertEquals(File::FILE_TYPE_IMAGE, $this->file->getType());
40 | }
41 |
42 | /**
43 | * @covers \He110\CommunicationTools\ScreenItems\File::fromArray()
44 | * @covers \He110\CommunicationTools\ScreenItems\File::toArray()
45 | */
46 | public function testToArray()
47 | {
48 | $conf = [
49 | "path" => static::IMAGE_PATH,
50 | "name" => __METHOD__
51 | ];
52 | $this->file->fromArray($conf);
53 | $this->assertEquals($conf["path"], $this->file->getPath());
54 | $this->assertEquals($conf["name"], $this->file->getName());
55 |
56 | $new = $this->file->toArray();
57 | $this->assertArrayHasKey("path", $new);
58 | $this->assertArrayHasKey("name", $new);
59 | $this->assertArrayHasKey("size", $new);
60 | $this->assertArrayHasKey("type", $new);
61 | $this->assertArrayHasKey("description", $new);
62 |
63 | $this->assertEmpty($new["description"]);
64 |
65 | $this->assertEquals($conf["path"], $new["path"]);
66 | $this->assertEquals($conf["name"], $new["name"]);
67 | $this->assertEquals(File::FILE_TYPE_IMAGE, $new["type"]);
68 | }
69 |
70 | /**
71 | * @covers \He110\CommunicationTools\ScreenItems\File::getDescription()
72 | * @covers \He110\CommunicationTools\ScreenItems\File::setDescription()
73 | */
74 | public function testGetDescription()
75 | {
76 | $description = "TEST";
77 | $this->file->setDescription($description);
78 | $this->assertEquals($description, $this->file->getDescription());
79 | }
80 |
81 | /**
82 | * @covers \He110\CommunicationTools\ScreenItems\File::create()
83 | */
84 | public function testCreate()
85 | {
86 | $ob = File::create(["path" => static::IMAGE_PATH, "name" => __METHOD__]);
87 | $this->assertNotEquals($this->file, $ob);
88 | $this->assertEquals(File::class, get_class($ob));
89 | $this->assertEquals(__METHOD__, $ob->getName());
90 | $this->assertEquals(static::IMAGE_PATH, $ob->getPath());
91 | }
92 |
93 | /**
94 | * @covers \He110\CommunicationTools\ScreenItems\File::__toString()
95 | */
96 | public function test__toString()
97 | {
98 | $this->file->setName(__METHOD__);
99 | $this->assertEquals((string)$this->file, __METHOD__);
100 | }
101 |
102 | /**
103 | * @dataProvider getSizeProvider
104 | *
105 | * @covers \He110\CommunicationTools\ScreenItems\File::getSize()
106 | * @covers \He110\CommunicationTools\ScreenItems\File::setPath()
107 | * @covers \He110\CommunicationTools\ScreenItems\File::setSize()
108 | * @covers \He110\CommunicationTools\ScreenItems\File::isImage()
109 | */
110 | public function testGetSize(string $file, int $size, string $type)
111 | {
112 | $this->file->setPath($file);
113 | $this->assertEquals($size, $this->file->getSize());
114 | $this->assertEquals($type, $this->file->getType());
115 | }
116 |
117 | /**
118 | * @return array
119 | */
120 | public function getSizeProvider(): array
121 | {
122 | return array(
123 | array(static::IMAGE_PATH, 39481, File::FILE_TYPE_IMAGE),
124 | array(static::DOCUMENT_PATH, 12, File::FILE_TYPE_DOCUMENT)
125 | );
126 | }
127 |
128 | /**
129 | * @covers \He110\CommunicationTools\ScreenItems\File::getName()
130 | * @covers \He110\CommunicationTools\ScreenItems\File::setName()
131 | */
132 | public function testSetName()
133 | {
134 | $this->assertNull($this->file->getName());
135 | $this->file->setName(__METHOD__);
136 | $this->assertEquals(__METHOD__, $this->file->getName());
137 | }
138 |
139 | /**
140 | * @covers \He110\CommunicationTools\ScreenItems\File::getType()
141 | * @covers \He110\CommunicationTools\ScreenItems\File::setType()
142 | */
143 | public function testSetType()
144 | {
145 | $this->assertNull($this->file->getType());
146 | $this->file->setType(File::FILE_TYPE_DOCUMENT);
147 | $this->assertEquals(File::FILE_TYPE_DOCUMENT, $this->file->getType());
148 | }
149 |
150 | public function setUp(): void
151 | {
152 | $this->file = new File();
153 | }
154 |
155 | public function tearDown(): void
156 | {
157 | $this->file = null;
158 | unset($this->file);
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/tests/MessengerPoolTest.php:
--------------------------------------------------------------------------------
1 | assertEmpty($pool->getTargetUser());
29 | $pool->add($this->createMessengerMock(1));
30 | $this->assertEquals(1, $pool->getTargetUser());
31 | $pool->add($this->createMessengerMock(2));
32 | $this->assertEquals(1, $pool->getTargetUser());
33 | $pool->setTargetUser(2);
34 | $this->assertEquals(2, $pool->getTargetUser());
35 | }
36 |
37 | /**
38 | * @covers \He110\CommunicationTools\MessengerPool::add()
39 | * @covers \He110\CommunicationTools\MessengerPool::getList()
40 | */
41 | public function testAdd()
42 | {
43 | $list = $this->pool->getList();
44 | $this->pool->add($this->createMessengerMock(2));
45 | $this->assertEquals(1, count($list));
46 | $this->assertEquals(2, count($this->pool->getList()));
47 | }
48 |
49 | /**
50 | * @covers \He110\CommunicationTools\MessengerPool::removeByKey()
51 | */
52 | public function testRemoveByKey()
53 | {
54 | $list = $this->pool->getList();
55 | list($messenger) = $list;
56 | $this->assertEquals(1, count($list));
57 | $messengerKey = $this->pool->indexOf($messenger);
58 | $this->pool->removeByKey($messengerKey);
59 | $this->assertEquals(0, count($this->pool->getList()));
60 | }
61 |
62 | /**
63 | * @covers \He110\CommunicationTools\MessengerPool::remove()
64 | */
65 | public function testRemove()
66 | {
67 | $list = $this->pool->getList();
68 | list($messenger) = $list;
69 | $this->assertEquals(1, count($list));
70 | $this->pool->remove($messenger);
71 | $this->assertEquals(0, count($this->pool->getList()));
72 | }
73 |
74 | /**
75 | * @covers \He110\CommunicationTools\MessengerPool::sendScreen()
76 | */
77 | public function testSendScreen()
78 | {
79 | $screen = $this->getMockBuilder(MessengerScreen::class)->getMock();
80 | $this->trueAndFalseTest("sendScreen", $screen);
81 | }
82 |
83 | /**
84 | * @dataProvider sendTypesProvider
85 | *
86 | * @covers \He110\CommunicationTools\MessengerPool::sendMessage()
87 | * @covers \He110\CommunicationTools\MessengerPool::sendImage()
88 | * @covers \He110\CommunicationTools\MessengerPool::sendDocument()
89 | * @covers \He110\CommunicationTools\MessengerPool::sendVoice()
90 | */
91 | public function testSendTypes(string $type)
92 | {
93 | $this->trueAndFalseTest($type, "test_argument");
94 | }
95 |
96 | public function sendTypesProvider()
97 | {
98 | return array(
99 | array("sendMessage"),
100 | array("sendImage"),
101 | array("sendDocument"),
102 | array("sendVoice"),
103 | );
104 | }
105 |
106 | /**
107 | * @covers \He110\CommunicationTools\MessengerPool::indexOf()
108 | */
109 | public function testIndexOf()
110 | {
111 | list($messenger) = $this->pool->getList();
112 | $this->assertEquals(0, $this->pool->indexOf($messenger));
113 | $newMessenger = $this->createMessengerMock(10, false);
114 | $this->assertEquals(-1, $this->pool->indexOf($newMessenger));
115 | }
116 |
117 | /**
118 | * @param string $userId
119 | * @param bool $defaultResult
120 | * @return \PHPUnit\Framework\MockObject\MockObject|MessengerInterface
121 | */
122 | private function createMessengerMock(string $userId, bool $defaultResult = true)
123 | {
124 | $userIdMemory = $userId;
125 | $messenger = $this->getMockBuilder(MessengerInterface::class)->getMock();
126 | $messenger->method("setTargetUser")->willReturnCallback(function($argument) use (&$userIdMemory){
127 | $userIdMemory = $argument;
128 | });
129 | $messenger->method("getTargetUser")->will($this->returnCallback(function() use (&$userIdMemory){
130 | return $userIdMemory;
131 | }));
132 | $messenger->method("sendMessage")->willReturn($defaultResult);
133 | $messenger->method("sendImage")->willReturn($defaultResult);
134 | $messenger->method("sendDocument")->willReturn($defaultResult);
135 | $messenger->method("sendImage")->willReturn($defaultResult);
136 | $messenger->method("sendScreen")->willReturn($defaultResult);
137 | $messenger->method("sendVoice")->willReturn($defaultResult);
138 |
139 | return $messenger;
140 | }
141 |
142 | private function trueAndFalseTest(string $methodName, $argument)
143 | {
144 | $this->assertTrue($this->pool->{$methodName}($argument));
145 | $this->pool->add($this->createMessengerMock(2, false));
146 | $this->assertFalse($this->pool->{$methodName}($argument));
147 | }
148 |
149 | public function setUp(): void
150 | {
151 | $this->pool = new MessengerPool();
152 | $this->pool->add($this->createMessengerMock(1));
153 | }
154 |
155 | public function tearDown(): void
156 | {
157 | $this->pool = null;
158 | unset($this->pool);
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/MessengerScreen.php:
--------------------------------------------------------------------------------
1 | content[] = Message::create(["text" => $text]);
31 | return $this;
32 | }
33 |
34 | /**
35 | * @param string $label
36 | * @return MessengerScreen
37 | */
38 | public function addButtonText(string $label): self
39 | {
40 | $this->content[] = Button::create([
41 | "label" => $label,
42 | "type" => Button::BUTTON_TYPE_TEXT
43 | ]);
44 | return $this;
45 | }
46 |
47 | /**
48 | * @param string $label
49 | * @param string $url
50 | * @return MessengerScreen
51 | */
52 | public function addButtonLink(string $label, string $url): self
53 | {
54 | $this->content[] = Button::create([
55 | "label" => $label,
56 | "type" => Button::BUTTON_TYPE_URL,
57 | "content" => $url
58 | ]);
59 | return $this;
60 | }
61 |
62 | /**
63 | * @param string $label
64 | * @param \Closure $closure
65 | * @return MessengerScreen
66 | */
67 | public function addButtonCallback(string $label, \Closure $closure): self
68 | {
69 | $this->content[] = Button::create([
70 | "label" => $label,
71 | "type" => Button::BUTTON_TYPE_CALLBACK,
72 | "content" => $closure
73 | ]);
74 | return $this;
75 | }
76 |
77 | /**
78 | * @param string $pathToFile
79 | * @param string $description
80 | * @return MessengerScreen
81 | * @throws AttachmentNotFoundException
82 | */
83 | public function addImage(string $pathToFile, string $description = ""): self
84 | {
85 | $this->checkFile($pathToFile);
86 | $file = File::create([
87 | "path" => $pathToFile,
88 | "description" => $description,
89 | "type" => File::FILE_TYPE_IMAGE
90 | ]);
91 | $this->content[] = $file;
92 | return $this;
93 | }
94 |
95 | /**
96 | * @param string $pathToFile
97 | * @param string $description
98 | * @return MessengerScreen
99 | * @throws AttachmentNotFoundException
100 | */
101 | public function addDocument(string $pathToFile, string $description = ""): self
102 | {
103 | $this->checkFile($pathToFile);
104 | $file = File::create([
105 | "path" => $pathToFile,
106 | "description" => $description,
107 | "type" => File::FILE_TYPE_DOCUMENT
108 | ]);
109 | $this->content[] = $file;
110 | return $this;
111 | }
112 |
113 | /**
114 | * @param string $pathToFile
115 | * @return MessengerScreen
116 | * @throws AttachmentNotFoundException
117 | */
118 | public function addVoice(string $pathToFile): self
119 | {
120 | $this->checkFile($pathToFile);
121 | $file = Voice::create([
122 | "path" => $pathToFile
123 | ]);
124 | $this->content[] = $file;
125 | return $this;
126 | }
127 |
128 | /**
129 | * @param bool $asArray
130 | * @return array
131 | */
132 | public function getContent(bool $asArray = true): array
133 | {
134 | $array = [];
135 | foreach($this->content as $item) {
136 | $array[] = $asArray ? $item->toArray() : $item;
137 | }
138 | return $array;
139 | }
140 |
141 | /**
142 | * @return MessengerScreen
143 | */
144 | public function resetContent(): self
145 | {
146 | $this->content = [];
147 | return $this;
148 | }
149 |
150 | /**
151 | * @param string $pathToFile
152 | * @throws AttachmentNotFoundException
153 | */
154 | private function checkFile(string $pathToFile): void
155 | {
156 | if (!file_exists($pathToFile))
157 | throw new AttachmentNotFoundException("File not found");
158 | }
159 |
160 | /**
161 | * @return array
162 | */
163 | public function fixItemsOrder(): array
164 | {
165 | $content = $this->getContent(false);
166 | $buttons = [];
167 | $lastItem = null;
168 | $acceptableItem = null;
169 | $this->fixItemsOrderHelper($content, $buttons, $lastItem, $acceptableItem);
170 |
171 | if ($buttons && $content[$lastItem] instanceof Voice)
172 | $this->fixItemsOrderSorter($acceptableItem, $lastItem, $content, $buttons);
173 |
174 | return $content;
175 | }
176 |
177 | /**
178 | * @param $acceptableItem
179 | * @param $lastItem
180 | * @param $content
181 | * @param $buttons
182 | */
183 | private function fixItemsOrderSorter($acceptableItem, $lastItem, &$content, $buttons): void
184 | {
185 | if ($acceptableItem === null) {
186 | Helpers::array_insert($content, $lastItem, [Message::create(["text" => "Use buttons"])]);
187 | $acceptableItem = $lastItem;
188 | }
189 | $content = array_slice($content, 0, count($content) - count($buttons));
190 | Helpers::array_insert($content, $acceptableItem + 1, $buttons);
191 | }
192 |
193 | /**
194 | * @param $content
195 | * @param $buttons
196 | * @param $lastItem
197 | * @param $acceptableItem
198 | */
199 | private function fixItemsOrderHelper($content, &$buttons, &$lastItem, &$acceptableItem): void
200 | {
201 | foreach ($content as $index => $item) {
202 | if ($item instanceof Button) {
203 | $buttons[] = $item;
204 | } else {
205 | $lastItem = $index;
206 | if (!($item instanceof Voice)) {
207 | $acceptableItem = $lastItem;
208 | } else {
209 | $buttons = [];
210 | }
211 | }
212 | }
213 | }
214 | }
--------------------------------------------------------------------------------
/tests/Telegram/MessengerEventsTest.php:
--------------------------------------------------------------------------------
1 | "Ivan",
23 | "lastName" => "Ivanov",
24 | "username" => "IvanTest"
25 | ];
26 |
27 | /**
28 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::onMessage()
29 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::getRequest()
30 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::checkEvents()
31 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::addEvent()
32 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::detectPayloadType()
33 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::setUserFromRequest()
34 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::buildMessageRequest()
35 | */
36 | public function testOnMessage()
37 | {
38 | $var = "before";
39 | $text = "Here is some text for test";
40 |
41 | $client = new MessengerDoubler();
42 | $client->setAccessToken(MessengerTest::API_KEY);
43 | $client->setTargetUser(MessengerTest::TARGET_USER);
44 | $client->setDataForInput($this->getTelegramRequestMockForMessage($text));
45 | $client->onMessage(function($request) use (&$var, $text) {
46 | /** @var Request $request */
47 | $var = "after";
48 | $this->checkRequestUser($request);
49 | $this->assertEquals($text, $request->getMessage());
50 | $this->assertEquals(Request::REQUEST_TYPE_MESSAGE, $request->getType());
51 | });
52 |
53 | $this->assertEquals("before", $var);
54 | $client->checkEvents();
55 | $this->assertEquals("after", $var);
56 | }
57 |
58 | /**
59 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::onButtonClick()
60 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::getRequest()
61 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::checkEvents()
62 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::addEvent()
63 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::detectPayloadType()
64 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::setUserFromRequest()
65 | * @covers \He110\CommunicationTools\Telegram\MessengerEvents::buildButtonClickRequest()
66 | */
67 | public function testOnButtonClick()
68 | {
69 | $var = "before";
70 |
71 | $client = new MessengerDoubler();
72 | $client->setAccessToken(MessengerTest::API_KEY);
73 | $client->setTargetUser(MessengerTest::TARGET_USER);
74 | $client->setDataForInput($this->getTelegramRequestMockForCallback());
75 | $client->onButtonClick(function($request) use (&$var) {
76 | /** @var Request $request */
77 | $var = "after";
78 | $this->checkRequestUser($request);
79 | $this->assertEmpty($request->getMessage());
80 | $this->assertEquals("callbackFunctionText", $request->getPayload());
81 | $this->assertEquals(Request::REQUEST_TYPE_BUTTON_CLICK, $request->getType());
82 | });
83 |
84 | $this->assertEquals("before", $var);
85 | $client->checkEvents();
86 | $this->assertEquals("after", $var);
87 |
88 | $buttonText = "Message callback";
89 | $client->setDataForInput($this->getTelegramRequestMockForCallback("text=$buttonText"));
90 | $client->onButtonClick(function($request) use ($buttonText) {
91 | /** @var Request $request */
92 | $this->checkRequestUser($request);
93 | $this->assertNotEmpty($request->getMessage());
94 | $this->assertNull($request->getPayload());
95 | $this->assertEquals(Request::REQUEST_TYPE_BUTTON_CLICK, $request->getType());
96 | $this->assertEquals($buttonText, $request->getMessage());
97 | });
98 |
99 | $client->checkEvents();
100 |
101 | $client->setDataForInput($this->getTelegramRequestMockForCallback("invalid callback"));
102 | $client->getRequest();
103 | }
104 |
105 | /**
106 | * @param Request $request
107 | */
108 | private function checkRequestUser(Request &$request): void
109 | {
110 | $this->assertEquals($this->from["firstName"], $request->getUser()->getFirstName());
111 | $this->assertEquals($this->from["lastName"], $request->getUser()->getLastName());
112 | $this->assertEquals($this->from["username"], $request->getUser()->getUsername());
113 | }
114 |
115 | /**
116 | * @param string $text
117 | * @return string
118 | */
119 | public function getTelegramRequestMockForMessage(string $text = "text"): string
120 | {
121 | $updateId = rand(0, 500);
122 | $messageId = rand(0, 500);
123 | $from = $this->from;
124 | $targetUser = MessengerTest::TARGET_USER;
125 | $time = time();
126 | $text = addslashes($text);
127 |
128 | return <<from;
164 | $targetUser = MessengerTest::TARGET_USER;
165 | $time = time();
166 | $callback = addslashes($callback);
167 |
168 | return <<client = new Messenger();
238 | $this->client->setAccessToken(MessengerTest::API_KEY);
239 | $this->client->setTargetUser(MessengerTest::TARGET_USER);
240 | }
241 |
242 | public function tearDown(): void
243 | {
244 | $this->client = null;
245 | unset($this->client);
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/tests/MessengerScreenTest.php:
--------------------------------------------------------------------------------
1 | assertEmpty($this->screen->getContent());
34 | $this->screen->addDocument(FileTest::DOCUMENT_PATH, static::DESCRIPTION);
35 | $this->assertCount(1, $this->screen->getContent());
36 | list($ob) = $this->screen->getContent();
37 | $this->assertEquals(FileTest::DOCUMENT_PATH, $ob["path"]);
38 | $this->assertEquals(static::DESCRIPTION, $ob["description"]);
39 | $this->screen->resetContent();
40 | $this->assertEmpty($this->screen->getContent());
41 |
42 | try {
43 | $this->screen->addDocument("not_existed.file");
44 | } catch (\Exception $e) {
45 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
46 | }
47 | }
48 |
49 | /**
50 | * @covers \He110\CommunicationTools\MessengerScreen::addMessage()
51 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
52 | * @covers \He110\CommunicationTools\MessengerScreen::resetContent()
53 | */
54 | public function testAddMessage()
55 | {
56 | $this->assertEmpty($this->screen->getContent());
57 | $this->screen->addMessage(__METHOD__);
58 | $this->assertCount(1, $this->screen->getContent());
59 | list($message) = $this->screen->getContent();
60 | $this->assertEquals(__METHOD__, $message["text"]);
61 | $this->screen->resetContent();
62 | $this->assertEmpty($this->screen->getContent());
63 | }
64 |
65 | /**
66 | * @covers \He110\CommunicationTools\MessengerScreen::addImage()
67 | * @covers \He110\CommunicationTools\MessengerScreen::checkFile()
68 | */
69 | public function testAddImage()
70 | {
71 | $this->assertEmpty($this->screen->getContent());
72 | $this->screen->addImage(FileTest::IMAGE_PATH);
73 | $this->assertCount(1, $this->screen->getContent());
74 | list($ob) = $this->screen->getContent();
75 | $this->assertEquals(FileTest::IMAGE_PATH, $ob["path"]);
76 | $this->screen->resetContent();
77 | $this->assertEmpty($this->screen->getContent());
78 |
79 | try {
80 | $this->screen->addImage("not_existed.file");
81 | } catch (\Exception $e) {
82 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
83 | }
84 | }
85 |
86 | /**
87 | * @covers \He110\CommunicationTools\MessengerScreen::addButtonLink()
88 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
89 | */
90 | public function testAddButtonLink()
91 | {
92 | $url = "https://ya.ru";
93 | $this->assertEmpty($this->screen->getContent());
94 | $this->screen->addButtonLink(__METHOD__, $url);
95 | $this->assertCount(1, $this->screen->getContent());
96 | list($item) = $this->screen->getContent();
97 | $this->assertEquals(__METHOD__, $item["label"]);
98 | $this->assertEquals(Button::BUTTON_TYPE_URL, $item["type"]);
99 | $this->assertEquals($url, $item["url"]);
100 | }
101 |
102 | /**
103 | * @covers \He110\CommunicationTools\MessengerScreen::addVoice()
104 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
105 | * @covers \He110\CommunicationTools\MessengerScreen::checkFile()
106 | */
107 | public function testAddVoice()
108 | {
109 | $this->assertEmpty($this->screen->getContent());
110 | $this->screen->addVoice(VoiceTest::VOICE_OGG);
111 | $this->assertCount(1, $this->screen->getContent());
112 | list($ob) = $this->screen->getContent();
113 | $this->assertEquals(VoiceTest::VOICE_OGG, $ob["path"]);
114 | $this->screen->resetContent();
115 | $this->assertEmpty($this->screen->getContent());
116 |
117 | try {
118 | $this->screen->addVoice("not_existed.file");
119 | } catch (\Exception $e) {
120 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
121 | }
122 | }
123 |
124 | /**
125 | * @covers \He110\CommunicationTools\MessengerScreen::addButtonText()
126 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
127 | */
128 | public function testAddButtonText()
129 | {
130 | $this->assertEmpty($this->screen->getContent());
131 | $this->screen->addButtonText(__METHOD__);
132 | $this->assertCount(1, $this->screen->getContent());
133 | list($item) = $this->screen->getContent();
134 | $this->assertEquals(__METHOD__, $item["label"]);
135 | $this->assertEquals(Button::BUTTON_TYPE_TEXT, $item["type"]);
136 | }
137 |
138 | /**
139 | * @covers \He110\CommunicationTools\MessengerScreen::addButtonCallback()
140 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
141 | */
142 | public function testAddButtonCallback()
143 | {
144 | $this->assertEmpty($this->screen->getContent());
145 | $this->screen->addButtonCallback(__METHOD__, function ($a) { echo __METHOD__; });
146 | $this->assertCount(1, $this->screen->getContent());
147 | list($item) = $this->screen->getContent();
148 | $this->assertEquals(__METHOD__, $item["label"]);
149 | $this->assertEquals(Button::BUTTON_TYPE_CALLBACK, $item["type"]);
150 | $this->assertIsCallable($item["content"]);
151 | }
152 |
153 | /**
154 | * @covers \He110\CommunicationTools\MessengerScreen::fixItemsOrder()
155 | * @covers \He110\CommunicationTools\MessengerScreen::fixItemsOrderHelper()
156 | * @covers \He110\CommunicationTools\MessengerScreen::fixItemsOrderSorter()
157 | */
158 | public function testFixContentOrder()
159 | {
160 | $this->screen->addMessage(__METHOD__);
161 | $this->screen->addButtonText("Text button");
162 |
163 | $this->assertEquals($this->screen->getContent(false), $this->screen->fixItemsOrder());
164 |
165 | $this->screen->addVoice(VoiceTest::VOICE_OGG);
166 |
167 | $this->assertEquals($this->screen->getContent(false), $this->screen->fixItemsOrder());
168 |
169 | $this->screen->addButtonText("After voice");
170 |
171 | $fixed = $this->screen->fixItemsOrder();
172 |
173 | $this->assertNotEquals($this->screen->getContent(false), $fixed);
174 |
175 | $this->assertCount(4, $fixed);
176 | $this->assertInstanceOf(Message::class, $fixed[0]);
177 | $this->assertInstanceOf(Button::class, $fixed[1]);
178 | $this->assertInstanceOf(Button::class, $fixed[2]);
179 | $this->assertInstanceOf(Voice::class, $fixed[3]);
180 |
181 | $this->screen->resetContent();
182 |
183 | $this->screen->addVoice(VoiceTest::VOICE_OGG);
184 | $this->screen->addButtonText("Single button after voice");
185 |
186 | $fixed = $this->screen->fixItemsOrder();
187 |
188 | $this->assertCount(3, $fixed);
189 | $this->assertInstanceOf(Message::class, $fixed[0]);
190 | $this->assertInstanceOf(Button::class, $fixed[1]);
191 | $this->assertInstanceOf(Voice::class, $fixed[2]);
192 | }
193 |
194 | /**
195 | * @covers \He110\CommunicationTools\MessengerScreen::getContent()
196 | */
197 | public function testGetContent()
198 | {
199 | $this->screen->addMessage(__METHOD__);
200 | $this->assertCount(1, $this->screen->getContent());
201 | list($message) = $this->screen->getContent();
202 | $this->assertIsArray($message);
203 |
204 | list($message) = $this->screen->getContent(false);
205 | $this->assertInstanceOf(Message::class, $message);
206 | }
207 |
208 | public function setUp(): void
209 | {
210 | $this->screen = new MessengerScreen();
211 | }
212 |
213 | public function tearDown(): void
214 | {
215 | $this->screen = null;
216 | unset($this->screen);
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/tests/Telegram/MessengerTest.php:
--------------------------------------------------------------------------------
1 | assertTrue($this->client->sendMessage(__METHOD__));
44 |
45 |
46 | $this->assertTrue($this->client->sendMessage(__METHOD__, $this->generateButtons()));
47 |
48 | $this->client->setTargetUser("123456");
49 | $this->assertEquals("123456", $this->client->getTargetUser());
50 | $this->assertFalse($this->client->sendMessage(__METHOD__));
51 |
52 | $this->client->setTargetUser(null);
53 | $this->expectException(TargetUserException::class);
54 | $this->client->sendMessage(__METHOD__);
55 | }
56 |
57 | /**
58 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequirements()
59 | * @covers \He110\CommunicationTools\Telegram\Messenger::setAccessToken()
60 | */
61 | public function testCheckRequirements()
62 | {
63 | $this->expectException(AccessTokenException::class);
64 | $this->client->setAccessToken(null);
65 | $this->client->sendMessage(__METHOD__);
66 | }
67 |
68 | /**
69 | * @covers \He110\CommunicationTools\Telegram\Messenger::sendScreen()
70 | * @covers \He110\CommunicationTools\Telegram\Messenger::workWithScreenItem()
71 | * @covers \He110\CommunicationTools\Telegram\Messenger::sendScreenHelper()
72 | */
73 | public function testSendScreen()
74 | {
75 | $screen = new MessengerScreen();
76 | $screen->addMessage(__METHOD__);
77 | $screen->addButtonLink("Author", "https://zobenko.ru");
78 | $screen->addButtonText("Hello, world");
79 | $screen->addImage(FileTest::IMAGE_PATH, "Description");
80 | $screen->addVoice(VoiceTest::VOICE_WAV);
81 |
82 | $this->assertTrue($this->client->sendScreen($screen));
83 | }
84 |
85 | /**
86 | * @covers \He110\CommunicationTools\Telegram\Messenger::sendVoice()
87 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequirements()
88 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequestResult()
89 | * @covers \He110\CommunicationTools\Telegram\Messenger::prepareFile()
90 | */
91 | public function testSendVoice()
92 | {
93 | $this->assertTrue($this->client->sendVoice(__DIR__."/../Assets/voice.ogg"));
94 |
95 | try {
96 | $this->client->sendVoice(__DIR__ . "/../Assets/not_existed.ogg");
97 | } catch (\Exception $e) {
98 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
99 | }
100 |
101 | $this->client->setTargetUser("123456");
102 | $this->assertFalse($this->client->sendVoice(__DIR__."/../Assets/voice.ogg"));
103 |
104 | $this->client->setTargetUser(null);
105 | $this->expectException(TargetUserException::class);
106 | $this->client->sendVoice(__DIR__."/../Assets/voice.ogg");
107 | }
108 |
109 | /**
110 | * @covers \He110\CommunicationTools\Telegram\Messenger::setAccessToken()
111 | * @covers \He110\CommunicationTools\Telegram\Messenger::getAccessToken()
112 | */
113 | public function testSetAccessToken()
114 | {
115 | $this->assertEquals(static::API_KEY, $this->client->getAccessToken());
116 | $newToken = md5(rand(1,100));
117 |
118 | $this->client->setAccessToken($newToken);
119 | $this->assertEquals($newToken, $this->client->getAccessToken());
120 | }
121 |
122 | /**
123 | * @covers \He110\CommunicationTools\Telegram\Messenger::sendImage()
124 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequirements()
125 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequestResult()
126 | * @covers \He110\CommunicationTools\Telegram\Messenger::prepareFile()
127 | * @covers \He110\CommunicationTools\Telegram\Messenger::generateButtonMarkup()
128 | * @covers \He110\CommunicationTools\Telegram\Messenger::buttonToArray()
129 | * @covers \He110\CommunicationTools\Telegram\Messenger::workWithAttachment()
130 | */
131 | public function testSendImage()
132 | {
133 | $this->assertTrue($this->client->sendImage(__DIR__."/../Assets/image.jpg"));
134 | $this->assertTrue($this->client->sendImage(__DIR__."/../Assets/image.jpg", __METHOD__));
135 | $this->assertTrue($this->client->sendImage(__DIR__."/../Assets/image.jpg", __METHOD__, $this->generateButtons()));
136 |
137 | try {
138 | $this->client->sendImage(__DIR__ . "/../Assets/not_existed.jpg");
139 | } catch (\Exception $e) {
140 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
141 | }
142 |
143 | $this->client->setTargetUser("123456");
144 | $this->assertFalse($this->client->sendImage(__DIR__."/../Assets/image.jpg"));
145 |
146 | $this->client->setTargetUser(null);
147 | $this->expectException(TargetUserException::class);
148 | $this->client->sendImage(__DIR__."/../Assets/image.jpg");
149 | }
150 |
151 | /**
152 | * @covers \He110\CommunicationTools\Telegram\Messenger::sendDocument()
153 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequirements()
154 | * @covers \He110\CommunicationTools\Telegram\Messenger::checkRequestResult()
155 | * @covers \He110\CommunicationTools\Telegram\Messenger::prepareFile()
156 | * @covers \He110\CommunicationTools\Telegram\Messenger::generateButtonMarkup()
157 | * @covers \He110\CommunicationTools\Telegram\Messenger::buttonToArray()
158 | * @covers \He110\CommunicationTools\Telegram\Messenger::workWithAttachment()
159 | */
160 | public function testSendDocument()
161 | {
162 | $this->assertTrue($this->client->sendDocument(__DIR__."/../Assets/image.jpg"));
163 | $this->assertTrue($this->client->sendDocument(__DIR__."/../Assets/image.jpg", __METHOD__));
164 | $this->assertTrue($this->client->sendDocument(__DIR__."/../Assets/image.jpg", __METHOD__, $this->generateButtons()));
165 |
166 | try {
167 | $this->client->sendDocument(__DIR__ . "/../Assets/not_existed.jpg");
168 | } catch (\Exception $e) {
169 | $this->assertEquals(AttachmentNotFoundException::class, get_class($e));
170 | }
171 |
172 | $this->client->setTargetUser("123456");
173 | $this->assertFalse($this->client->sendDocument(__DIR__."/../Assets/image.jpg"));
174 |
175 | $this->client->setTargetUser(null);
176 | $this->expectException(TargetUserException::class);
177 | $this->client->sendDocument(__DIR__."/../Assets/image.jpg");
178 | }
179 |
180 | /**
181 | * @return array
182 | */
183 | public function generateButtons(): array
184 | {
185 | return [
186 | Button::create([
187 | "type" => Button::BUTTON_TYPE_URL,
188 | "label" => "Link",
189 | "content" => "https://zobenko.ru"
190 | ]),
191 | Button::create([
192 | "type" => Button::BUTTON_TYPE_TEXT,
193 | "label" => "Text"
194 | ]),
195 | Button::create([
196 | "type" => Button::BUTTON_TYPE_CALLBACK,
197 | "label" => "Callback",
198 | "content" => "callbackFunctionText"
199 | ])
200 | ];
201 | }
202 |
203 | public function setUp(): void
204 | {
205 | $this->client = new Messenger();
206 | $this->client->setAccessToken(static::API_KEY);
207 | $this->client->setTargetUser(static::TARGET_USER);
208 | }
209 |
210 | public function tearDown(): void
211 | {
212 | $this->client = null;
213 | unset($this->client);
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/src/Telegram/Messenger.php:
--------------------------------------------------------------------------------
1 | userId = $userId;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function getTargetUser(): ?string
48 | {
49 | return $this->userId;
50 | }
51 |
52 | /**
53 | * {@inheritdoc}
54 | *
55 | * @param string $text
56 | * @param array $buttons
57 | * @return bool
58 | * @throws AccessTokenException
59 | * @throws TargetUserException
60 | */
61 | public function sendMessage(string $text, array $buttons = []): bool
62 | {
63 | $this->checkRequirements();
64 |
65 | try {
66 | $keyboard = $this->generateButtonMarkup($buttons);
67 | $result = $this->client->sendMessage(
68 | $this->getTargetUser(),
69 | $text,
70 | null,
71 | false,
72 | null,
73 | $keyboard
74 | );
75 |
76 | return method_exists($result, "getMessageId") && $result->getMessageId();
77 | } catch (\Exception $exception) {
78 | return false;
79 | }
80 |
81 | }
82 |
83 | /**
84 | * {@inheritdoc}
85 | *
86 | * @param string $pathToFile
87 | * @param string|null $description
88 | * @param array $buttons
89 | * @return bool
90 | * @throws AccessTokenException
91 | * @throws AttachmentNotFoundException
92 | * @throws TargetUserException
93 | */
94 | public function sendImage(string $pathToFile, string $description = null, array $buttons = []): bool
95 | {
96 | return $this->workWithAttachment("image", $pathToFile, $description, $buttons);
97 | }
98 |
99 | /**
100 | * {@inheritdoc}
101 | *
102 | * @param string $pathToFile
103 | * @param string|null $description
104 | * @param array $buttons
105 | * @return bool
106 | * @throws AccessTokenException
107 | * @throws AttachmentNotFoundException
108 | * @throws TargetUserException
109 | */
110 | public function sendDocument(string $pathToFile, string $description = null, array $buttons = []): bool
111 | {
112 | return $this->workWithAttachment("document", $pathToFile, $description, $buttons);
113 | }
114 |
115 | /**
116 | * @param string $type
117 | * @param $pathToFile
118 | * @param $description
119 | * @param $buttons
120 | * @return bool
121 | * @throws AccessTokenException
122 | * @throws AttachmentNotFoundException
123 | * @throws TargetUserException
124 | */
125 | private function workWithAttachment(string $type, $pathToFile, $description, $buttons): bool
126 | {
127 | $method = $type == "image" ? "sendPhoto" : "sendDocument";
128 | $this->checkRequirements();
129 | $document = $this->prepareFile($pathToFile);
130 | try {
131 | $keyboard = $this->generateButtonMarkup($buttons);
132 | $result = $this->client->{$method}(
133 | $this->getTargetUser(),
134 | $document,
135 | $description,
136 | null,
137 | $keyboard
138 | );
139 | return $this->checkRequestResult($result);
140 | } catch (\Exception $exception) {
141 | return false;
142 | }
143 | }
144 |
145 | /**
146 | * {@inheritdoc}
147 | *
148 | * @param string $pathToFile
149 | * @return bool
150 | * @throws AccessTokenException
151 | * @throws AttachmentNotFoundException
152 | * @throws TargetUserException
153 | */
154 | public function sendVoice(string $pathToFile): bool
155 | {
156 | $this->checkRequirements();
157 | $document = $this->prepareFile($pathToFile);
158 | try {
159 | return $this->checkRequestResult($this->client->sendVoice($this->getTargetUser(), $document));
160 | } catch (\Exception $exception) {
161 | return false;
162 | }
163 | }
164 |
165 | /**
166 | * {@inheritdoc}
167 | */
168 | public function sendScreen(MessengerScreen $screen): bool
169 | {
170 | $buttons = array();
171 | $current = null;
172 | $result = true;
173 | foreach ($screen->fixItemsOrder() as $index => $item) {
174 | if ($item instanceof Button)
175 | $buttons[] = $item;
176 | }
177 | foreach ($screen->fixItemsOrder() as $index => $item) {
178 | if (!($item instanceof Button)) {
179 | list($current, $result, $btns) = $this->sendScreenHelper($current, $item, $result, $buttons);
180 | $buttons = array_merge($buttons, $btns);
181 | $buttons = array_unique($buttons);
182 | }
183 | }
184 | $this->workWithScreenItem($current, $buttons);
185 | return $result;
186 | }
187 |
188 | /**
189 | * @param ScreenItemInterface $item
190 | * @param array $buttons
191 | * @return bool
192 | * @throws AccessTokenException
193 | * @throws AttachmentNotFoundException
194 | * @throws TargetUserException
195 | */
196 | private function workWithScreenItem(ScreenItemInterface $item, array $buttons = []): bool
197 | {
198 | $class = get_class($item);
199 | switch ($class) {
200 | case \He110\CommunicationTools\ScreenItems\Message::class:
201 | return $this->sendMessage($item->getText(), $buttons);
202 | case Voice::class:
203 | return $this->sendVoice($item->getPath());
204 | default:
205 | $method = $item->getType() == File::FILE_TYPE_IMAGE ? "sendImage" : "sendDocument";
206 | return $this->{$method}($item->getPath(), $item->getDescription());
207 | }
208 | }
209 |
210 | /**
211 | * {@inheritdoc}
212 | */
213 | public function setAccessToken(?string $token)
214 | {
215 | $this->accessToken = $token;
216 | $this->client = new BotApi($token);
217 | }
218 |
219 | /**
220 | * {@inheritdoc}
221 | */
222 | public function getAccessToken(): ?string
223 | {
224 | return $this->accessToken;
225 | }
226 |
227 | /**
228 | * @throws AccessTokenException
229 | * @throws TargetUserException
230 | */
231 | private function checkRequirements()
232 | {
233 | if (is_null($this->client) || !$this->getAccessToken()) {
234 | throw new AccessTokenException("Telegram access token required");
235 | }
236 |
237 | if (empty($this->getTargetUser())) {
238 | throw new TargetUserException("Target Client ID required");
239 | }
240 |
241 | }
242 |
243 | /**
244 | * @param string $pathToFile
245 | * @return \CURLFile
246 | * @throws AttachmentNotFoundException
247 | */
248 | private function prepareFile(string $pathToFile): \CURLFile
249 | {
250 | if (!file_exists($pathToFile))
251 | throw new AttachmentNotFoundException("Attachment not found");
252 | return new \CURLFile($pathToFile);
253 | }
254 |
255 | /**
256 | * @param Message $message
257 | * @return bool
258 | */
259 | private function checkRequestResult(Message $message): bool
260 | {
261 | return method_exists($message, "getMessageId") && $message->getMessageId();
262 | }
263 |
264 | /**
265 | * @param Button[] $buttons
266 | * @return null|\TelegramBot\Api\Types\Inline\InlineKeyboardMarkup
267 | */
268 | private function generateButtonMarkup(array $buttons)
269 | {
270 | if ($buttons && current($buttons) instanceof Button) {
271 | $content = [];
272 | foreach ($buttons as $button) {
273 | $content[] = $this->buttonToArray($button);
274 | }
275 | return new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup($content);
276 | }
277 | return null;
278 | }
279 |
280 | /**
281 | * @param Button $button
282 | * @return array
283 | */
284 | private function buttonToArray(Button $button): array
285 | {
286 | if ($button->getType() == Button::BUTTON_TYPE_URL)
287 | return array(
288 | array(
289 | "text" => $button->getLabel(),
290 | "url" => $button->getContent()
291 | )
292 | );
293 | elseif ($button->getType() == Button::BUTTON_TYPE_CALLBACK) {
294 | return array(
295 | array(
296 | "text" => $button->getLabel(),
297 | "callback_data" => "clb=".$button->getContent()
298 | )
299 | );
300 | }
301 | else {
302 | return array(
303 | array(
304 | "text" => $button->getLabel(),
305 | "callback_data" => "text=" . $button->getLabel()
306 | )
307 | );
308 | }
309 | }
310 |
311 | /**
312 | * @param $current
313 | * @param $item
314 | * @param $result
315 | * @param $buttons
316 | * @return array
317 | * @throws AccessTokenException
318 | * @throws AttachmentNotFoundException
319 | * @throws TargetUserException
320 | */
321 | private function sendScreenHelper($current, $item, $result, $buttons): array
322 | {
323 | if ($current === null) {
324 | $current = $item;
325 | } elseif ($current !== $item && $current !== null) {
326 | $result = $result && $this->workWithScreenItem($current, $buttons);
327 | if (!($current instanceof Voice)) {
328 | $buttons = [];
329 | }
330 | $current = $item;
331 | }
332 | return array($current, $result, $buttons);
333 | }
334 | }
--------------------------------------------------------------------------------