/**
* HTTP API: WP_Http_Curl class
*
* @package WordPress
* @subpackage HTTP
* @since 4.4.0
*/
/**
* Core class used to integrate Curl as an HTTP transport.
*
* HTTP request method uses Curl extension to retrieve the url.
*
* Requires the Curl extension to be installed.
*
* @since 2.7.0
* @deprecated 6.4.0 Use WP_Http
* @see WP_Http
*/
#[AllowDynamicProperties]
class WP_Http_Curl {
/**
* Temporary header storage for during requests.
*
* @since 3.2.0
* @var string
*/
private $headers = '';
/**
* Temporary body storage for during requests.
*
* @since 3.6.0
* @var string
*/
private $body = '';
/**
* The maximum amount of data to receive from the remote server.
*
* @since 3.6.0
* @var int|false
*/
private $max_body_length = false;
/**
* The file resource used for streaming to file.
*
* @since 3.6.0
* @var resource|false
*/
private $stream_handle = false;
/**
* The total bytes written in the current request.
*
* @since 4.1.0
* @var int
*/
private $bytes_written_total = 0;
/**
* Send a HTTP request to a URI using cURL extension.
*
* @since 2.7.0
*
* @param string $url The request URL.
* @param string|array $args Optional. Override the defaults.
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
*/
public function request( $url, $args = array() ) {
$defaults = array(
'method' => 'GET',
'timeout' => 5,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'body' => null,
'cookies' => array(),
'decompress' => false,
'stream' => false,
'filename' => null,
);
$parsed_args = wp_parse_args( $args, $defaults );
if ( isset( $parsed_args['headers']['User-Agent'] ) ) {
$parsed_args['user-agent'] = $parsed_args['headers']['User-Agent'];
unset( $parsed_args['headers']['User-Agent'] );
} elseif ( isset( $parsed_args['headers']['user-agent'] ) ) {
$parsed_args['user-agent'] = $parsed_args['headers']['user-agent'];
unset( $parsed_args['headers']['user-agent'] );
}
// Construct Cookie: header if any cookies are set.
WP_Http::buildCookieHeader( $parsed_args );
$handle = curl_init();
// cURL offers really easy proxy support.
$proxy = new WP_HTTP_Proxy();
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
curl_setopt( $handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
curl_setopt( $handle, CURLOPT_PROXY, $proxy->host() );
curl_setopt( $handle, CURLOPT_PROXYPORT, $proxy->port() );
if ( $proxy->use_authentication() ) {
curl_setopt( $handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
curl_setopt( $handle, CURLOPT_PROXYUSERPWD, $proxy->authentication() );
}
}
$is_local = isset( $parsed_args['local'] ) && $parsed_args['local'];
$ssl_verify = isset( $parsed_args['sslverify'] ) && $parsed_args['sslverify'];
if ( $is_local ) {
/** This filter is documented in wp-includes/class-wp-http-streams.php */
$ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify, $url );
} elseif ( ! $is_local ) {
/** This filter is documented in wp-includes/class-wp-http.php */
$ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify, $url );
}
/*
* CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT expect integers. Have to use ceil since.
* a value of 0 will allow an unlimited timeout.
*/
$timeout = (int) ceil( $parsed_args['timeout'] );
curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, $timeout );
curl_setopt( $handle, CURLOPT_TIMEOUT, $timeout );
curl_setopt( $handle, CURLOPT_URL, $url );
curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, ( true === $ssl_verify ) ? 2 : false );
curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, $ssl_verify );
if ( $ssl_verify ) {
curl_setopt( $handle, CURLOPT_CAINFO, $parsed_args['sslcertificates'] );
}
curl_setopt( $handle, CURLOPT_USERAGENT, $parsed_args['user-agent'] );
/*
* The option doesn't work with safe mode or when open_basedir is set, and there's
* a bug #17490 with redirected POST requests, so handle redirections outside Curl.
*/
curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, false );
curl_setopt( $handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
switch ( $parsed_args['method'] ) {
case 'HEAD':
curl_setopt( $handle, CURLOPT_NOBODY, true );
break;
case 'POST':
curl_setopt( $handle, CURLOPT_POST, true );
curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] );
break;
case 'PUT':
curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, 'PUT' );
curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] );
break;
default:
curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, $parsed_args['method'] );
if ( ! is_null( $parsed_args['body'] ) ) {
curl_setopt( $handle, CURLOPT_POSTFIELDS, $parsed_args['body'] );
}
break;
}
if ( true === $parsed_args['blocking'] ) {
curl_setopt( $handle, CURLOPT_HEADERFUNCTION, array( $this, 'stream_headers' ) );
curl_setopt( $handle, CURLOPT_WRITEFUNCTION, array( $this, 'stream_body' ) );
}
curl_setopt( $handle, CURLOPT_HEADER, false );
if ( isset( $parsed_args['limit_response_size'] ) ) {
$this->max_body_length = (int) $parsed_args['limit_response_size'];
} else {
$this->max_body_length = false;
}
// If streaming to a file open a file handle, and setup our curl streaming handler.
if ( $parsed_args['stream'] ) {
if ( ! WP_DEBUG ) {
$this->stream_handle = @fopen( $parsed_args['filename'], 'w+' );
} else {
$this->stream_handle = fopen( $parsed_args['filename'], 'w+' );
}
if ( ! $this->stream_handle ) {
return new WP_Error(
'http_request_failed',
sprintf(
/* translators: 1: fopen(), 2: File name. */
__( 'Could not open handle for %1$s to %2$s.' ),
'fopen()',
$parsed_args['filename']
)
);
}
} else {
$this->stream_handle = false;
}
if ( ! empty( $parsed_args['headers'] ) ) {
// cURL expects full header strings in each element.
$headers = array();
foreach ( $parsed_args['headers'] as $name => $value ) {
$headers[] = "{$name}: $value";
}
curl_setopt( $handle, CURLOPT_HTTPHEADER, $headers );
}
if ( '1.0' === $parsed_args['httpversion'] ) {
curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );
} else {
curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
}
/**
* Fires before the cURL request is executed.
*
* Cookies are not currently handled by the HTTP API. This action allows
* plugins to handle cookies themselves.
*
* @since 2.8.0
*
* @param resource $handle The cURL handle returned by curl_init() (passed by reference).
* @param array $parsed_args The HTTP request arguments.
* @param string $url The request URL.
*/
do_action_ref_array( 'http_api_curl', array( &$handle, $parsed_args, $url ) );
// We don't need to return the body, so don't. Just execute request and return.
if ( ! $parsed_args['blocking'] ) {
curl_exec( $handle );
$curl_error = curl_error( $handle );
if ( $curl_error ) {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return new WP_Error( 'http_request_failed', $curl_error );
}
if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ), true ) ) {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
}
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return array(
'headers' => array(),
'body' => '',
'response' => array(
'code' => false,
'message' => false,
),
'cookies' => array(),
);
}
curl_exec( $handle );
$processed_headers = WP_Http::processHeaders( $this->headers, $url );
$body = $this->body;
$bytes_written_total = $this->bytes_written_total;
$this->headers = '';
$this->body = '';
$this->bytes_written_total = 0;
$curl_error = curl_errno( $handle );
// If an error occurred, or, no response.
if ( $curl_error || ( 0 === strlen( $body ) && empty( $processed_headers['headers'] ) ) ) {
if ( CURLE_WRITE_ERROR /* 23 */ === $curl_error ) {
if ( ! $this->max_body_length || $this->max_body_length !== $bytes_written_total ) {
if ( $parsed_args['stream'] ) {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
fclose( $this->stream_handle );
return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) );
} else {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return new WP_Error( 'http_request_failed', curl_error( $handle ) );
}
}
} else {
$curl_error = curl_error( $handle );
if ( $curl_error ) {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return new WP_Error( 'http_request_failed', $curl_error );
}
}
if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ), true ) ) {
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
}
}
if ( PHP_VERSION_ID < 80000 ) { // curl_close() has no effect as of PHP 8.0.
curl_close( $handle );
}
if ( $parsed_args['stream'] ) {
fclose( $this->stream_handle );
}
$response = array(
'headers' => $processed_headers['headers'],
'body' => null,
'response' => $processed_headers['response'],
'cookies' => $processed_headers['cookies'],
'filename' => $parsed_args['filename'],
);
// Handle redirects.
$redirect_response = WP_Http::handle_redirects( $url, $parsed_args, $response );
if ( false !== $redirect_response ) {
return $redirect_response;
}
if ( true === $parsed_args['decompress']
&& true === WP_Http_Encoding::should_decode( $processed_headers['headers'] )
) {
$body = WP_Http_Encoding::decompress( $body );
}
$response['body'] = $body;
return $response;
}
/**
* Grabs the headers of the cURL request.
*
* Each header is sent individually to this callback, and is appended to the `$header` property
* for temporary storage.
*
* @since 3.2.0
*
* @param resource $handle cURL handle.
* @param string $headers cURL request headers.
* @return int Length of the request headers.
*/
private function stream_headers( $handle, $headers ) {
$this->headers .= $headers;
return strlen( $headers );
}
/**
* Grabs the body of the cURL request.
*
* The contents of the document are passed in chunks, and are appended to the `$body`
* property for temporary storage. Returning a length shorter than the length of
* `$data` passed in will cause cURL to abort the request with `CURLE_WRITE_ERROR`.
*
* @since 3.6.0
*
* @param resource $handle cURL handle.
* @param string $data cURL request body.
* @return int Total bytes of data written.
*/
private function stream_body( $handle, $data ) {
$data_length = strlen( $data );
if ( $this->max_body_length && ( $this->bytes_written_total + $data_length ) > $this->max_body_length ) {
$data_length = ( $this->max_body_length - $this->bytes_written_total );
$data = substr( $data, 0, $data_length );
}
if ( $this->stream_handle ) {
$bytes_written = fwrite( $this->stream_handle, $data );
} else {
$this->body .= $data;
$bytes_written = $data_length;
}
$this->bytes_written_total += $bytes_written;
// Upon event of this function returning less than strlen( $data ) curl will error with CURLE_WRITE_ERROR.
return $bytes_written;
}
/**
* Determines whether this class can be used for retrieving a URL.
*
* @since 2.7.0
*
* @param array $args Optional. Array of request arguments. Default empty array.
* @return bool False means this class can not be used, true means it can.
*/
public static function test( $args = array() ) {
if ( ! function_exists( 'curl_init' ) || ! function_exists( 'curl_exec' ) ) {
return false;
}
$is_ssl = isset( $args['ssl'] ) && $args['ssl'];
if ( $is_ssl ) {
$curl_version = curl_version();
// Check whether this cURL version support SSL requests.
if ( ! ( CURL_VERSION_SSL & $curl_version['features'] ) ) {
return false;
}
}
/**
* Filters whether cURL can be used as a transport for retrieving a URL.
*
* @since 2.7.0
*
* @param bool $use_class Whether the class can be used. Default true.
* @param array $args An array of request arguments.
*/
return apply_filters( 'use_curl_transport', true, $args );
}
}
They also manage renters, show apartments, correct defects, execute maintenance, and charge interest. They demand payment from property owners, usually in the form of a portion of the rent. With that, you have the 101 on crafting a property management chart of accounts. The result is a fairly fleshed-out chart of accounts example template for property management. Once you have that in place, every transaction that passes in or out of the business is recorded on that chart of accounts, be it a property sale, rent payments, or service cost.
Their team is responsive, efficient, and always willing to go the extra mile to help out. Before we started working with them, our bookkeeping was a mess, and we were spending way too much time trying to keep up with it. The team at Outsource-Bookkeeper.com has been incredibly helpful in organizing our finances and keeping us on track. They are responsive, reliable, and always willing to go above and beyond to help us out. With these steps, you’ll craft a chart of accounts that not only caters to the needs of today but can tango with the surprises of tomorrow.
The chart of accounts is where you organize every type of income and expense in your real estate business. For agents, this might include income categories like buyer commissions, seller commissions, referral fees, or leasing fees. A chart of accounts is an organized list of all the financial categories a business uses to track income, expenses, assets, and liabilities. Set up categories like commissions, maintenance, property income, management fees, and owner contributions. By regularly monitoring financial reports, you can identify areas of concern, spot trends, and make data-driven decisions.
Let’s break down how you can set this up and make it as future-proof as grandma’s fruitcake. Throwing these accounts into your real estate chart of accounts lets you cut through the clutter, get a grip on your finances, and make tax time a little less painful. Keeping your real estate investments in line with https://www.austindailyherald.com/sponsored-content/why-real-estate-bookkeeping-is-critical-for-your-business-9247e950 your financial goals might sound like a tall order. But building a top-notch chart of accounts can make all the difference. Here’s a look-see at the building blocks you need for your real estate chart of accounts to keep your tax and financial plans working for you.
Real estate investing requires the ability to view the finances of all owned properties separately as well as on a portfolio level. This is both to understand the performance of individual properties and because the IRS mandates a property by property breakdown on the Schedule E form for passive rental income. Generally Accepted Accounting Principles (U.S. GAAP), a real estate chart of accounts serves as the Why Real Estate Bookkeeping is Critical for Your Business foundational framework for accurate financial reporting and analysis.
You can add, edit, or deactivate accounts to make sure the structure perfectly matches how you operate and report to owners. If you’re managing a rental property, a good place to start for a suggested chart of accounts is IRS Schedule E (Form 1040). There is no standard structure for a chart of accounts, including one for managing property (be it rental property or other). Your chart of accounts provides a foundation for a sound business structure, so it’s worth investing the time (or professional help) in crafting one that does the job you need it to do.
]]>This partnership is about more than just filing taxes; it’s about proactive tax planning and strategic advice throughout the year. By getting an expert involved early, you can set up your accounting systems correctly from the start, make smarter acquisition decisions, and create a financial strategy that supports your growth. It transforms your CPA from a simple service provider into a key member of your investment team. Anyone involved in property transactions can find value in working with a real estate CPA. This includes landlords managing a few rental properties, seasoned real estate investors with diverse portfolios, and property developers.
This type of accountant is the highest qualified financial person in the fiscal field. Paula Edmonds brings a thoughtful, client-first perspective to LSL’s Tax & Advisory team, combining technical insight with a genuine desire to help people succeed. To speak with a CPA specializing in real estate, reach out to us today to schedule a complimentary consultation. Also, the specific bookkeeper will offer faultless recommendations about procuring procedures that will cut expenses. Generally, we meet with potential clients for an initial consultation to learn more about their situation, if we can help, and if both parties believe it makes sense to work together. In many cases, we’ve had clients delegate this responsibility to an assistant, office manager, or another staff member, further reducing the amount of time our clients need to spend on this process.
Partial asset dispositions and retirements during renovations introduce further complexity. Without proper records or an engineering-based estimate, taxpayers forfeit deductions and continue depreciating assets that no longer exist. Accounting is an important part of every industry and real estate is no exception.
These steps acknowledge that even “simple” buildings contain complex tax machinery that, when handled professionally, can materially enhance after-tax returns. Our commitment is to provide knowledgeable, personal, and value-added services to help you succeed in the https://www.lagrangenews.com/sponsored-content/real-estate-bookkeeping-how-it-powers-your-business-488ddc68 real estate industry. A real estate CPA has a designation for passing state education and licensing requirements to be a certified public accountant specializing in real estate. They are generally more up-to-date on tax codes and strategies and can perform duties regular accountants can’t. This includes representing real estate investors if there’s a tax audit or dispute.
If you are selling stocks or property, and you have a long-term gain of $100,000, you have 180 days to invest that into a Qualified Opportunity Zone. If you hold that investment for 5 years, you will only be taxed on 90% of your capital gain – or $90,000. If you hold your investment for 7 years, you’ll only be taxed on 85% of your gain, or $80,000. Being a Certified Public Accountant (CPA), means that the individual has achieved a professional accreditation through a combination of education, real world experience and is licensed to practice. You’ll see exactly where your strengths are today—and where refining your structure could drive stronger growth, better asset protection, and a higher return on investment. When audits or reviews are required, we’ll deliver the appropriate level of assurance for your financial statements so you can meet stakeholder and lending requirements with confidence.
Several factors influence how much you’ll pay for a real estate tax accountant. Multiple income sources, various deductions, and navigating tax credits all add to the time and expertise required. The type of return—individual, business, or corporate—also affects the price, as each has its own set of rules. A seasoned professional with deep real estate tax knowledge will likely charge more than someone newer to the field. Finally, any extra services, such as help with an audit, will influence the overall cost.
The intersection of MACRS, tangible property regulations, partnership allocations, and financing terms creates a landscape in which technical missteps are easy to make and expensive to correct. These methods determine who bears pre-contribution gain and how post-contribution depreciation is shared. Depreciation on Section 1250 property (buildings) can give rise to unrecaptured Section 1250 gain taxed at rates up to 25 percent for individuals, with additional Section 291 recapture rules for Real Estate Bookkeeping: How It Powers Your Business C corporations. The sale of an interest in a partnership holding depreciated real estate can also create complex outcomes through hot asset rules and Section 751.
They can also provide expert financial analysis for your real estate investments, helping you make informed decisions about acquisitions, dispositions, and property management. For example, they can help you understand the common accounting mistakes real estate investors make. This level of expertise is often beyond the scope of a traditional accountant’s practice. Choosing a real estate accountant offers a higher level of specialized skills, ensuring your finances are handled with care and precision. They can also offer support with financial statement preparation, which is crucial for informed decision-making. Real estate accounting isn’t just about applying standard bookkeeping to property management; it’s a distinct field that addresses the specific financial challenges and opportunities within the industry.
It must also address tenant-improvement driven components, ownership of fixtures, and whether improvements constitute repairs or capital improvements under the tangible property regulations. Treating cost segregation as a quick tax move rather than a formal, document-heavy process is a common and costly misconception. We understand that real estate isn’t just an asset class — it’s a business model.
]]>