-
-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #100 from morawskim/libnotify
New notifer for Linux which use libnotify and PHP-FFI
- Loading branch information
Showing
13 changed files
with
258 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the JoliNotif project. | ||
* | ||
* (c) Loïck Piera <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Joli\JoliNotif\Exception; | ||
|
||
class FFIRuntimeException extends \RuntimeException implements Exception | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#define FFI_LIB "libnotify.so.4" | ||
|
||
typedef bool gboolean; | ||
typedef void* gpointer; | ||
typedef struct _NotifyNotification NotifyNotification; | ||
typedef struct _GTypeInstanceError GError; | ||
|
||
gboolean notify_init(const char *app_name); | ||
gboolean notify_is_initted (void); | ||
void notify_uninit (void); | ||
NotifyNotification *notify_notification_new(const char *summary, const char *body, const char *icon); | ||
gboolean notify_notification_show (NotifyNotification *notification, GError **error); | ||
void g_object_unref (gpointer object); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the JoliNotif project. | ||
* | ||
* (c) Loïck Piera <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Joli\JoliNotif\Notifier; | ||
|
||
use Joli\JoliNotif\Exception\FFIRuntimeException; | ||
use Joli\JoliNotif\Exception\InvalidNotificationException; | ||
use Joli\JoliNotif\Notification; | ||
use Joli\JoliNotif\Notifier; | ||
use JoliCode\PhpOsHelper\OsHelper; | ||
|
||
class LibNotifyNotifier implements Notifier | ||
{ | ||
private static string $APP_NAME = 'jolinotif'; | ||
|
||
private \FFI $ffi; | ||
|
||
public function __destruct() | ||
{ | ||
if (isset($this->ffi)) { | ||
$this->ffi->notify_uninit(); | ||
} | ||
} | ||
|
||
public static function isLibraryExists(): bool | ||
{ | ||
return file_exists('/lib64/libnotify.so.4') | ||
|| file_exists('/lib/x86_64-linux-gnu/libnotify.so.4'); | ||
} | ||
|
||
public function isSupported(): bool | ||
{ | ||
return OsHelper::isUnix() | ||
&& !OsHelper::isMacOS() | ||
&& class_exists(\FFI::class) | ||
&& self::isLibraryExists(); | ||
} | ||
|
||
public function getPriority(): int | ||
{ | ||
return static::PRIORITY_HIGH; | ||
} | ||
|
||
public function send(Notification $notification): bool | ||
{ | ||
if (!$notification->getBody()) { | ||
throw new InvalidNotificationException($notification, 'Notification body can not be empty'); | ||
} | ||
|
||
$this->initialize(); | ||
$notification = $this->ffi->notify_notification_new( | ||
$notification->getTitle() ?? '', | ||
$notification->getBody(), | ||
$notification->getIcon() | ||
); | ||
$value = $this->ffi->notify_notification_show($notification, null); | ||
$this->ffi->g_object_unref($notification); | ||
|
||
return $value; | ||
} | ||
|
||
private function initialize(): void | ||
{ | ||
if (isset($this->ffi)) { | ||
return; | ||
} | ||
|
||
$ffi = \FFI::load(__DIR__ . '/FFI/ffi-libnotify.h'); | ||
|
||
if (!$ffi) { | ||
throw new FFIRuntimeException('Unable to load libnotify'); | ||
} | ||
|
||
$this->ffi = $ffi; | ||
|
||
if (!$this->ffi->notify_init(self::$APP_NAME)) { | ||
throw new FFIRuntimeException('Unable to initialize libnotify'); | ||
} | ||
|
||
if (!$this->ffi->notify_is_initted()) { | ||
throw new FFIRuntimeException('Libnotify has not been initialized'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the JoliNotif project. | ||
* | ||
* (c) Loïck Piera <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Joli\JoliNotif\tests\Notifier; | ||
|
||
use Joli\JoliNotif\Exception\InvalidNotificationException; | ||
use Joli\JoliNotif\Notification; | ||
use Joli\JoliNotif\Notifier; | ||
use Joli\JoliNotif\Notifier\LibNotifyNotifier; | ||
|
||
class LibNotifyNotifierTest extends NotifierTestCase | ||
{ | ||
public function testGetPriority() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
$this->assertSame(Notifier::PRIORITY_HIGH, $notifier->getPriority()); | ||
} | ||
|
||
public function testSendWithEmptyBody() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
$this->expectException(InvalidNotificationException::class); | ||
$this->expectExceptionMessage('Notification body can not be empty'); | ||
$notifier->send(new Notification()); | ||
} | ||
|
||
/** | ||
* @requires extension ffi | ||
*/ | ||
public function testInitialize() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
if (!$notifier::isLibraryExists()) { | ||
$this->markTestSkipped('Looks like libnotify is not installed'); | ||
} | ||
|
||
$this->assertTrue($notifier->isSupported()); | ||
} | ||
|
||
public function testSendThrowsExceptionWhenNotificationDoesntHaveBody() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
$notification = new Notification(); | ||
|
||
try { | ||
$notifier->send($notification); | ||
$this->fail('Expected a InvalidNotificationException'); | ||
} catch (\Exception $e) { | ||
$this->assertInstanceOf('Joli\JoliNotif\Exception\InvalidNotificationException', $e); | ||
} | ||
} | ||
|
||
public function testSendThrowsExceptionWhenNotificationHasAnEmptyBody() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
$notification = new Notification(); | ||
$notification->setBody(''); | ||
|
||
try { | ||
$notifier->send($notification); | ||
$this->fail('Expected a InvalidNotificationException'); | ||
} catch (\Exception $e) { | ||
$this->assertInstanceOf('Joli\JoliNotif\Exception\InvalidNotificationException', $e); | ||
} | ||
} | ||
|
||
/** | ||
* @requires extension ffi | ||
*/ | ||
public function testSendNotificationWithAllOptions() | ||
{ | ||
$notifier = $this->getNotifier(); | ||
|
||
$notification = (new Notification()) | ||
->setBody('I\'m the notification body') | ||
->setTitle('I\'m the notification title') | ||
->addOption('subtitle', 'I\'m the notification subtitle') | ||
->addOption('sound', 'Frog') | ||
->addOption('url', 'https://google.com') | ||
->setIcon($this->getIconDir() . '/image.gif') | ||
; | ||
|
||
$result = $notifier->send($notification); | ||
|
||
if (!$result) { | ||
$this->markTestSkipped('Notification was not sent'); | ||
} | ||
|
||
$this->assertTrue($notifier->send($notification)); | ||
} | ||
|
||
protected function getNotifier(): LibNotifyNotifier | ||
{ | ||
return new LibNotifyNotifier(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters