Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
OpnSense
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kulya
OpnSense
Commits
ad276991
Commit
ad276991
authored
Jan 04, 2015
by
Ad Schellevis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code styling fixes (PSR) for captive new captive portal code
parent
6e46796a
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
840 additions
and
603 deletions
+840
-603
captiveportal.inc
src/etc/inc/captiveportal.inc
+3
-3
ARP.php
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/ARP.php
+26
-23
CPClient.php
...nsense/mvc/app/models/OPNsense/CaptivePortal/CPClient.php
+402
-316
DB.php
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/DB.php
+157
-90
Rules.php
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/Rules.php
+121
-78
Config.php
src/opnsense/mvc/app/models/OPNsense/Core/Config.php
+77
-55
ConfigException.php
...opnsense/mvc/app/models/OPNsense/Core/ConfigException.php
+17
-0
Shell.php
src/opnsense/mvc/app/models/OPNsense/Core/Shell.php
+31
-28
Singleton.php
src/opnsense/mvc/app/models/OPNsense/Core/Singleton.php
+5
-9
status_captiveportal.php
src/www/status_captiveportal.php
+1
-1
No files found.
src/etc/inc/captiveportal.inc
View file @
ad276991
...
@@ -172,7 +172,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
...
@@ -172,7 +172,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
}
}
$sessionid
=
$cpc
->
portal
_a
llow
(
$cpzone
,
$clientip
,
$clientmac
,
$username
,
$password
,
$bw_up
,
$bw_down
,
$radiusctx
,
$session_timeout
,
$idle_timeout
,
$session_terminate_time
,
$interim_interval
);
$sessionid
=
$cpc
->
portal
A
llow
(
$cpzone
,
$clientip
,
$clientmac
,
$username
,
$password
,
$bw_up
,
$bw_down
,
$radiusctx
,
$session_timeout
,
$idle_timeout
,
$session_terminate_time
,
$interim_interval
);
if
(
isset
(
$config
[
'captiveportal'
][
$cpzone
][
'radacct_enable'
])
&&
!
empty
(
$radiusservers
[
$radiusctx
]))
{
if
(
isset
(
$config
[
'captiveportal'
][
$cpzone
][
'radacct_enable'
])
&&
!
empty
(
$radiusservers
[
$radiusctx
]))
{
$acct_val
=
RADIUS_ACCOUNTING_START
(
$pipeno
,
$username
,
$sessionid
,
$radiusservers
[
$radiusctx
],
$clientip
,
$clientmac
);
$acct_val
=
RADIUS_ACCOUNTING_START
(
$pipeno
,
$username
,
$sessionid
,
$radiusservers
[
$radiusctx
],
$clientip
,
$clientmac
);
...
@@ -699,11 +699,11 @@ function captiveportal_prune_old() {
...
@@ -699,11 +699,11 @@ function captiveportal_prune_old() {
$cpcfg
=
$config
[
'captiveportal'
][
$cpzone
];
$cpcfg
=
$config
[
'captiveportal'
][
$cpzone
];
if
(
!
isset
(
$cpcfg
[
'radacct_enable'
]))
{
if
(
!
isset
(
$cpcfg
[
'radacct_enable'
]))
{
// cleanup session (default)
// cleanup session (default)
$cpc
->
portal
_cleanup_s
essions
(
$cpzone
);
$cpc
->
portal
CleanupS
essions
(
$cpzone
);
}
else
{
}
else
{
// cleanup sessions if radius accounting is enable
// cleanup sessions if radius accounting is enable
// TODO: this code needs a rewrite, probably the easiest thing todo is update the zone administration and run
// TODO: this code needs a rewrite, probably the easiest thing todo is update the zone administration and run
// the normal cleanup (portal
_cleanup_s
essions) to detach both processes
// the normal cleanup (portal
CleanupS
essions) to detach both processes
//
//
$vcpcfg
=
$config
[
'voucher'
][
$cpzone
];
$vcpcfg
=
$config
[
'voucher'
][
$cpzone
];
...
...
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/ARP.php
View file @
ad276991
...
@@ -41,7 +41,7 @@ class ARP
...
@@ -41,7 +41,7 @@ class ARP
* pointer to shell object
* pointer to shell object
* @var \Core\Shell
* @var \Core\Shell
*/
*/
private
$shell
;
private
$shell
;
/**
/**
* construct new ARP table handlers
* construct new ARP table handlers
...
@@ -59,11 +59,9 @@ class ARP
...
@@ -59,11 +59,9 @@ class ARP
public
function
setStatic
(
$ipaddress
,
$mac
)
public
function
setStatic
(
$ipaddress
,
$mac
)
{
{
// validate input, only set static entries for valid addresses
// validate input, only set static entries for valid addresses
if
(
preg_match
(
'/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/'
,
trim
(
$mac
)))
if
(
preg_match
(
'/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/'
,
trim
(
$mac
)))
{
{
if
(
filter_var
(
$ipaddress
,
FILTER_VALIDATE_IP
,
FILTER_FLAG_IPV4
|
FILTER_FLAG_IPV6
))
{
if
(
filter_var
(
$ipaddress
,
FILTER_VALIDATE_IP
,
FILTER_FLAG_IPV4
|
FILTER_FLAG_IPV6
)
)
$this
->
shell
->
exec
(
"/usr/sbin/arp -s "
.
trim
(
$ipaddress
)
.
" "
.
trim
(
$mac
));
{
$this
->
shell
->
exec
(
"/usr/sbin/arp -s "
.
trim
(
$ipaddress
)
.
" "
.
trim
(
$mac
));
}
}
}
}
}
}
...
@@ -72,41 +70,46 @@ class ARP
...
@@ -72,41 +70,46 @@ class ARP
* drop static arp entry
* drop static arp entry
* @param $ipaddress hosts ipaddress
* @param $ipaddress hosts ipaddress
*/
*/
function
dropStatic
(
$ipaddress
){
public
function
dropStatic
(
$ipaddress
)
{
// validate input, drop arp entry
// validate input, drop arp entry
if
(
filter_var
(
$ipaddress
,
FILTER_VALIDATE_IP
,
FILTER_FLAG_IPV4
|
FILTER_FLAG_IPV6
)
)
{
if
(
filter_var
(
$ipaddress
,
FILTER_VALIDATE_IP
,
FILTER_FLAG_IPV4
|
FILTER_FLAG_IPV6
))
{
$this
->
shell
->
exec
(
"/usr/sbin/arp -d "
.
trim
(
$ipaddress
)
);
$this
->
shell
->
exec
(
"/usr/sbin/arp -d "
.
trim
(
$ipaddress
)
);
}
}
}
}
/**
/**
* Return arp table hashed by mac address
* Return arp table hashed by mac address
*/
*/
function
getMACs
(){
public
function
getMACs
()
{
$result
=
array
();
$result
=
array
();
$shell_output
=
array
();
$shell_output
=
array
();
// execute arp shell command and collect (only valid) info into named array
// execute arp shell command and collect (only valid) info into named array
if
(
$this
->
shell
->
exec
(
"arp -an"
,
false
,
false
,
$shell_output
)
==
0
)
{
if
(
$this
->
shell
->
exec
(
"arp -an"
,
false
,
false
,
$shell_output
)
==
0
)
{
foreach
(
$shell_output
as
$line
)
{
foreach
(
$shell_output
as
$line
)
{
$line_parts
=
explode
(
" "
,
$line
)
;
$line_parts
=
explode
(
" "
,
$line
)
;
if
(
sizeof
(
$line_parts
)
>=
4
)
{
if
(
sizeof
(
$line_parts
)
>=
4
)
{
$ipaddress
=
substr
(
$line_parts
[
1
],
1
,
strlen
(
$line_parts
[
1
])
-
2
)
;
$ipaddress
=
substr
(
$line_parts
[
1
],
1
,
strlen
(
$line_parts
[
1
])
-
2
)
;
// reformat mac addresses, sometimes arp return segments without trailing zero's
// reformat mac addresses, sometimes arp return segments without trailing zero's
$mac_raw
=
strtolower
(
$line_parts
[
3
]);
$mac_raw
=
strtolower
(
$line_parts
[
3
]);
$mac
=
""
;
$mac
=
""
;
foreach
(
explode
(
":"
,
$mac_raw
)
as
$segment
){
foreach
(
explode
(
":"
,
$mac_raw
)
as
$segment
)
{
if
(
$mac
!=
""
)
$mac
.=
":"
;
if
(
$mac
!=
""
)
{
if
(
strlen
(
$segment
)
==
1
)
$mac
.=
"0"
.
$segment
;
$mac
.=
":"
;
else
$mac
.=
$segment
;
}
if
(
strlen
(
$segment
)
==
1
)
{
$mac
.=
"0"
.
$segment
;
}
else
{
$mac
.=
$segment
;
}
}
}
if
(
preg_match
(
'/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/'
,
trim
(
$mac
))){
if
(
preg_match
(
'/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/'
,
trim
(
$mac
)))
{
$result
[
$mac
]
=
array
(
'ip'
=>
$ipaddress
);
$result
[
$mac
]
=
array
(
'ip'
=>
$ipaddress
);
}
}
}
}
}
}
}
}
return
$result
;
return
$result
;
}
}
}
}
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/CPClient.php
View file @
ad276991
This diff is collapsed.
Click to expand it.
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/DB.php
View file @
ad276991
This diff is collapsed.
Click to expand it.
src/opnsense/mvc/app/models/OPNsense/CaptivePortal/Rules.php
View file @
ad276991
This diff is collapsed.
Click to expand it.
src/opnsense/mvc/app/models/OPNsense/Core/Config.php
View file @
ad276991
...
@@ -34,17 +34,14 @@
...
@@ -34,17 +34,14 @@
namespace
OPNsense\Core
;
namespace
OPNsense\Core
;
/**
use
\Phalcon\DI\FactoryDefault
;
* Class ConfigException
* @package Core
*/
class
ConfigException
extends
\Exception
{
}
/**
/**
* Class Config
* Class Config
* @package Core
* @package Core
*/
*/
class
Config
extends
Singleton
{
class
Config
extends
Singleton
{
/**
/**
* config file location ( path + name )
* config file location ( path + name )
...
@@ -68,32 +65,52 @@ class Config extends Singleton {
...
@@ -68,32 +65,52 @@ class Config extends Singleton {
* status field: valid config loaded
* status field: valid config loaded
* @var bool
* @var bool
*/
*/
private
$isValid
=
F
alse
;
private
$isValid
=
f
alse
;
/**
/**
* Load config file
* print config xml in dot notation
* @param DOMNode $node
* @param string $nodename
* @throws ConfigException
* @throws ConfigException
*/
*/
p
rivate
function
load
(){
p
ublic
function
dump
(
$node
=
null
,
$nodename
=
""
)
// exception handling
{
if
(
!
file_exists
(
$this
->
config_file
)
)
throw
new
ConfigException
(
'file not found'
)
;
$this
->
checkvalid
()
;
$xml
=
file_get_contents
(
$this
->
config_file
);
// root node
if
(
trim
(
$xml
)
==
''
)
{
if
(
$node
==
null
)
{
throw
new
ConfigException
(
'empty file'
)
;
$node
=
$this
->
configxml
;
}
}
$this
->
configxml
=
new
\DOMDocument
;
$subNodes
=
$node
->
childNodes
;
$this
->
configxml
->
loadXML
(
$xml
);
foreach
(
$subNodes
as
$subNode
)
{
$this
->
simplexml
=
simplexml_import_dom
(
$this
->
configxml
);
if
(
$subNode
->
nodeType
==
XML_TEXT_NODE
&&
(
strlen
(
trim
(
$subNode
->
wholeText
))
>=
1
))
{
$this
->
isValid
=
true
;
print
(
$nodename
.
"."
.
$node
->
tagName
.
" "
.
$subNode
->
nodeValue
.
"
\n
"
);
}
if
(
$subNode
->
hasChildNodes
())
{
if
(
$nodename
!=
""
)
{
$tmp
=
$nodename
.
"."
.
$node
->
tagName
;
}
elseif
(
$node
!=
$this
->
configxml
)
{
$tmp
=
$node
->
tagName
;
}
else
{
$tmp
=
""
;
}
$this
->
dump
(
$subNode
,
$tmp
);
}
}
}
}
/**
/**
* @throws ConfigException
* @throws ConfigException
*/
*/
private
function
checkvalid
(){
private
function
checkvalid
()
if
(
!
$this
->
isValid
)
throw
new
ConfigException
(
'no valid config loaded'
)
;
{
if
(
!
$this
->
isValid
)
{
throw
new
ConfigException
(
'no valid config loaded'
)
;
}
}
}
/*
/*
...
@@ -102,41 +119,23 @@ class Config extends Singleton {
...
@@ -102,41 +119,23 @@ class Config extends Singleton {
* @param string $nodename
* @param string $nodename
* @throws ConfigException
* @throws ConfigException
*/
*/
public
function
dump
(
$node
=
null
,
$nodename
=
""
){
$this
->
checkvalid
();
// root node
if
(
$node
==
null
)
$node
=
$this
->
configxml
;
$subNodes
=
$node
->
childNodes
;
foreach
(
$subNodes
as
$subNode
){
if
(
$subNode
->
nodeType
==
XML_TEXT_NODE
&&
(
strlen
(
trim
(
$subNode
->
wholeText
))
>=
1
))
{
print
(
$nodename
.
"."
.
$node
->
tagName
.
" "
.
$subNode
->
nodeValue
.
"
\n
"
);
}
if
(
$subNode
->
hasChildNodes
()
){
if
(
$nodename
!=
""
)
$tmp
=
$nodename
.
"."
.
$node
->
tagName
;
elseif
(
$node
!=
$this
->
configxml
)
$tmp
=
$node
->
tagName
;
else
$tmp
=
""
;
$this
->
dump
(
$subNode
,
$tmp
);
}
}
public
function
xpath
(
$query
)
{
$this
->
checkvalid
();
$xpath
=
new
\DOMXPath
(
$this
->
configxml
);
return
$xpath
->
query
(
$query
);
}
}
/*
/*
* init new config object, try to load current configuration
* init new config object, try to load current configuration
* (executed via Singleton)
* (executed via Singleton)
*/
*/
protected
function
init
()
{
$this
->
config_file
=
\Phalcon\DI\FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
config_path
.
"config.xml"
;
try
{
$this
->
load
();
}
catch
(
\Exception
$e
){
$this
->
configxml
=
null
;
}
public
function
object
()
{
$this
->
checkvalid
();
return
$this
->
simplexml
;
}
}
/*
/*
...
@@ -145,10 +144,16 @@ class Config extends Singleton {
...
@@ -145,10 +144,16 @@ class Config extends Singleton {
* @return \DOMNodeList
* @return \DOMNodeList
* @throws ConfigException
* @throws ConfigException
*/
*/
function
xpath
(
$query
){
$this
->
checkvalid
();
protected
function
init
()
$xpath
=
new
\DOMXPath
(
$this
->
configxml
);
{
return
$xpath
->
query
(
$query
);
$this
->
config_file
=
FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
config_path
.
"config.xml"
;
try
{
$this
->
load
();
}
catch
(
\Exception
$e
)
{
$this
->
configxml
=
null
;
}
}
}
/*
/*
...
@@ -156,9 +161,26 @@ class Config extends Singleton {
...
@@ -156,9 +161,26 @@ class Config extends Singleton {
* @return SimpleXML
* @return SimpleXML
* @throws ConfigException
* @throws ConfigException
*/
*/
function
object
(){
$this
->
checkvalid
();
return
$this
->
simplexml
;
}
/**
* Load config file
* @throws ConfigException
*/
private
function
load
()
{
// exception handling
if
(
!
file_exists
(
$this
->
config_file
))
{
throw
new
ConfigException
(
'file not found'
)
;
}
$xml
=
file_get_contents
(
$this
->
config_file
);
if
(
trim
(
$xml
)
==
''
)
{
throw
new
ConfigException
(
'empty file'
)
;
}
$this
->
configxml
=
new
\DOMDocument
;
$this
->
configxml
->
loadXML
(
$xml
);
$this
->
simplexml
=
simplexml_import_dom
(
$this
->
configxml
);
$this
->
isValid
=
true
;
}
}
}
src/opnsense/mvc/app/models/OPNsense/Core/ConfigException.php
0 → 100644
View file @
ad276991
<?php
/**
* Created by PhpStorm.
* User: ad
* Date: 04-01-15
* Time: 20:06
*/
namespace
app\models\OPNsense\Core
;
/**
* Class ConfigException
* @package Core
*/
class
ConfigException
extends
\Exception
{
}
src/opnsense/mvc/app/models/OPNsense/Core/Shell.php
View file @
ad276991
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
namespace
OPNsense\Core
;
namespace
OPNsense\Core
;
use
\Phalcon\DI\FactoryDefault
;
class
Shell
class
Shell
{
{
...
@@ -52,11 +53,31 @@ class Shell
...
@@ -52,11 +53,31 @@ class Shell
/**
/**
* new shell object
* new shell object
*/
*/
function
__construct
()
public
function
__construct
()
{
{
// init, set simulation mode / debug autoput
// init, set simulation mode / debug autoput
$this
->
simulate
=
\Phalcon\DI\FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
simulate_mode
;
$this
->
simulate
=
FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
simulate_mode
;
$this
->
debug
=
\Phalcon\DI\FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
debug
;
$this
->
debug
=
FactoryDefault
::
getDefault
()
->
get
(
'config'
)
->
globals
->
debug
;
}
/**
* execute command or list of commands
*
* @param string/Array() $command command to execute
* @param bool $mute
* @param bool $clearsigmask
* @param Array() &$output
*/
public
function
exec
(
$command
,
$mute
=
false
,
$clearsigmask
=
false
,
&
$output
=
null
)
{
if
(
is_array
(
$command
))
{
foreach
(
$command
as
$comm
)
{
$this
->
execSingle
(
$comm
,
$mute
,
$clearsigmask
,
$output
);
}
}
else
{
$this
->
execSingle
(
$command
,
$mute
,
$clearsigmask
,
$output
);
}
}
}
...
@@ -65,8 +86,11 @@ class Shell
...
@@ -65,8 +86,11 @@ class Shell
* @param string $command command to execute
* @param string $command command to execute
* @param bool $mute
* @param bool $mute
* @param bool $clearsigmask
* @param bool $clearsigmask
* @param Array() &$output
* @return int
*/
*/
private
function
_exec
(
$command
,
$mute
=
false
,
$clearsigmask
=
false
,
&
$output
=
null
){
private
function
execSingle
(
$command
,
$mute
=
false
,
$clearsigmask
=
false
,
&
$output
=
null
)
{
$oarr
=
array
();
$oarr
=
array
();
$retval
=
0
;
$retval
=
0
;
...
@@ -82,10 +106,11 @@ class Shell
...
@@ -82,10 +106,11 @@ class Shell
pcntl_sigprocmask
(
SIG_SETMASK
,
array
(),
$oldset
);
pcntl_sigprocmask
(
SIG_SETMASK
,
array
(),
$oldset
);
}
}
$garbage
=
exec
(
"
$command
2>&1"
,
$output
,
$retval
);
exec
(
"
$command
2>&1"
,
$output
,
$retval
);
if
((
$retval
<>
0
)
&&
(
$mute
===
false
))
{
if
((
$retval
<>
0
)
&&
(
$mute
===
false
))
{
//log_error(sprintf(gettext("The command '%1\$s' returned exit code '%2\$d', the output was '%3\$s' "), implode(" ", $output);
//log_error(sprintf(gettext("The command '%1\$s'
// returned exit code '%2\$d', the output was '%3\$s' "), implode(" ", $output);
// TODO: log
// TODO: log
unset
(
$output
);
unset
(
$output
);
}
}
...
@@ -101,26 +126,4 @@ class Shell
...
@@ -101,26 +126,4 @@ class Shell
return
null
;
return
null
;
}
}
/**
* execute command or list of commands
*
* @param string/Array() $command command to execute
* @param bool $mute
* @param bool $clearsigmask
* @param Array() &$output
*/
function
exec
(
$command
,
$mute
=
false
,
$clearsigmask
=
false
,
&
$output
=
null
)
{
if
(
is_array
(
$command
)){
foreach
(
$command
as
$comm
){
$this
->
_exec
(
$comm
,
$mute
,
$clearsigmask
,
$output
);
}
}
else
{
$this
->
_exec
(
$command
,
$mute
,
$clearsigmask
,
$output
);
}
}
}
}
src/opnsense/mvc/app/models/OPNsense/Core/Singleton.php
View file @
ad276991
...
@@ -33,11 +33,6 @@
...
@@ -33,11 +33,6 @@
namespace
OPNsense\Core
;
namespace
OPNsense\Core
;
/**
* Class Singleton
* @package Core
*/
/**
/**
* Class Singleton
* Class Singleton
* @package Core
* @package Core
...
@@ -65,7 +60,7 @@ abstract class Singleton
...
@@ -65,7 +60,7 @@ abstract class Singleton
*/
*/
final
private
function
__clone
()
final
private
function
__clone
()
{
{
throw
new
\Exception
(
"An instance of "
.
get_called_class
()
.
" cannot be cloned."
);
throw
new
\Exception
(
"An instance of "
.
get_called_class
()
.
" cannot be cloned."
);
}
}
/**
/**
...
@@ -76,7 +71,7 @@ abstract class Singleton
...
@@ -76,7 +71,7 @@ abstract class Singleton
{
{
$className
=
get_called_class
();
$className
=
get_called_class
();
if
(
isset
(
self
::
$instances
[
$className
])
==
false
)
{
if
(
isset
(
self
::
$instances
[
$className
])
==
false
)
{
self
::
$instances
[
$className
]
=
new
static
();
self
::
$instances
[
$className
]
=
new
static
();
}
}
return
self
::
$instances
[
$className
];
return
self
::
$instances
[
$className
];
...
@@ -88,6 +83,7 @@ abstract class Singleton
...
@@ -88,6 +83,7 @@ abstract class Singleton
* so an extended class could simply
* so an extended class could simply
* specify its own init
* specify its own init
*/
*/
protected
function
init
(){}
protected
function
init
()
{
}
}
}
src/www/status_captiveportal.php
View file @
ad276991
...
@@ -79,7 +79,7 @@ if (!empty($cpzone)) {
...
@@ -79,7 +79,7 @@ if (!empty($cpzone)) {
$cpdb
=
$cpdb_handle
->
listClients
(
array
(),
"and"
,
array
(
$order
)
)
;
$cpdb
=
$cpdb_handle
->
listClients
(
array
(),
"and"
,
array
(
$order
)
)
;
if
(
$_GET
[
'showact'
])
{
if
(
$_GET
[
'showact'
])
{
$accounting_info
=
$cpclient_handle
->
list
_a
ccounting
();
$accounting_info
=
$cpclient_handle
->
list
A
ccounting
();
}
}
else
{
else
{
$accounting_info
=
array
()
;
$accounting_info
=
array
()
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment