I create little project to read, send SMS from AT Commands into php.
I was create from here Execute AT commands to send sms in php and it is successful to send sms.
edited : this is the source code to sending sms with at commands in PHP
<?php
require "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet("COM9");
$serial->confBaudRate(115200);
// Then we need to open it
$serial->deviceOpen();
// To write into
$serial->sendMessage("AT+CMGF=1\n\r");
$serial->sendMessage("AT+cmgs=\"+6285291xxxxxx\"\n\r");
$serial->sendMessage("sms text\n\r");
$serial->sendMessage(chr(26));
//wait for modem to send message
sleep(7);
$read=$serial->readPort();
$serial->deviceClose();
<?php
define ("SERIAL_DEVICE_NOTSET", 0);
define ("SERIAL_DEVICE_SET", 1);
define ("SERIAL_DEVICE_OPENED", 2);
/**
* Serial port control class
*
* THIS PROGRAM COMES WITH ABSOLUTELY NO WARANTIES !
* USE IT AT YOUR OWN RISKS !
*
* Changes added by Rizwan Kassim <rizwank#uwink.com> for OSX functionality
* default serial device for osx devices is /dev/tty.serial for machines with a built in serial device
*
* #author Rémy Sanchez <thenux#gmail.com>
* #thanks Aurélien Derouineau for finding how to open serial ports with windows
* #thanks Alec Avedisyan for help and testing with reading
* #copyright under GPL 2 licence
*/
class phpSerial
{
var $_device = null;
var $_windevice = null;
var $_dHandle = null;
var $_dState = SERIAL_DEVICE_NOTSET;
var $_buffer = "";
var $_os = "";
/**
* This var says if buffer should be flushed by sendMessage (true) or manualy (false)
*
* #var bool
*/
var $autoflush = true;
/**
* Constructor. Perform some checks about the OS and setserial
*
* #return phpSerial
*/
function phpSerial ()
{
setlocale(LC_ALL, "en_US");
$sysname = php_uname();
if (substr($sysname, 0, 5) === "Linux")
{
$this->_os = "linux";
if($this->_exec("stty --version") === 0)
{
register_shutdown_function(array($this, "deviceClose"));
}
else
{
trigger_error("No stty availible, unable to run.", E_USER_ERROR);
}
}
elseif (substr($sysname, 0, 6) === "Darwin")
{
$this->_os = "osx";
// We know stty is available in Darwin.
// stty returns 1 when run from php, because "stty: stdin isn't a
// terminal"
// skip this check
// if($this->_exec("stty") === 0)
// {
register_shutdown_function(array($this, "deviceClose"));
// }
// else
// {
// trigger_error("No stty availible, unable to run.", E_USER_ERROR);
// }
}
elseif(substr($sysname, 0, 7) === "Windows")
{
$this->_os = "windows";
register_shutdown_function(array($this, "deviceClose"));
}
else
{
trigger_error("Host OS is neither osx, linux nor windows, unable tu run.", E_USER_ERROR);
exit();
}
}
//
// OPEN/CLOSE DEVICE SECTION -- {START}
//
/**
* Device set function : used to set the device name/address.
* -> linux : use the device address, like /dev/ttyS0
* -> osx : use the device address, like /dev/tty.serial
* -> windows : use the COMxx device name, like COM1 (can also be used
* with linux)
*
* #param string $device the name of the device to be used
* #return bool
*/
function deviceSet ($device)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
if ($this->_os === "linux")
{
if (preg_match("#^COM(\d+):?$#i", $device, $matches))
{
$device = "/dev/ttyS" . ($matches[1] - 1);
}
if ($this->_exec("stty -F " . $device) === 0)
{
$this->_device = $device;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
elseif ($this->_os === "osx")
{
if ($this->_exec("stty -f " . $device) === 0)
{
$this->_device = $device;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
elseif ($this->_os === "windows")
{
if (preg_match("#^COM(\d+):?$#i", $device, $matches) and $this->_exec(exec("mode " . $device . " xon=on BAUD=9600")) === 0)
{
$this->_windevice = "COM" . $matches[1];
$this->_device = "\\.\com" . $matches[1];
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
trigger_error("Specified serial port is not valid", E_USER_WARNING);
return false;
}
else
{
trigger_error("You must close your device before to set an other one", E_USER_WARNING);
return false;
}
}
/**
* Opens the device for reading and/or writing.
*
* #param string $mode Opening mode : same parameter as fopen()
* #return bool
*/
function deviceOpen ($mode = "r+b")
{
if ($this->_dState === SERIAL_DEVICE_OPENED)
{
trigger_error("The device is already opened", E_USER_NOTICE);
return true;
}
if ($this->_dState === SERIAL_DEVICE_NOTSET)
{
trigger_error("The device must be set before to be open", E_USER_WARNING);
return false;
}
if (!preg_match("#^[raw]\+?b?$#", $mode))
{
trigger_error("Invalid opening mode : ".$mode.". Use fopen() modes.", E_USER_WARNING);
return false;
}
$this->_dHandle = #fopen($this->_device, $mode);
if ($this->_dHandle !== false)
{
stream_set_blocking($this->_dHandle, 0);
$this->_dState = SERIAL_DEVICE_OPENED;
return true;
}
$this->_dHandle = null;
trigger_error("Unable to open the device", E_USER_WARNING);
return false;
}
/**
* Closes the device
*
* #return bool
*/
function deviceClose ()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
return true;
}
if (fclose($this->_dHandle))
{
$this->_dHandle = null;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
trigger_error("Unable to close the device", E_USER_ERROR);
return false;
}
//
// OPEN/CLOSE DEVICE SECTION -- {STOP}
//
//
// CONFIGURE SECTION -- {START}
//
/**
* Configure the Baud Rate
* Possible rates : 110, 150, 300, 600, 1200, 2400, 4800, 9600, 38400,
* 57600 and 115200.
*
* #param int $rate the rate to set the port in
* #return bool
*/
function confBaudRate ($rate)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set the baud rate : the device is either not set or opened", E_USER_WARNING);
return false;
}
$validBauds = array (
110 => 11,
150 => 15,
300 => 30,
600 => 60,
1200 => 12,
2400 => 24,
4800 => 48,
9600 => 96,
19200 => 19,
38400 => 38400,
57600 => 57600,
115200 => 115200
);
if (isset($validBauds[$rate]))
{
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . (int) $rate, $out);
}
if ($this->_os === "darwin")
{
$ret = $this->_exec("stty -f " . $this->_device . " " . (int) $rate, $out);
}
elseif ($this->_os === "windows")
{
$ret = $this->_exec("mode " . $this->_windevice . " BAUD=" . $validBauds[$rate], $out);
}
else return false;
if ($ret !== 0)
{
trigger_error ("Unable to set baud rate: " . $out[1], E_USER_WARNING);
return false;
}
}
}
/**
* Configure parity.
* Modes : odd, even, none
*
* #param string $parity one of the modes
* #return bool
*/
function confParity ($parity)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set parity : the device is either not set or opened", E_USER_WARNING);
return false;
}
$args = array(
"none" => "-parenb",
"odd" => "parenb parodd",
"even" => "parenb -parodd",
);
if (!isset($args[$parity]))
{
trigger_error("Parity mode not supported", E_USER_WARNING);
return false;
}
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . $args[$parity], $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " PARITY=" . $parity{0}, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set parity : " . $out[1], E_USER_WARNING);
return false;
}
/**
* Sets the length of a character.
*
* #param int $int length of a character (5 <= length <= 8)
* #return bool
*/
function confCharacterLength ($int)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set length of a character : the device is either not set or opened", E_USER_WARNING);
return false;
}
$int = (int) $int;
if ($int < 5) $int = 5;
elseif ($int > 8) $int = 8;
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " cs" . $int, $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " DATA=" . $int, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set character length : " .$out[1], E_USER_WARNING);
return false;
}
/**
* Sets the length of stop bits.
*
* #param float $length the length of a stop bit. It must be either 1,
* 1.5 or 2. 1.5 is not supported under linux and on some computers.
* #return bool
*/
function confStopBits ($length)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set the length of a stop bit : the device is either not set or opened", E_USER_WARNING);
return false;
}
if ($length != 1 and $length != 2 and $length != 1.5 and !($length == 1.5 and $this->_os === "linux"))
{
trigger_error("Specified stop bit length is invalid", E_USER_WARNING);
return false;
}
if ($this->_os === "linux")
{
$ret = $this->_exec("stty -F " . $this->_device . " " . (($length == 1) ? "-" : "") . "cstopb", $out);
}
else
{
$ret = $this->_exec("mode " . $this->_windevice . " STOP=" . $length, $out);
}
if ($ret === 0)
{
return true;
}
trigger_error("Unable to set stop bit length : " . $out[1], E_USER_WARNING);
return false;
}
/**
* Configures the flow control
*
* #param string $mode Set the flow control mode. Availible modes :
* -> "none" : no flow control
* -> "rts/cts" : use RTS/CTS handshaking
* -> "xon/xoff" : use XON/XOFF protocol
* #return bool
*/
function confFlowControl ($mode)
{
if ($this->_dState !== SERIAL_DEVICE_SET)
{
trigger_error("Unable to set flow control mode : the device is either not set or opened", E_USER_WARNING);
return false;
}
$linuxModes = array(
"none" => "clocal -crtscts -ixon -ixoff",
"rts/cts" => "-clocal crtscts -ixon -ixoff",
"xon/xoff" => "-clocal -crtscts ixon ixoff"
);
$windowsModes = array(
"none" => "xon=off octs=off rts=on",
"rts/cts" => "xon=off octs=on rts=hs",
"xon/xoff" => "xon=on octs=off rts=on",
);
if ($mode !== "none" and $mode !== "rts/cts" and $mode !== "xon/xoff") {
trigger_error("Invalid flow control mode specified", E_USER_ERROR);
return false;
}
if ($this->_os === "linux")
$ret = $this->_exec("stty -F " . $this->_device . " " . $linuxModes[$mode], $out);
else
$ret = $this->_exec("mode " . $this->_windevice . " " . $windowsModes[$mode], $out);
if ($ret === 0) return true;
else {
trigger_error("Unable to set flow control : " . $out[1], E_USER_ERROR);
return false;
}
}
/**
* Sets a setserial parameter (cf man setserial)
* NO MORE USEFUL !
* -> No longer supported
* -> Only use it if you need it
*
* #param string $param parameter name
* #param string $arg parameter value
* #return bool
*/
function setSetserialFlag ($param, $arg = "")
{
if (!$this->_ckOpened()) return false;
$return = exec ("setserial " . $this->_device . " " . $param . " " . $arg . " 2>&1");
if ($return{0} === "I")
{
trigger_error("setserial: Invalid flag", E_USER_WARNING);
return false;
}
elseif ($return{0} === "/")
{
trigger_error("setserial: Error with device file", E_USER_WARNING);
return false;
}
else
{
return true;
}
}
//
// CONFIGURE SECTION -- {STOP}
//
//
// I/O SECTION -- {START}
//
/**
* Sends a string to the device
*
* #param string $str string to be sent to the device
* #param float $waitForReply time to wait for the reply (in seconds)
*/
function sendMessage ($str, $waitForReply = 0.1)
{
$this->_buffer .= $str;
if ($this->autoflush === true) $this->serialflush();
usleep((int) ($waitForReply * 1000000));
}
/**
* Reads the port until no new datas are availible, then return the content.
*
* #pararm int $count number of characters to be read (will stop before
* if less characters are in the buffer)
* #return string
*/
function readPort ($count = 0)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
trigger_error("Device must be opened to read it", E_USER_WARNING);
return false;
}
if ($this->_os === "linux" || $this->_os === "osx")
{
// Behavior in OSX isn't to wait for new data to recover, but just grabs what's there!
// Doesn't always work perfectly for me in OSX
$content = ""; $i = 0;
if ($count !== 0)
{
do {
if ($i > $count) $content .= fread($this->_dHandle, ($count - $i));
else $content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
else
{
do {
$content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
return $content;
}
elseif ($this->_os === "windows")
{
$content = "";
if ($count > 0)
{
$content = fread($this->_dHandle, $count);
}
return $content;
}
return false;
}
/**
* Flushes the output buffer
* Renamed from flush for osx compat. issues
*
* #return bool
*/
function serialflush ()
{
if (!$this->_ckOpened()) return false;
if (fwrite($this->_dHandle, $this->_buffer) !== false)
{
$this->_buffer = "";
return true;
}
else
{
$this->_buffer = "";
trigger_error("Error while sending message", E_USER_WARNING);
return false;
}
}
//
// I/O SECTION -- {STOP}
//
//
// INTERNAL TOOLKIT -- {START}
//
function _ckOpened()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED)
{
trigger_error("Device must be opened", E_USER_WARNING);
return false;
}
return true;
}
function _ckClosed()
{
if ($this->_dState !== SERIAL_DEVICE_CLOSED)
{
trigger_error("Device must be closed", E_USER_WARNING);
return false;
}
return true;
}
function _exec($cmd, &$out = null)
{
$desc = array(
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$proc = proc_open($cmd, $desc, $pipes);
$ret = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$retVal = proc_close($proc);
if (func_num_args() == 2) $out = array($ret, $err);
return $retVal;
}
//
// INTERNAL TOOLKIT -- {STOP}
//
}
?>
Question:
any advance php code
to read sms from AT Commands into php
to read ussd (like *111*1#) from AT Commands into php
Related
I'm trying to build a PHP script that sends a text message using a USB GSM Dongle. I'm using php_serial class that is provided here. The GSM modem is connected on COM3 and following is my code. However, I always gets the error "Specified serial port is not valid".
php_serial_class
class PhpSerial
{
public $_device = null;
public $_winDevice = null;
public $_dHandle = null;
public $_dState = SERIAL_DEVICE_NOTSET;
public $_buffer = "";
public $_os = "";
/**
* This var says if buffer should be flushed by sendMessage (true) or
* manually (false)
*
* #var bool
*/
public $autoFlush = true;
/**
* Constructor. Perform some checks about the OS and setserial
*
* #return PhpSerial
*/
public function PhpSerial()
{
setlocale(LC_ALL, "en_US");
$sysName = php_uname();
if (substr($sysName, 0, 5) === "Linux") {
$this->_os = "linux";
if ($this->_exec("stty") === 0) {
register_shutdown_function(array($this, "deviceClose"));
} else {
trigger_error(
"No stty availible, unable to run.",
E_USER_ERROR
);
}
} elseif (substr($sysName, 0, 6) === "Darwin") {
$this->_os = "osx";
register_shutdown_function(array($this, "deviceClose"));
} elseif (substr($sysName, 0, 7) === "Windows") {
$this->_os = "windows";
register_shutdown_function(array($this, "deviceClose"));
} else {
trigger_error("Host OS is neither osx, linux nor windows, unable " .
"to run.", E_USER_ERROR);
exit();
}
}
//
// OPEN/CLOSE DEVICE SECTION -- {START}
//
/**
* Device set function : used to set the device name/address.
* -> linux : use the device address, like /dev/ttyS0
* -> osx : use the device address, like /dev/tty.serial
* -> windows : use the COMxx device name, like COM1 (can also be used
* with linux)
*
* #param string $device the name of the device to be used
* #return bool
*/
public function deviceSet($device)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED) {
if ($this->_os === "linux") {
if (preg_match("#^COM(\\d+):?$#i", $device, $matches)) {
$device = "/dev/ttyS" . ($matches[1] - 1);
}
if ($this->_exec("stty -F " . $device) === 0) {
$this->_device = $device;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
} elseif ($this->_os === "osx") {
if ($this->_exec("stty -f " . $device) === 0) {
$this->_device = $device;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
} elseif ($this->_os === "windows") {
if (preg_match("#^COM(\\d+):?$#i", $device, $matches)
and $this->_exec(
exec("mode " . $device . " xon=on BAUD=9600")
) === 0
) {
$this->_winDevice = "COM" . $matches[1];
$this->_device = "\\.com" . $matches[1];
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
}
trigger_error("Specified serial port is not valid", E_USER_WARNING);
return false;
} else {
trigger_error("You must close your device before to set an other " .
"one", E_USER_WARNING);
return false;
}
}
/**
* Opens the device for reading and/or writing.
*
* #param string $mode Opening mode : same parameter as fopen()
* #return bool
*/
public function deviceOpen($mode = "r+b")
{
if ($this->_dState === SERIAL_DEVICE_OPENED) {
trigger_error("The device is already opened", E_USER_NOTICE);
return true;
}
if ($this->_dState === SERIAL_DEVICE_NOTSET) {
trigger_error(
"The device must be set before to be open",
E_USER_WARNING
);
return false;
}
if (!preg_match("#^[raw]\\+?b?$#", $mode)) {
trigger_error(
"Invalid opening mode : ".$mode.". Use fopen() modes.",
E_USER_WARNING
);
return false;
}
$this->_dHandle = #fopen($this->_device, $mode);
if ($this->_dHandle !== false) {
stream_set_blocking($this->_dHandle, 0);
$this->_dState = SERIAL_DEVICE_OPENED;
return true;
}
$this->_dHandle = null;
trigger_error("Unable to open the device", E_USER_WARNING);
return false;
}
/**
* Closes the device
*
* #return bool
*/
public function deviceClose()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED) {
return true;
}
if (fclose($this->_dHandle)) {
$this->_dHandle = null;
$this->_dState = SERIAL_DEVICE_SET;
return true;
}
trigger_error("Unable to close the device", E_USER_ERROR);
return false;
}
//
// OPEN/CLOSE DEVICE SECTION -- {STOP}
//
//
// CONFIGURE SECTION -- {START}
//
/**
* Configure the Baud Rate
* Possible rates : 110, 150, 300, 600, 1200, 2400, 4800, 9600, 38400,
* 57600 and 115200.
*
* #param int $rate the rate to set the port in
* #return bool
*/
public function confBaudRate($rate)
{
if ($this->_dState !== SERIAL_DEVICE_SET) {
trigger_error("Unable to set the baud rate : the device is " .
"either not set or opened", E_USER_WARNING);
return false;
}
$validBauds = array (
110 => 11,
150 => 15,
300 => 30,
600 => 60,
1200 => 12,
2400 => 24,
4800 => 48,
9600 => 96,
19200 => 19,
38400 => 38400,
57600 => 57600,
115200 => 115200
);
if (isset($validBauds[$rate])) {
if ($this->_os === "linux") {
$ret = $this->_exec(
"stty -F " . $this->_device . " " . (int) $rate,
$out
);
} elseif ($this->_os === "osx") {
$ret = $this->_exec(
"stty -f " . $this->_device . " " . (int) $rate,
$out
);
} elseif ($this->_os === "windows") {
$ret = $this->_exec(
"mode " . $this->_winDevice . " BAUD=" . $validBauds[$rate],
$out
);
} else {
return false;
}
if ($ret !== 0) {
trigger_error(
"Unable to set baud rate: " . $out[1],
E_USER_WARNING
);
return false;
}
return true;
} else {
return false;
}
}
/**
* Configure parity.
* Modes : odd, even, none
*
* #param string $parity one of the modes
* #return bool
*/
public function confParity($parity)
{
if ($this->_dState !== SERIAL_DEVICE_SET) {
trigger_error(
"Unable to set parity : the device is either not set or opened",
E_USER_WARNING
);
return false;
}
$args = array(
"none" => "-parenb",
"odd" => "parenb parodd",
"even" => "parenb -parodd",
);
if (!isset($args[$parity])) {
trigger_error("Parity mode not supported", E_USER_WARNING);
return false;
}
if ($this->_os === "linux") {
$ret = $this->_exec(
"stty -F " . $this->_device . " " . $args[$parity],
$out
);
} elseif ($this->_os === "osx") {
$ret = $this->_exec(
"stty -f " . $this->_device . " " . $args[$parity],
$out
);
} else {
$ret = $this->_exec(
"mode " . $this->_winDevice . " PARITY=" . $parity{0},
$out
);
}
if ($ret === 0) {
return true;
}
trigger_error("Unable to set parity : " . $out[1], E_USER_WARNING);
return false;
}
/**
* Sets the length of a character.
*
* #param int $int length of a character (5 <= length <= 8)
* #return bool
*/
public function confCharacterLength($int)
{
if ($this->_dState !== SERIAL_DEVICE_SET) {
trigger_error("Unable to set length of a character : the device " .
"is either not set or opened", E_USER_WARNING);
return false;
}
$int = (int) $int;
if ($int < 5) {
$int = 5;
} elseif ($int > 8) {
$int = 8;
}
if ($this->_os === "linux") {
$ret = $this->_exec(
"stty -F " . $this->_device . " cs" . $int,
$out
);
} elseif ($this->_os === "osx") {
$ret = $this->_exec(
"stty -f " . $this->_device . " cs" . $int,
$out
);
} else {
$ret = $this->_exec(
"mode " . $this->_winDevice . " DATA=" . $int,
$out
);
}
if ($ret === 0) {
return true;
}
trigger_error(
"Unable to set character length : " .$out[1],
E_USER_WARNING
);
return false;
}
/**
* Sets the length of stop bits.
*
* #param float $length the length of a stop bit. It must be either 1,
* 1.5 or 2. 1.5 is not supported under linux and on
* some computers.
* #return bool
*/
public function confStopBits($length)
{
if ($this->_dState !== SERIAL_DEVICE_SET) {
trigger_error("Unable to set the length of a stop bit : the " .
"device is either not set or opened", E_USER_WARNING);
return false;
}
if ($length != 1
and $length != 2
and $length != 1.5
and !($length == 1.5 and $this->_os === "linux")
) {
trigger_error(
"Specified stop bit length is invalid",
E_USER_WARNING
);
return false;
}
if ($this->_os === "linux") {
$ret = $this->_exec(
"stty -F " . $this->_device . " " .
(($length == 1) ? "-" : "") . "cstopb",
$out
);
} elseif ($this->_os === "osx") {
$ret = $this->_exec(
"stty -f " . $this->_device . " " .
(($length == 1) ? "-" : "") . "cstopb",
$out
);
} else {
$ret = $this->_exec(
"mode " . $this->_winDevice . " STOP=" . $length,
$out
);
}
if ($ret === 0) {
return true;
}
trigger_error(
"Unable to set stop bit length : " . $out[1],
E_USER_WARNING
);
return false;
}
/**
* Configures the flow control
*
* #param string $mode Set the flow control mode. Availible modes :
* -> "none" : no flow control
* -> "rts/cts" : use RTS/CTS handshaking
* -> "xon/xoff" : use XON/XOFF protocol
* #return bool
*/
public function confFlowControl($mode)
{
if ($this->_dState !== SERIAL_DEVICE_SET) {
trigger_error("Unable to set flow control mode : the device is " .
"either not set or opened", E_USER_WARNING);
return false;
}
$linuxModes = array(
"none" => "clocal -crtscts -ixon -ixoff",
"rts/cts" => "-clocal crtscts -ixon -ixoff",
"xon/xoff" => "-clocal -crtscts ixon ixoff"
);
$windowsModes = array(
"none" => "xon=off octs=off rts=on",
"rts/cts" => "xon=off octs=on rts=hs",
"xon/xoff" => "xon=on octs=off rts=on",
);
if ($mode !== "none" and $mode !== "rts/cts" and $mode !== "xon/xoff") {
trigger_error("Invalid flow control mode specified", E_USER_ERROR);
return false;
}
if ($this->_os === "linux") {
$ret = $this->_exec(
"stty -F " . $this->_device . " " . $linuxModes[$mode],
$out
);
} elseif ($this->_os === "osx") {
$ret = $this->_exec(
"stty -f " . $this->_device . " " . $linuxModes[$mode],
$out
);
} else {
$ret = $this->_exec(
"mode " . $this->_winDevice . " " . $windowsModes[$mode],
$out
);
}
if ($ret === 0) {
return true;
} else {
trigger_error(
"Unable to set flow control : " . $out[1],
E_USER_ERROR
);
return false;
}
}
/**
* Sets a setserial parameter (cf man setserial)
* NO MORE USEFUL !
* -> No longer supported
* -> Only use it if you need it
*
* #param string $param parameter name
* #param string $arg parameter value
* #return bool
*/
public function setSetserialFlag($param, $arg = "")
{
if (!$this->_ckOpened()) {
return false;
}
$return = exec(
"setserial " . $this->_device . " " . $param . " " . $arg . " 2>&1"
);
if ($return{0} === "I") {
trigger_error("setserial: Invalid flag", E_USER_WARNING);
return false;
} elseif ($return{0} === "/") {
trigger_error("setserial: Error with device file", E_USER_WARNING);
return false;
} else {
return true;
}
}
//
// CONFIGURE SECTION -- {STOP}
//
//
// I/O SECTION -- {START}
//
/**
* Sends a string to the device
*
* #param string $str string to be sent to the device
* #param float $waitForReply time to wait for the reply (in seconds)
*/
public function sendMessage($str, $waitForReply = 0.1)
{
$this->_buffer .= $str;
if ($this->autoFlush === true) {
$this->serialflush();
}
usleep((int) ($waitForReply * 1000000));
}
/**
* Reads the port until no new datas are availible, then return the content.
*
* #param int $count Number of characters to be read (will stop before
* if less characters are in the buffer)
* #return string
*/
public function readPort($count = 0)
{
if ($this->_dState !== SERIAL_DEVICE_OPENED) {
trigger_error("Device must be opened to read it", E_USER_WARNING);
return false;
}
if ($this->_os === "linux" || $this->_os === "osx") {
// Behavior in OSX isn't to wait for new data to recover, but just
// grabs what's there!
// Doesn't always work perfectly for me in OSX
$content = ""; $i = 0;
if ($count !== 0) {
do {
if ($i > $count) {
$content .= fread($this->_dHandle, ($count - $i));
} else {
$content .= fread($this->_dHandle, 128);
}
} while (($i += 128) === strlen($content));
} else {
do {
$content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
return $content;
} elseif ($this->_os === "windows") {
// Windows port reading procedures still buggy
$content = ""; $i = 0;
if ($count !== 0) {
do {
if ($i > $count) {
$content .= fread($this->_dHandle, ($count - $i));
} else {
$content .= fread($this->_dHandle, 128);
}
} while (($i += 128) === strlen($content));
} else {
do {
$content .= fread($this->_dHandle, 128);
} while (($i += 128) === strlen($content));
}
return $content;
}
return false;
}
/**
* Flushes the output buffer
* Renamed from flush for osx compat. issues
*
* #return bool
*/
public function serialflush()
{
if (!$this->_ckOpened()) {
return false;
}
if (fwrite($this->_dHandle, $this->_buffer) !== false) {
$this->_buffer = "";
return true;
} else {
$this->_buffer = "";
trigger_error("Error while sending message", E_USER_WARNING);
return false;
}
}
//
// I/O SECTION -- {STOP}
//
//
// INTERNAL TOOLKIT -- {START}
//
public function _ckOpened()
{
if ($this->_dState !== SERIAL_DEVICE_OPENED) {
trigger_error("Device must be opened", E_USER_WARNING);
return false;
}
return true;
}
public function _ckClosed()
{
if ($this->_dState === SERIAL_DEVICE_OPENED) {
trigger_error("Device must be closed", E_USER_WARNING);
return false;
}
return true;
}
public function _exec($cmd, &$out = null)
{
$desc = array(
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$proc = proc_open($cmd, $desc, $pipes);
$ret = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$retVal = proc_close($proc);
if (func_num_args() == 2) $out = array($ret, $err);
return $retVal;
}
//
// INTERNAL TOOLKIT -- {STOP}
//
}
send_msg.php
include 'php_serial.class.php';
$serial = new PhpSerial;
$serial->deviceSet("COM3");
$serial->deviceOpen('w+');
stream_set_timeout($serial->_dHandle, 10);
$serial->confBaudRate(9600);
$serial->sendMessage("AT",1);
var_dump($serial->readPort());
$serial->sendMessage("AT+CMGF=1\n\r",1);
var_dump($serial->readPort());
$serial->sendMessage("AT+CMGL=\"ALL\"\n\r",2);
var_dump($serial->readPort());
$serial->deviceClose();
Tried changing ports for the device in device manager but didn't work.
enter image description here
Running XAMPP on Windows 10.
I'm getting a PHP fatal error on a cron script used for Commission Junction. It seems in the error_log it keeps updating with
PHP Fatal error: Call to undefined method Mage_Core_Helper_Data::getEscapedCSVData() in /home/lovescen/public_html/app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php on line 269
The code on line 269 is
$escapedValue = Mage::helper("core")->getEscapedCSVData(array($value));
And here is the entire code in Csv.php.
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magento.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magento.com for more information.
*
* #category Mage
* #package Mage_Dataflow
* #copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Convert csv parser
*
* #category Mage
* #package Mage_Dataflow
* #author Magento Core Team <core#magentocommerce.com>
*/
class Mage_Dataflow_Model_Convert_Parser_Csv extends Mage_Dataflow_Model_Convert_Parser_Abstract
{
protected $_fields;
protected $_mapfields = array();
public function parse()
{
// fixed for multibyte characters
setlocale(LC_ALL, Mage::app()->getLocale()->getLocaleCode().'.UTF-8');
$fDel = $this->getVar('delimiter', ',');
$fEnc = $this->getVar('enclose', '"');
if ($fDel == '\t') {
$fDel = "\t";
}
$adapterName = $this->getVar('adapter', null);
$adapterMethod = $this->getVar('method', 'saveRow');
if (!$adapterName || !$adapterMethod) {
$message = Mage::helper('dataflow')->__('Please declare "adapter" and "method" nodes first.');
$this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL);
return $this;
}
try {
$adapter = Mage::getModel($adapterName);
}
catch (Exception $e) {
$message = Mage::helper('dataflow')->__('Declared adapter %s was not found.', $adapterName);
$this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL);
return $this;
}
if (!method_exists($adapter, $adapterMethod)) {
$message = Mage::helper('dataflow')->__('Method "%s" not defined in adapter %s.', $adapterMethod, $adapterName);
$this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL);
return $this;
}
$batchModel = $this->getBatchModel();
$batchIoAdapter = $this->getBatchModel()->getIoAdapter();
if (Mage::app()->getRequest()->getParam('files')) {
$file = Mage::app()->getConfig()->getTempVarDir().'/import/'
. urldecode(Mage::app()->getRequest()->getParam('files'));
$this->_copy($file);
}
$batchIoAdapter->open(false);
$isFieldNames = $this->getVar('fieldnames', '') == 'true' ? true : false;
if (!$isFieldNames && is_array($this->getVar('map'))) {
$fieldNames = $this->getVar('map');
}
else {
$fieldNames = array();
foreach ($batchIoAdapter->read(true, $fDel, $fEnc) as $v) {
$fieldNames[$v] = $v;
}
}
$countRows = 0;
while (($csvData = $batchIoAdapter->read(true, $fDel, $fEnc)) !== false) {
if (count($csvData) == 1 && $csvData[0] === null) {
continue;
}
$itemData = array();
$countRows ++; $i = 0;
foreach ($fieldNames as $field) {
$itemData[$field] = isset($csvData[$i]) ? $csvData[$i] : null;
$i ++;
}
$batchImportModel = $this->getBatchImportModel()
->setId(null)
->setBatchId($this->getBatchModel()->getId())
->setBatchData($itemData)
->setStatus(1)
->save();
}
$this->addException(Mage::helper('dataflow')->__('Found %d rows.', $countRows));
$this->addException(Mage::helper('dataflow')->__('Starting %s :: %s', $adapterName, $adapterMethod));
$batchModel->setParams($this->getVars())
->setAdapter($adapterName)
->save();
//$adapter->$adapterMethod();
return $this;
// // fix for field mapping
// if ($mapfields = $this->getProfile()->getDataflowProfile()) {
// $this->_mapfields = array_values($mapfields['gui_data']['map'][$mapfields['entity_type']]['db']);
// } // end
//
// if (!$this->getVar('fieldnames') && !$this->_mapfields) {
// $this->addException('Please define field mapping', Mage_Dataflow_Model_Convert_Exception::FATAL);
// return;
// }
//
// if ($this->getVar('adapter') && $this->getVar('method')) {
// $adapter = Mage::getModel($this->getVar('adapter'));
// }
//
// $i = 0;
// while (($line = fgetcsv($fh, null, $fDel, $fEnc)) !== FALSE) {
// $row = $this->parseRow($i, $line);
//
// if (!$this->getVar('fieldnames') && $i == 0 && $row) {
// $i = 1;
// }
//
// if ($row) {
// $loadMethod = $this->getVar('method');
// $adapter->$loadMethod(compact('i', 'row'));
// }
// $i++;
// }
//
// return $this;
}
public function parseRow($i, $line)
{
if (sizeof($line) == 1) return false;
if (0==$i) {
if ($this->getVar('fieldnames')) {
$this->_fields = $line;
return;
} else {
foreach ($line as $j=>$f) {
$this->_fields[$j] = $this->_mapfields[$j];
}
}
}
$resultRow = array();
foreach ($this->_fields as $j=>$f) {
$resultRow[$f] = isset($line[$j]) ? $line[$j] : '';
}
return $resultRow;
}
/**
* Read data collection and write to temporary file
*
* #return Mage_Dataflow_Model_Convert_Parser_Csv
*/
public function unparse()
{
$batchExport = $this->getBatchExportModel()
->setBatchId($this->getBatchModel()->getId());
$fieldList = $this->getBatchModel()->getFieldList();
$batchExportIds = $batchExport->getIdCollection();
$io = $this->getBatchModel()->getIoAdapter();
$io->open();
if (!$batchExportIds) {
$io->write("");
$io->close();
return $this;
}
if ($this->getVar('fieldnames')) {
$csvData = $this->getCsvString($fieldList);
$io->write($csvData);
}
foreach ($batchExportIds as $batchExportId) {
$csvData = array();
$batchExport->load($batchExportId);
$row = $batchExport->getBatchData();
foreach ($fieldList as $field) {
$csvData[] = isset($row[$field]) ? $row[$field] : '';
}
$csvData = $this->getCsvString($csvData);
$io->write($csvData);
}
$io->close();
return $this;
}
public function unparseRow($args)
{
$i = $args['i'];
$row = $args['row'];
$fDel = $this->getVar('delimiter', ',');
$fEnc = $this->getVar('enclose', '"');
$fEsc = $this->getVar('escape', '\\');
$lDel = "\r\n";
if ($fDel == '\t') {
$fDel = "\t";
}
$line = array();
foreach ($this->_fields as $f) {
$v = isset($row[$f]) ? str_replace(array('"', '\\'), array($fEnc.'"', $fEsc.'\\'), $row[$f]) : '';
$line[] = $fEnc.$v.$fEnc;
}
return join($fDel, $line);
}
/**
* Retrieve csv string from array
*
* #param array $fields
* #return string
*/
public function getCsvString($fields = array()) {
$delimiter = $this->getVar('delimiter', ',');
$enclosure = $this->getVar('enclose', '');
$escapeChar = $this->getVar('escape', '\\');
if ($delimiter == '\t') {
$delimiter = "\t";
}
$str = '';
foreach ($fields as $value) {
$escapedValue = Mage::helper("core")->getEscapedCSVData(array($value));
$value = $escapedValue[0];
if (strpos($value, $delimiter) !== false ||
empty($enclosure) ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escapeChar) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $enclosure.$value.$enclosure.$delimiter;
}
}
return substr($str, 0, -1) . "\n";
}
}
Not sure how to fix this problem. If I could get some help I'd really appreciate it.
Thanks
UPDATE
Here is the code from my app/code/core/Mage/Core/Helper/Data.php file: http://pastie.org/10815259
Does the file app/code/core/Mage/Core/Helper/Data.php have the getEscapedCSVData function in it?
It appears that this function is added by SUPEE-7405. Have you patched your store with this SUPEE?
In my case some previous programer have copy the file
from core
\app\code\core\Mage\Core\Helper\Data.php
to local
app\code\local\Mage\Core\Helper\Data.php
and then apply SUPE PATCH 7405...
it cause that all modifications made by SUPE in data.php where rewrite by the old ones in local folder...
Solution: copy the new data.php to local or made a extension of class (better solution)
any body know that how to make check.php to verify the product key
when i check what are posting on check.php here the logs of method post
Sun, 18 May 2014 07:35:13 +0000a:6 {
s: 1: "u";
s: 44: "voN92KcXNxXQE1VrV+Muq4T/KuwziiyOT8rhwpcLZko=";
s: 1: "t";
s: 10: "1400398513";
s: 1: "p";
s: 88: "TVWb+BMcajJlu4+We5RfkCEMSRnvSjjx1pqTMuLRBftnWYkSJ2tMZuVezul2sYC5uXMW+qLLKJ7r87F5Cmp7QA==";
s: 1: "k";
s: 24: "493ppO3G+CVNZB0g3g6K2w==";
s: 1: "i";
s:128: "G133zJt4a1Csa+/LYCb7Q6NVvSNABx/Hyh3VxokaQy6AB/4vMxwSzh651jN+H5EBB3JCN54W2bzgBrEV3d7IpEfope3gO8iep9EbMDPujrlM5OSnLIdZx2g1aBLBGHLv";
s: 1: "v";
s: 24: "0rL3Iq61TBoDUi5piGG//A==";
}
and here is php code of that file if any body know how to make check.php please help me thanks
<?php
class Time {
protected $productKey = '';
protected $signature = null;
protected $expiry = 864000;
protected $installed = false;
protected $timestamp = 0;
protected $url = '';
/**
* License object constructor
*
* #access public
*/
public function __construct($productKey = array())
{
$this->url = 'http://www.example.com';
if (is_file(VISICHAT_ROOT . DS . 'config.php')) {
if (0 < filesize(VISICHAT_ROOT . DS . 'config.php')) {
$this->installed = true;
$productKey = Factory::getClass('config')->license;
}
}
$this->productKey = $productKey;
$this->fetchSignature();
}
/**
* Check whether the license is valid
*
* #return boolean
*/
public function isValid()
{
if ($this->getClass() == null) {
return false;
}
return $this->getClass()->check();
}
/**
* Downloads PHP class from the example server
*
* #return string
*/
public function fetchSignature()
{
if ($this->signature == null) {
$timestamp = 343;
if ($this->installed) {
$timestamp = Factory::getClass('Setting')->getNumber('signature_timestamp');
}
if ($timestamp < time() - $this->expiry) {
$this->timestamp = time();
$ch = curl_init();
$postdata = '&u=' . $this->encryptQuery(VIDEOCHAT_URL) . '&t=' . $this->timestamp . '&p=' . $this->encryptQuery(__FILE__) . '&k=' . $this->encryptQuery($this->productKey) . '&i=' . $this->encryptQuery(php_uname()) . '&v=' . $this->encryptQuery(Factory::getVersion());
if ($this->installed) {
$postdata .= '&d=' . $this->encryptQuery(Factory::getClass('config')->database) . '&a=' . $this->encryptQuery(Factory::getClass('Setting')->get('chat_app'));
}
curl_setopt($ch, CURLOPT_URL, 'license.example.com/check.php');
curl_setopt($ch, CURLOPT_USERAGENT, 'example');
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$this->signature = curl_exec($ch);
if ($this->installed) {
$setting = Factory::getClass('Setting');
$setting->saveProperty('signature', $this->signature);
$setting->saveProperty('signature_timestamp', $this->timestamp);
}
curl_close($ch);
}
else {
$this->signature = Factory::getClass('Setting')->get('signature');
}
}
return $this->signature;
}
/**
* Get the signature object
*
* #return class
*/
public function getClass()
{
$failedMessage = 'License verification failed.<br />Please double check your license details at: <a href=\'https://www.example.com/customers/\' target=\'_blank\'>example Customers Portal</a>';
$signature = $this->fetchSignature();
if (0 < strlen($signature)) {
$signature = $this->decrypt($signature);
}
if (substr(trim($signature), 0, 5) == 'class') {
if (!class_exists('Signature')) {
eval($signature);
}
if (class_exists('Signature')) {
$object = new Signature();
if ($this->installed) {
$setting = Factory::getClass('Setting');
$setting->saveProperty('update_contents_field', $object->getNotification());
}
return $object;
}
if ($this->installed) {
$setting = Factory::getClass('Setting');
$setting->saveProperty('update_contents_field', '<span class=\'expired\'>' . $failedMessage . '</span>');
return null;
}
} else {
if ($this->installed) {
$setting = Factory::getClass('Setting');
$setting->saveProperty('update_contents_field', '<span class=\'expired\'>' . $failedMessage . '</span>');
}
}
}
/**
* Encrypt the raw data
*
* #return decrypted string
*/
public function decrypt($data)
{
if (strlen($data) == 0) {
return '';
}
return openssl_decrypt($data, 'aes128', $this->getPassword(), false, $this->getIV());
}
/**
* Encrypt the query string data before posting
*
* #return decrypted string
*/
public function encryptQuery($data)
{
return urlencode(openssl_encrypt($data, 'aes128', substr(md5($this->url . $this->timestamp), 0, 16), false, substr(sha1($this->timestamp . $this->url), 0, 16)));
}
/**
* Encrypt the data with the given key
*
* #return encrypted data
*/
public function hashToken($token)
{
$code = $this->getClass()->getCode();
if ($code == '') {
$code = rand(10000000, 90000000);
}
return sha1($token . $code);
}
/**
* Get the initialization vector for the AES function
*
* #return string
*/
public function getIV()
{
$signature = $this->productKey . $this->getVideoChatURL() . 'example';
return substr(sha1(md5($signature) . $signature . 'example.com'), 0, 16);
}
/**
* Get the initialization vector for the AES function
*
* #return string
*/
public function getPassword()
{
$timestamp = $this->timestamp;
if ($this->installed) {
$timestamp = Factory::getClass('Setting')->getNumber('signature_timestamp');
}
$signature = $this->productKey . $this->getVideoChatURL() . __FILE__ . 'example' . $timestamp;
return sha1(sha1($signature . 'example.com') . $signature . 'www.example.com');
}
/**
* Get the video chat URL in format of http://yoursite.com/ (removes www.)
*
* #return string
*/
public function getVideoChatURL()
{
$videoChatURL = VIDEOCHAT_URL;
if (substr($videoChatURL, 0, 8) == 'https://') {
if (substr($videoChatURL, 0, 12) == 'https://www.') {
$videoChatURL = 'https://' . substr($videoChatURL, 12);
}
} else {
if (substr($videoChatURL, 0, 7) == 'http://') {
if (substr($videoChatURL, 0, 11) == 'http://www.') {
$videoChatURL = 'http://' . substr($videoChatURL, 11);
}
}
}
if (substr($videoChatURL, -1) != '/') {
$videoChatURL .= '/';
}
return $videoChatURL;
}
}
if (!(defined('VISICHAT_START'))) {
exit('Access Denied');
(bool)true;
}
?>
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I have some troubleshoot with µTorrent and I think you can help me.
My µTorrent doesn't receive any data about seeds and leeches
Here is my scrapement code:
<?php
class scrapement extends Core {
public function renderPage() {
if (!isset($_GET['info_hash']) || (strlen($_GET['info_hash']) != 20))
$this->error('Invalid hash');
$query = $this->query("SELECT `info_hash`, `seeders`, `leechers`, `times_completed` FROM `torrents` WHERE `info_hash` = '".$this->checkValues($_GET['info_hash'], 0)."'");
if(!mysql_num_rows($query)) {
$this->error('No torrent with that hash found');
}
$benc = "d5:files";
while ($row = $this->fetch($query))
{
$benc .= "d20:".str_pad($row["info_hash"], 20)."d8:completei".$row['seeders']."e10:downloadedi".$row['times_completed']."e10:incompletei".$row['leechers']."eee";
}
$benc .= 'ed5:flagsd20:min_request_intervali1800eee';
$this->getLog($benc);
header("Content-Type: text/plain");
header("Pragma: no-cache");
echo $benc;
}
private function error($err) {
header('Content-Type: text/plain; charset=UTF-8');
header('Pragma: no-cache');
exit("d14:failure reason".strlen($err).":{$err}ed5:flagsd20:min_request_intervali1800eeee");
}
}
?>
The logs from scrapement script: ($this->getLog($benc);)
d5:filesd20:êzo¦G{9…NÑ´ò43d8:completei1e10:downloadedi21e10:incompletei0eeeed5:flagsd20:min_request_intervali1800eee
as µTorrent has not any logs to view I tried with Ratio Master ...and... the scrapement it's working
[02:49:10] GET /scrapement?passkey=fe4d2xxxxxx&info_hash=B%c3%2c%e7%be%ec%2a%5c%a1%c4c%f8%c4M35%3f%f3%c6%e8 HTTP/1.1
Host:
User-Agent: uTorrent/1800
Accept-Encoding: gzip
so why the uTorrent doesn't receive any data?
You have an error in your bencoded data format. I recommend you use a proper encoding routine to convert data structures to bencoded format, rather than manually constructing the strings by concatenation. Here is a class which handles both encoding and decoding:
/**
* Encodes and decodes bencode formatted strings
*/
class BEncoder
{
/**
* Encode a value using the bencode format
*
* #param mixed $data The value to encode
*
* #return string The encoded value
*
* #throws \InvalidArgumentException When an unencodable value is encountered
*/
public function encode($data)
{
if (is_resource($data)) {
throw new \InvalidArgumentException('Resources cannot be bencoded');
}
// convert objects to arrays of public properties
// this makes it possible to sort dictionaries as required
if (is_object($data)) {
$data = get_object_vars($data);
}
if (is_string($data)) {
// byte sequence
$result = strlen($data) . ':' . $data;
} else if (is_int($data) || is_float($data) || is_bool($data)) {
// integer
$result = 'i' . round($data, 0) . 'e';
} else if (is_array($data)) {
if (array_values($data) === $data) {
// list
$result = 'l';
foreach ($data as $value) {
$result .= $this->encode($value);
}
} else if (is_array($data)) {
// dictionary
ksort($data);
$result = 'd';
foreach ($data as $key => $value) {
$result .= $this->encode((string) $key) . $this->encode($value);
}
}
$result .= 'e';
}
return $result;
}
/**
* Decode a value using the bencode format
*
* #param string $data The value to decode
*
* #return mixed The decoded value
*
* #throws \InvalidArgumentException When an undecodable value is encountered
*/
public function decode($data)
{
if (!is_string($data)) {
throw new \InvalidArgumentException('Data is not a valid bencoded string');
}
$data = trim($data);
try {
$result = $this->decodeComponent($data, $position);
if ($data !== '') {
throw new \InvalidArgumentException('Data found after end of value');
}
} catch (\InvalidArgumentException $e) {
$err = 'Syntax error at character ' . $position . ' "' . substr($data, 0, 7) . '..."): ' . $e->getMessage();
throw new \InvalidArgumentException($err);
}
return $result;
}
/**
* Move the pointer in the data currently being decoded
*
* #param string $data The data being decoded
* #param int $position The position pointer
* #param int $count The number of bytes to move the pointer
*/
private function movePointer(&$data, &$position, $count)
{
$data = (string) substr($data, $count);
$position += $count;
}
/**
* Recursively decode a structure from a data string
*
* #param string $data The data being decoded
* #param int $position The position pointer
*
* #return mixed The decoded value
*
* #throws \InvalidArgumentException When an undecodable value is encountered
*/
private function decodeComponent(&$data, &$position = 0)
{
switch ($data[0]) {
case 'i':
if (!preg_match('/^i(-?\d+)e/', $data, $matches)) {
throw new \InvalidArgumentException('Invalid integer');
}
$this->movePointer($data, $position, strlen($matches[0]));
return (int) $matches[1];
case 'l':
$this->movePointer($data, $position, 1);
if ($data === '') {
throw new \InvalidArgumentException('Unexpected end of list');
}
$result = array();
while ($data[0] !== 'e') {
$value = $this->decodeComponent($data, $position);
if ($data === '') {
throw new \InvalidArgumentException('Unexpected end of list');
}
$result[] = $value;
}
$this->movePointer($data, $position, 1);
return $result;
case 'd':
$this->movePointer($data, $position, 1);
if ($data === '') {
throw new \InvalidArgumentException('Unexpected end of dictionary');
}
$result = array();
while ($data[0] !== 'e') {
$key = $this->decodeComponent($data, $position);
if ($data === '') {
throw new \InvalidArgumentException('Unexpected end of dictionary');
}
$value = $this->decodeComponent($data, $position);
if ($data === '') {
throw new \InvalidArgumentException('Unexpected end of dictionary');
}
$result[$key] = $value;
}
$this->movePointer($data, $position, 1);
return $result;
default:
if (!preg_match('/^(\d+):/', $data, $matches)) {
throw new \InvalidArgumentException('Unknown data type');
}
$this->movePointer($data, $position, strlen($matches[0]));
if (strlen($data) < $matches[1]) {
$this->movePointer($data, $position, strlen($data));
throw new \InvalidArgumentException('Unexpected end of byte string');
}
$result = substr($data, 0, $matches[1]);
$this->movePointer($data, $position, $matches[1]);
return $result;
}
}
}
To use it with your code you would do something like this:
class scrapement extends Core
{
private $bencoder;
public function __construct($bencoder)
{
// inject an instance of the BEncoder class into this object
$this->bencoder = $bencoder;
}
public function renderPage()
{
if (!isset($_GET['info_hash']) || (strlen($_GET['info_hash']) != 20)) {
$this->error('Invalid hash');
}
$query = $this->query("
SELECT `info_hash`, `seeders`, `leechers`, `times_completed`
FROM `torrents`
WHERE `info_hash` = '" . $this->checkValues($_GET['info_hash'], 0) . "'
");
if (!mysql_num_rows($query)) {
$this->error('No torrent with that hash found');
}
$data = array(
'flags' => array(
'min_request_interval' => 1800
),
'files' => array()
);
while ($row = $this->fetch($query)) {
$hash = str_pad($row["info_hash"], 20);
$data['files'][$hash] = array(
'complete' => $row['seeders'],
'incomplete' => $row['leechers'],
'downloaded' => $row['times_completed']
);
}
$data = $this->bencoder->encode($data);
$this->getLog($data);
header("Content-Type: text/plain");
header("Pragma: no-cache");
echo $data;
}
private function error($err)
{
$data = array(
'flags' => array(
'min_request_interval' => 1800
),
'failure reason' => $err
);
$data = $this->bencoder->encode($data);
$this->getLog($data);
header('Content-Type: text/plain; charset=UTF-8');
header('Pragma: no-cache');
echo $data;
}
}
Why this code return "" :
$ip = "";
if(getenv("HTTP_CLIENT_IP"))
{
$ip = getenv("HTTP_CLIENT_IP");
} elseif(getenv("HTTP_X_FORWARDED_FOR")) {
$ip = getenv("HTTP_X_FORWARDED_FOR");
} else {
$ip = getenv("REMOTE_ADDR");
}
Environment: W2003EE, IIS 6.0, PHP 5.2.9 (ISAPI)
$_SERVER is a built-in PHP variable.
getenv() looks at the current
environment.
In my case i need to use $_SERVER. Thank all!
Try $_SERVER['REMOTE_ADDR'] or $_SERVER['HTTP_X_FORWARDED_FOR']
If you wonder what is set you can dump $_SERVER somewhere.
The value of environment variable REMOTE_ADDR must be empty or not set. If working on linux check its value on terminal by the command echo $REMOTE_ADDR. If it returns null, sets its value before assigning $ip.
The problem may have something to do with IIS working a bit differently. I've had success with these two function from the CakePHP project.
/**
* Gets remote client IP
*
* #return string Client IP address
* #access public
*/
function getClientIP($safe = true) {
if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
$ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
} else {
if (env('HTTP_CLIENT_IP') != null) {
$ipaddr = env('HTTP_CLIENT_IP');
} else {
$ipaddr = env('REMOTE_ADDR');
}
}
if (env('HTTP_CLIENTADDRESS') != null) {
$tmpipaddr = env('HTTP_CLIENTADDRESS');
if (!empty($tmpipaddr)) {
$ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
}
}
return trim($ipaddr);
}
/**
* Gets an environment variable from available sources, and provides emulation
* for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
* IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
* environment information.
*
* #param string $key Environment variable name.
* #return string Environment variable setting.
* #link http://book.cakephp.org/view/701/env
*/
function env($key) {
if ($key == 'HTTPS') {
if (isset($_SERVER['HTTPS'])) {
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
}
return (strpos(env('SCRIPT_URI'), 'https://') === 0);
}
if ($key == 'SCRIPT_NAME') {
if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
$key = 'SCRIPT_URL';
}
}
$val = null;
if (isset($_SERVER[$key])) {
$val = $_SERVER[$key];
} elseif (isset($_ENV[$key])) {
$val = $_ENV[$key];
} elseif (getenv($key) !== false) {
$val = getenv($key);
}
if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
$addr = env('HTTP_PC_REMOTE_ADDR');
if ($addr !== null) {
$val = $addr;
}
}
if ($val !== null) {
return $val;
}
switch ($key) {
case 'SCRIPT_FILENAME':
if (defined('SERVER_IIS') && SERVER_IIS === true) {
return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
}
break;
case 'DOCUMENT_ROOT':
$name = env('SCRIPT_NAME');
$filename = env('SCRIPT_FILENAME');
$offset = 0;
if (!strpos($name, '.php')) {
$offset = 4;
}
return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
break;
case 'PHP_SELF':
return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
break;
case 'CGI_MODE':
return (PHP_SAPI === 'cgi');
break;
case 'HTTP_BASE':
$host = env('HTTP_HOST');
if (substr_count($host, '.') !== 1) {
return preg_replace('/^([^.])*/i', null, env('HTTP_HOST'));
}
return '.' . $host;
break;
}
return null;
}